diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index df5b188691..0000000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-name: 发现问题
-about: 我发现了某处链接或者知识点的错误
-title: 'bug '
-labels: bug
-assignees: ''
-
----
-
-
-
-你好,我发现如下文章有 bug(点击文字可跳转到相关文章):
-
-[动态规划系列/抢房子.md](https://github.com/labuladong/fucking-algorithm/blob/master/动态规划系列/抢房子.md)
-
-问题描述:
-
-某章图片链接失效/其中的 XXX 内容有误/等等。
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000000..3981dae22b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,49 @@
+name: 报告错误的解法代码
+title: "[bug][{这里替换为出错的编程语言}] {这里替换为出错的力扣题目标识符} "
+description: "反馈我的刷题全家桶中的错误。"
+labels: [ "code bug" ]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ 力扣题目标识符是题目 URL 的最后一部分。比如 [https://leetcode.cn/problems/search-a-2d-matrix/](https://leetcode.cn/problems/search-a-2d-matrix/) 这道题标识符就是 `search-a-2d-matrix`。请补全 issue 题目,示例:`[bug][golang] search-a-2d-matrix`.
+
+ - type: checkboxes
+ attributes:
+ label: 请在提交 bug 之前先搜索
+ description: >
+ 请先搜索 [issues](https://github.com/labuladong/fucking-algorithm/issues) 确保你提的这个 bug 还没有被提交过。
+ options:
+ - label: >
+ 我已经搜索过 [issues](https://github.com/labuladong/fucking-algorithm/issues),没有发现相同的 bug。
+ required: true
+ - type: input
+ attributes:
+ label: 出错的题目链接
+ description: |
+ 输入力扣的题目链接
+ placeholder: 例如 https://leetcode.cn/problems/search-a-2d-matrix/
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: 报错信息
+ description: |
+ 把出错的原因复制粘贴在这里
+ value: |
+
+ ```
+
+ ```
+ validations:
+ required: true
+ - type: checkboxes
+ attributes:
+ label: 你是否愿意提交 PR 修复这个 bug?
+ description: >
+ PR 规范 [见这里](https://github.com/labuladong/fucking-algorithm/issues/1113),欢迎成为本仓库的 contributor!
+ options:
+ - label: 我愿意!
+ - type: markdown
+ attributes:
+ value: "感谢你的支持,[labuladong 的刷题全家桶](https://labuladong.github.io/article/fname.html?fname=全家桶简介) 会因你变得越来越好!"
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000000..f08e81c1c3
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,17 @@
+
+
+
+
+Fixes
+
+我修改的是如下题目的 xx 解法:
+
+
+
+通过截图如下:
+
+
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/LCS.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/LCS.md"
index 836c36d7f8..5c9005bd36 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/LCS.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/LCS.md"
@@ -1,5 +1,6 @@
---
title: '详解最长公共子序列问题,秒杀三道动态规划题目'
+tags: ['动态规划', '子序列']
---
@@ -11,7 +12,7 @@ title: '详解最长公共子序列问题,秒杀三道动态规划题目'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213KMP\345\255\227\347\254\246\345\214\271\351\205\215\347\256\227\346\263\225.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213KMP\345\255\227\347\254\246\345\214\271\351\205\215\347\256\227\346\263\225.md"
index ffa1c847a8..e80c9c6ed6 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213KMP\345\255\227\347\254\246\345\214\271\351\205\215\347\256\227\346\263\225.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213KMP\345\255\227\347\254\246\345\214\271\351\205\215\347\256\227\346\263\225.md"
@@ -1,5 +1,6 @@
---
title: '动态规划之KMP字符匹配算法'
+tags: ['字符串']
---
@@ -11,7 +12,7 @@ title: '动态规划之KMP字符匹配算法'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
index ba29f045e0..7366b6e492 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
@@ -1,5 +1,6 @@
---
title: '动态规划之博弈问题'
+tags: ['动态规划']
---
@@ -11,7 +12,7 @@ title: '动态规划之博弈问题'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\233\233\351\224\256\351\224\256\347\233\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\233\233\351\224\256\351\224\256\347\233\230.md"
index 148c3060f3..4a2ebcb7fa 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\233\233\351\224\256\351\224\256\347\233\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\233\233\351\224\256\351\224\256\347\233\230.md"
@@ -1,5 +1,6 @@
---
title: '动态规划之四键键盘'
+tags: ['动态规划']
---
@@ -11,7 +12,7 @@ title: '动态规划之四键键盘'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\346\255\243\345\210\231\350\241\250\350\276\276.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\346\255\243\345\210\231\350\241\250\350\276\276.md"
index d29ded6f10..c5514167fd 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\346\255\243\345\210\231\350\241\250\350\276\276.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\346\255\243\345\210\231\350\241\250\350\276\276.md"
@@ -1,5 +1,6 @@
---
title: '动态规划之正则表达'
+tags: ['动态规划', '字符串']
---
@@ -11,7 +12,7 @@ title: '动态规划之正则表达'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md"
index 9ebbc9c476..c5e1107739 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md"
@@ -1,5 +1,6 @@
---
title: '动态规划设计:最长递增子序列'
+tags: ['动态规划', '设计']
---
@@ -11,7 +12,7 @@ title: '动态规划设计:最长递增子序列'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\257\246\350\247\243\350\277\233\351\230\266.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\257\246\350\247\243\350\277\233\351\230\266.md"
index 9793516e3d..753cf21285 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\257\246\350\247\243\350\277\233\351\230\266.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\257\246\350\247\243\350\277\233\351\230\266.md"
@@ -12,7 +12,7 @@ tags: ['动态规划', '核心框架系列']

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\215\225\350\257\215\346\213\274\346\216\245.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\215\225\350\257\215\346\213\274\346\216\245.md"
index 4b60af389e..59f7e0b266 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\215\225\350\257\215\346\213\274\346\216\245.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\215\225\350\257\215\346\213\274\346\216\245.md"
@@ -1,5 +1,6 @@
---
title: '两种思路解决单词拼接问题'
+tags: ['动态规划', '设计']
---
@@ -11,7 +12,7 @@ title: '两种思路解决单词拼接问题'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\233\242\347\201\255\350\202\241\347\245\250\351\227\256\351\242\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\233\242\347\201\255\350\202\241\347\245\250\351\227\256\351\242\230.md"
index cb33469f14..6e0e317e54 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\233\242\347\201\255\350\202\241\347\245\250\351\227\256\351\242\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\233\242\347\201\255\350\202\241\347\245\250\351\227\256\351\242\230.md"
@@ -1,5 +1,6 @@
---
title: '团灭 LeetCode 股票买卖问题'
+tags: ['动态规划']
---
@@ -11,7 +12,7 @@ title: '团灭 LeetCode 股票买卖问题'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\255\220\345\272\217\345\210\227\351\227\256\351\242\230\346\250\241\346\235\277.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\255\220\345\272\217\345\210\227\351\227\256\351\242\230\346\250\241\346\235\277.md"
index bb6e0916ca..1397e2845d 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\255\220\345\272\217\345\210\227\351\227\256\351\242\230\346\250\241\346\235\277.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\255\220\345\272\217\345\210\227\351\227\256\351\242\230\346\250\241\346\235\277.md"
@@ -1,5 +1,6 @@
---
title: '动态规划之子序列问题解题模板'
+tags: ['动态规划', '子序列']
---
@@ -11,7 +12,7 @@ title: '动态规划之子序列问题解题模板'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md"
index 1f0a18b9fc..fb72f1b55a 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md"
@@ -1,5 +1,6 @@
---
title: '团灭 LeetCode 打家劫舍问题'
+tags: ['动态规划']
---
@@ -11,7 +12,7 @@ title: '团灭 LeetCode 打家劫舍问题'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\344\274\230\345\255\220\347\273\223\346\236\204.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\344\274\230\345\255\220\347\273\223\346\236\204.md"
index c666d62db1..467fa7534d 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\344\274\230\345\255\220\347\273\223\346\236\204.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\344\274\230\345\255\220\347\273\223\346\236\204.md"
@@ -1,5 +1,6 @@
---
title: '动态规划系列答疑篇'
+tags: ['动态规划', '核心框架']
---
@@ -11,7 +12,7 @@ title: '动态规划系列答疑篇'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\347\212\266\346\200\201\345\216\213\347\274\251\346\212\200\345\267\247.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\347\212\266\346\200\201\345\216\213\347\274\251\346\212\200\345\267\247.md"
index 9259f73073..f490cd2174 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\347\212\266\346\200\201\345\216\213\347\274\251\346\212\200\345\267\247.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\347\212\266\346\200\201\345\216\213\347\274\251\346\212\200\345\267\247.md"
@@ -1,5 +1,6 @@
---
title: '对动态规划发动降维打击'
+tags: ['动态规划', '核心框架']
---
@@ -11,7 +12,7 @@ title: '对动态规划发动降维打击'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\347\274\226\350\276\221\350\267\235\347\246\273.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\347\274\226\350\276\221\350\267\235\347\246\273.md"
index a96e9bc4f8..79f3448d04 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\347\274\226\350\276\221\350\267\235\347\246\273.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\347\274\226\350\276\221\350\267\235\347\246\273.md"
@@ -1,5 +1,6 @@
---
title: '编辑距离'
+tags: ['动态规划']
---
@@ -11,7 +12,7 @@ title: '编辑距离'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\350\203\214\345\214\205\351\227\256\351\242\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\350\203\214\345\214\205\351\227\256\351\242\230.md"
index 6a7aea3978..f054cf7433 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\350\203\214\345\214\205\351\227\256\351\242\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\350\203\214\345\214\205\351\227\256\351\242\230.md"
@@ -1,5 +1,6 @@
---
title: '动态规划之背包问题'
+tags: ['动态规划', '背包问题']
---
@@ -11,7 +12,7 @@ title: '动态规划之背包问题'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\350\264\252\345\277\203\347\256\227\346\263\225\344\271\213\345\214\272\351\227\264\350\260\203\345\272\246\351\227\256\351\242\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\350\264\252\345\277\203\347\256\227\346\263\225\344\271\213\345\214\272\351\227\264\350\260\203\345\272\246\351\227\256\351\242\230.md"
index e0f7c8a2ba..6e330168e4 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\350\264\252\345\277\203\347\256\227\346\263\225\344\271\213\345\214\272\351\227\264\350\260\203\345\272\246\351\227\256\351\242\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\350\264\252\345\277\203\347\256\227\346\263\225\344\271\213\345\214\272\351\227\264\350\260\203\345\272\246\351\227\256\351\242\230.md"
@@ -1,5 +1,6 @@
---
title: '贪心算法之区间调度问题'
+tags: ['贪心算法', '排序']
---
@@ -11,7 +12,7 @@ title: '贪心算法之区间调度问题'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\253\230\346\245\274\346\211\224\351\270\241\350\233\213\351\227\256\351\242\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\253\230\346\245\274\346\211\224\351\270\241\350\233\213\351\227\256\351\242\230.md"
index a27d04a19d..0cffaf6a53 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\253\230\346\245\274\346\211\224\351\270\241\350\233\213\351\227\256\351\242\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\253\230\346\245\274\346\211\224\351\270\241\350\233\213\351\227\256\351\242\230.md"
@@ -1,5 +1,6 @@
---
title: '经典动态规划问题:高楼扔鸡蛋'
+tags: ['动态规划']
---
@@ -11,7 +12,7 @@ title: '经典动态规划问题:高楼扔鸡蛋'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\255\224\345\241\224.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\255\224\345\241\224.md"
index f914134904..028005ee1f 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\255\224\345\241\224.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\255\224\345\241\224.md"
@@ -1,5 +1,6 @@
---
title: '动态规划算法通关魔塔'
+tags: ['动态规划']
---
@@ -11,7 +12,7 @@ title: '动态规划算法通关魔塔'

-**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
+**通知:[数据结构精品课](https://aep.h5.xeknow.com/s/1XJHEO) 已更新到 V2.1,[手把手刷二叉树系列课程](https://aep.xet.tech/s/3YGcq3) 上线。[第 18 期每日打卡](https://aep.xet.tech/s/2PLO1n) 开始报名。反馈或修正 chatGPT 翻译的多语言代码 [点击这里](https://github.com/labuladong/fucking-algorithm/issues/1113)。另外,建议你在我的 [网站](https://labuladong.github.io/algo/) 学习文章,体验更好。**
diff --git "a/\345\244\232\350\257\255\350\250\200\350\247\243\346\263\225\344\273\243\347\240\201/contribution-guide.md" "b/\345\244\232\350\257\255\350\250\200\350\247\243\346\263\225\344\273\243\347\240\201/contribution-guide.md"
new file mode 100644
index 0000000000..0336bb3d4c
--- /dev/null
+++ "b/\345\244\232\350\257\255\350\250\200\350\247\243\346\263\225\344\273\243\347\240\201/contribution-guide.md"
@@ -0,0 +1,74 @@
+# 修正 labuladong 刷题插件中的错误
+
+## 背景
+
+为了帮助大家更好地学习算法,我之前写了很多算法教程,并开发了一系列刷题插件,统称为《labuladong 的刷题全家桶》,详情见 [这里](https://labuladong.github.io/article/fname.html?fname=全家桶简介)。
+
+在我的教程和插件中的解法主要使用的是 Java 语言,原因是 Java 这门语言中规中矩,就算之前没有接触过,也能比较容易看懂逻辑。不过现在这不是 chatGPT 横空出世了嘛,我就借助 chatGPT 把我的解法改写成多种语言,希望对不同技术背景的小伙伴更加友好。
+
+chatGPT 的改写效果还是非常不错的,不过难免还是存在一些错误,所以我希望能够和大家一起来修正这些错误。
+
+## 如何反馈错误
+
+如果你发现某些解法代码不能通过力扣的所有测试用例(一般都是 chatGPT 改写的解法代码会出现这种情况,我的解法代码都是通过测试才发布的),可以 [点这里](https://github.com/labuladong/fucking-algorithm/issues/new?assignees=&labels=code+bug&template=bug_report.yml&title=%5Bbug%5D%5B%7B%E8%BF%99%E9%87%8C%E6%9B%BF%E6%8D%A2%E4%B8%BA%E5%87%BA%E9%94%99%E7%9A%84%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80%7D%5D+%7B%E8%BF%99%E9%87%8C%E6%9B%BF%E6%8D%A2%E4%B8%BA%E5%87%BA%E9%94%99%E7%9A%84%E5%8A%9B%E6%89%A3%E9%A2%98%E7%9B%AE%E6%A0%87%E8%AF%86%E7%AC%A6%7D+) 按照模板提交 issue,我和其他小伙伴会提交 PR 修复这些错误。
+
+## 如何修正错误
+
+首先,感谢你愿意为我的插件提供的解法代码纠错,你向本仓库提交 PR 修复错误后,你将成为本仓库的 contributor,出现在仓库首页的贡献者列表中。本仓库已经获得了 115k star,你的贡献将会被许多人看到。
+
+修复代码很简单,所有多语言解法代码都存储在 [多语言解法代码/solution_code.md](https://github.com/labuladong/fucking-algorithm/blob/master/%E5%A4%9A%E8%AF%AD%E8%A8%80%E8%A7%A3%E6%B3%95%E4%BB%A3%E7%A0%81/solution_code.md) 中,你只要修改这个文件就行了。其内容的组织形如如下:
+
+
+ https://leetcode.cn/problems/xxx 的多语言解法👇
+
+ ```cpp
+ class Solution {
+ public:
+ int xxx() {
+ // ...
+ }
+ };
+ ```
+
+ ```java
+ class Solution {
+ public int xxx() {
+ // ...
+ }
+ }
+ ```
+
+ ```python
+ class Solution:
+ def xxx(self):
+ # ...
+ ```
+
+ ```javascript
+ var xxx = function() {
+ // ...
+ }
+ ```
+
+ ```go
+ func xxx() {
+ // ...
+ }
+ ```
+
+ https://leetcode.cn/problems/xxx 的多语言解法👆
+
+
+比如你想修改 [https://leetcode-cn.com/problems/longest-palindromic-substring/](https://leetcode-cn.com/problems/longest-palindromic-substring/) 的 JavaScript 解法,你可以在 [多语言解法代码/solution_code.md](https://github.com/labuladong/fucking-algorithm/blob/master/%E5%A4%9A%E8%AF%AD%E8%A8%80%E8%A7%A3%E6%B3%95%E4%BB%A3%E7%A0%81/solution_code.md) 中搜索 `longest-palindromic-substring` 关键词,即可找到这道题的多语言解法,然后修改 JavaScript 对应的解法代码,提交 PR 即可。
+
+我的插件会自动拉取这个文件的最新内容,所以你的 PR 被合进 master 分支后,插件中的内容修改也会生效。
+
+## 提交 PR 的要求
+
+1、你的 PR 必须是针对 [多语言解法代码/solution_code.md](https://github.com/labuladong/fucking-algorithm/blob/master/%E5%A4%9A%E8%AF%AD%E8%A8%80%E8%A7%A3%E6%B3%95%E4%BB%A3%E7%A0%81/solution_code.md) 文件中代码部分的修改,不要修改其他文件和其他内容。
+
+2、把我的解法翻译成多语言的目的是帮助不同背景的小伙伴理解算法思维,所以你修改的代码可以不是效率最优的,但应该尽可能和我的解法思路保持一致,且包含我的解法中的完整注释。
+
+3、你的 PR 描述中需要包含代码通过所有测试用例截图。PR 标题的格式为 `[fix][{lang}] {slug}`,其中 `{lang}` 需要替换为你修复的解法语言,比如 `[fix][cpp]`,`{slug}` 需要替换为你修复的题目的标识符(题目 URL 的最后一部分),比如 [https://leetcode.cn/problems/search-a-2d-matrix/](https://leetcode.cn/problems/search-a-2d-matrix/) 这道题的标识符就是 `search-a-2d-matrix`。
+
+**你可以查看这个 PR 作为案例**:https://github.com/labuladong/fucking-algorithm/pull/1112
\ No newline at end of file
diff --git "a/\345\244\232\350\257\255\350\250\200\350\247\243\346\263\225\344\273\243\347\240\201/solution_code.md" "b/\345\244\232\350\257\255\350\250\200\350\247\243\346\263\225\344\273\243\347\240\201/solution_code.md"
new file mode 100644
index 0000000000..4e82f51cac
--- /dev/null
+++ "b/\345\244\232\350\257\255\350\250\200\350\247\243\346\263\225\344\273\243\347\240\201/solution_code.md"
@@ -0,0 +1,69883 @@
+https://leetcode.cn/problems/01-matrix 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ vector> updateMatrix(vector>& mat) {
+ int m = mat.size(), n = mat[0].size();
+ // 记录答案的结果数组
+ vector> res(m, vector(n, -1));
+ // 初始化队列,把那些值为 0 的坐标放到队列里
+ queue> q;
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ if (mat[i][j] == 0) {
+ q.push({i, j});
+ res[i][j] = 0;
+ }
+ }
+ }
+ // 执行 BFS 算法框架,从值为 0 的坐标开始向四周扩散
+ vector> dirs{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
+ while (!q.empty()) {
+ auto cur = q.front();
+ q.pop();
+ int x = cur.first, y = cur.second;
+ // 向四周扩散
+ for (auto& dir : dirs) {
+ int nextX = x + dir[0];
+ int nextY = y + dir[1];
+ // 确保相邻的这个坐标没有越界且之前未被计算过
+ if (nextX >= 0 && nextX < m && nextY >= 0 && nextY < n
+ && res[nextX][nextY] == -1) {
+ q.push({nextX, nextY});
+ // 从 mat[x][y] 走到 mat[nextX][nextY] 需要一步
+ res[nextX][nextY] = res[x][y] + 1;
+ }
+ }
+ }
+
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func updateMatrix(mat [][]int) [][]int {
+ m, n := len(mat), len(mat[0])
+ // 记录答案的结果数组
+ res := make([][]int, m)
+ for i := range res {
+ res[i] = make([]int, n)
+ for j := range res[i] {
+ res[i][j] = -1
+ }
+ }
+ // 初始化队列,把那些值为 0 的坐标放到队列里
+ q := make([][2]int, 0)
+ for i := 0; i < m; i++ {
+ for j := 0; j < n; j++ {
+ if mat[i][j] == 0 {
+ q = append(q, [2]int{i, j})
+ res[i][j] = 0
+ }
+ }
+ }
+ // 执行 BFS 算法框架,从值为 0 的坐标开始向四周扩散
+ dirs := [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}
+ for len(q) > 0 {
+ cur := q[0]
+ q = q[1:]
+ x, y := cur[0], cur[1]
+ // 向四周扩散
+ for _, dir := range dirs {
+ nextX, nextY := x+dir[0], y+dir[1]
+ // 确保相邻的这个坐标没有越界且之前未被计算过
+ if nextX >= 0 && nextX < m && nextY >= 0 && nextY < n && res[nextX][nextY] == -1 {
+ q = append(q, [2]int{nextX, nextY})
+ // 从 mat[x][y] 走到 mat[nextX][nextY] 需要一步
+ res[nextX][nextY] = res[x][y] + 1
+ }
+ }
+ }
+
+ return res
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int[][] updateMatrix(int[][] mat) {
+ int m = mat.length, n = mat[0].length;
+ // 记录答案的结果数组
+ int[][] res = new int[m][n];
+ // 初始化全部填充特殊值 -1,代表未计算,
+ // 待会可以用来判断坐标是否已经计算过,避免重复遍历
+ for (int[] row : res) {
+ Arrays.fill(row, -1);
+ }
+
+ Queue q = new LinkedList<>();
+ // 初始化队列,把那些值为 0 的坐标放到队列里
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ if (mat[i][j] == 0) {
+ q.offer(new int[]{i, j});
+ res[i][j] = 0;
+ }
+ }
+ }
+ // 执行 BFS 算法框架,从值为 0 的坐标开始向四周扩散
+ int[][] dirs = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
+ while (!q.isEmpty()) {
+ int[] cur = q.poll();
+ int x = cur[0], y = cur[1];
+ // 向四周扩散
+ for (int i = 0; i < 4; i++) {
+ int nextX = x + dirs[i][0];
+ int nextY = y + dirs[i][1];
+ // 确保相邻的这个坐标没有越界且之前未被计算过
+ if (nextX >= 0 && nextX < m && nextY >= 0 && nextY < n
+ && res[nextX][nextY] == -1) {
+ q.offer(new int[]{nextX, nextY});
+ // 从 mat[x][y] 走到 mat[nextX][nextY] 需要一步
+ res[nextX][nextY] = res[x][y] + 1;
+ }
+ }
+ }
+
+ return res;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+function updateMatrix(mat) {
+ const m = mat.length, n = mat[0].length;
+ // 记录答案的结果数组
+ const res = new Array(m).fill().map(() => new Array(n).fill(-1));
+
+ const q = [];
+ // 初始化队列,把那些值为 0 的坐标放到队列里
+ for (let i = 0; i < m; i++) {
+ for (let j = 0; j < n; j++) {
+ if (mat[i][j] === 0) {
+ q.push([i, j]);
+ res[i][j] = 0;
+ }
+ }
+ }
+ // 执行 BFS 算法框架,从值为 0 的坐标开始向四周扩散
+ const dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]];
+ while (q.length) {
+ const cur = q.shift();
+ const x = cur[0], y = cur[1];
+ // 向四周扩散
+ for (let i = 0; i < 4; i++) {
+ const nextX = x + dirs[i][0];
+ const nextY = y + dirs[i][1];
+ // 确保相邻的这个坐标没有越界且之前未被计算过
+ if (nextX >= 0 && nextX < m && nextY >= 0 && nextY < n
+ && res[nextX][nextY] === -1) {
+ q.push([nextX, nextY]);
+ // 从 mat[x][y] 走到 mat[nextX][nextY] 需要一步
+ res[nextX][nextY] = res[x][y] + 1;
+ }
+ }
+ }
+
+ return res;
+}
+```
+
+```python
+# by chatGPT (python)
+from collections import deque
+
+class Solution:
+ def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:
+ m, n = len(mat), len(mat[0])
+ # 记录答案的结果数组
+ res = [[-1] * n for _ in range(m)]
+
+ q = deque()
+ # 初始化队列,把那些值为 0 的坐标放到队列里
+ for i in range(m):
+ for j in range(n):
+ if mat[i][j] == 0:
+ q.append((i, j))
+ res[i][j] = 0
+
+ # 执行 BFS 算法框架,从值为 0 的坐标开始向四周扩散
+ dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]
+ while q:
+ x, y = q.popleft()
+ # 向四周扩散
+ for dx, dy in dirs:
+ nextX, nextY = x + dx, y + dy
+ # 确保相邻的这个坐标没有越界且之前未被计算过
+ if 0 <= nextX < m and 0 <= nextY < n and res[nextX][nextY] == -1:
+ q.append((nextX, nextY))
+ # 从 mat[x][y] 走到 mat[nextX][nextY] 需要一步
+ res[nextX][nextY] = res[x][y] + 1
+
+ return res
+```
+
+https://leetcode.cn/problems/01-matrix 的多语言解法👆
+
+https://leetcode.cn/problems/0i0mDW 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int memo[201][201];
+
+ int minPathSum(vector>& grid) {
+ int m = grid.size();
+ int n = grid[0].size();
+ // 构造备忘录,初始值全部设为 -1
+ memset(memo, -1, sizeof(memo));
+
+ return dp(grid, m - 1, n - 1);
+ }
+
+ int dp(vector>& grid, int i, int j) {
+ // base case
+ if (i == 0 && j == 0) {
+ return grid[0][0];
+ }
+ if (i < 0 || j < 0) {
+ return INT_MAX;
+ }
+ // 避免重复计算
+ if (memo[i][j] != -1) {
+ return memo[i][j];
+ }
+ // 将计算结果记入备忘录
+ memo[i][j] = min(
+ dp(grid, i - 1, j),
+ dp(grid, i, j - 1)
+ ) + grid[i][j];
+
+ return memo[i][j];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func minPathSum(grid [][]int) int {
+ m := len(grid)
+ n := len(grid[0])
+ // 构造备忘录,初始值全部设为 -1
+ memo := make([][]int, m)
+ for i := 0; i < m; i++ {
+ memo[i] = make([]int, n)
+ for j := 0; j < n; j++ {
+ memo[i][j] = -1
+ }
+ }
+
+ return dp(grid, m - 1, n - 1, memo)
+}
+
+func dp(grid [][]int, i int, j int, memo [][]int) int {
+ // base case
+ if i == 0 && j == 0 {
+ return grid[0][0]
+ }
+ if i < 0 || j < 0 {
+ return math.MaxInt32
+ }
+ // 避免重复计算
+ if memo[i][j] != -1 {
+ return memo[i][j]
+ }
+ // 将计算结果记入备忘录
+ left := dp(grid, i - 1, j, memo)
+ up := dp(grid, i, j - 1, memo)
+ curr := grid[i][j] + min(left, up)
+ memo[i][j] = curr
+ return curr
+}
+
+func min(a, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ int[][] memo;
+
+ public int minPathSum(int[][] grid) {
+ int m = grid.length;
+ int n = grid[0].length;
+ // 构造备忘录,初始值全部设为 -1
+ memo = new int[m][n];
+ for (int[] row : memo)
+ Arrays.fill(row, -1);
+
+ return dp(grid, m - 1, n - 1);
+ }
+
+ int dp(int[][] grid, int i, int j) {
+ // base case
+ if (i == 0 && j == 0) {
+ return grid[0][0];
+ }
+ if (i < 0 || j < 0) {
+ return Integer.MAX_VALUE;
+ }
+ // 避免重复计算
+ if (memo[i][j] != -1) {
+ return memo[i][j];
+ }
+ // 将计算结果记入备忘录
+ memo[i][j] = Math.min(
+ dp(grid, i - 1, j),
+ dp(grid, i, j - 1)
+ ) + grid[i][j];
+
+ return memo[i][j];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+let memo;
+
+var minPathSum = function(grid) {
+ const m = grid.length;
+ const n = grid[0].length;
+ // 构造备忘录,初始值全部设为 -1
+ memo = new Array(m);
+ for (let i = 0; i < m; i++) {
+ memo[i] = new Array(n).fill(-1);
+ }
+
+ return dp(grid, m - 1, n - 1);
+};
+
+var dp = function(grid, i, j) {
+ // base case
+ if (i === 0 && j === 0) {
+ return grid[0][0];
+ }
+ if (i < 0 || j < 0) {
+ return Number.MAX_SAFE_INTEGER;
+ }
+ // 避免重复计算
+ if (memo[i][j] !== -1) {
+ return memo[i][j];
+ }
+ // 将计算结果记入备忘录
+ memo[i][j] = Math.min(
+ dp(grid, i - 1, j),
+ dp(grid, i, j - 1)
+ ) + grid[i][j];
+
+ return memo[i][j];
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def __init__(self):
+ self.memo = None
+
+ def minPathSum(self, grid: List[List[int]]) -> int:
+ m = len(grid)
+ n = len(grid[0])
+ # 构造备忘录,初始值全部设为 -1
+ self.memo = [[-1 for _ in range(n)] for _ in range(m)]
+
+ return self.dp(grid, m - 1, n - 1)
+
+ def dp(self, grid: List[List[int]], i: int, j: int) -> int:
+ # base case
+ if i == 0 and j == 0:
+ return grid[0][0]
+ if i < 0 or j < 0:
+ return float('inf')
+ # 避免重复计算
+ if self.memo[i][j] != -1:
+ return self.memo[i][j]
+ # 将计算结果记入备忘录
+ self.memo[i][j] = min(
+ self.dp(grid, i - 1, j),
+ self.dp(grid, i, j - 1)
+ ) + grid[i][j]
+
+ return self.memo[i][j]
+```
+
+https://leetcode.cn/problems/0i0mDW 的多语言解法👆
+
+https://leetcode.cn/problems/1fGaJU 的多语言解法👇
+
+```cpp
+// by labuladong (cpp)
+class Solution {
+ public:
+ vector> threeSum(vector& nums) {
+ sort(nums.begin(), nums.end());
+ // n 为 3,从 nums[0] 开始计算和为 0 的三元组
+ return nSumTarget(nums, 3, 0, 0);
+ }
+
+ /* 注意:调用这个函数之前一定要先给 nums 排序 */
+ // n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+ vector> nSumTarget(
+ vector& nums, int n, int start, int target) {
+
+ int sz = nums.size();
+ vector> res;
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if (n < 2 || sz < n) return res;
+ // 2Sum 是 base case
+ if (n == 2) {
+ // 双指针那一套操作
+ int lo = start, hi = sz - 1;
+ while (lo < hi) {
+ int sum = nums[lo] + nums[hi];
+ int left = nums[lo], right = nums[hi];
+ if (sum < target) {
+ while (lo < hi && nums[lo] == left) lo++;
+ } else if (sum > target) {
+ while (lo < hi && nums[hi] == right) hi--;
+ } else {
+ res.push_back({left, right});
+ while (lo < hi && nums[lo] == left) lo++;
+ while (lo < hi && nums[hi] == right) hi--;
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for (int i = start; i < sz; i++) {
+ vector>
+ sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
+ for (vector& arr : sub) {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ arr.push_back(nums[i]);
+ res.push_back(arr);
+ }
+ while (i < sz - 1 && nums[i] == nums[i + 1]) i++;
+ }
+ }
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func threeSum(nums []int) [][]int {
+ sort.Ints(nums)
+ // n 为 3,从 nums[0] 开始计算和为 0 的三元组
+ return nSumTarget(nums, 3, 0, 0)
+}
+
+/* 注意:调用这个函数之前一定要先给 nums 排序 */
+// n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+func nSumTarget(nums []int, n int, start int, target int) [][]int {
+ sz := len(nums)
+ var res [][]int
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if n < 2 || sz < n {
+ return res
+ }
+ // 2Sum 是 base case
+ if n == 2 {
+ // 双指针那一套操作
+ lo, hi := start, sz-1
+ for lo < hi {
+ sum := nums[lo] + nums[hi]
+ left, right := nums[lo], nums[hi]
+ if sum < target {
+ for lo < hi && nums[lo] == left {
+ lo++
+ }
+ } else if sum > target {
+ for lo < hi && nums[hi] == right {
+ hi--
+ }
+ } else {
+ res = append(res, []int{left, right})
+ for lo < hi && nums[lo] == left {
+ lo++
+ }
+ for lo < hi && nums[hi] == right {
+ hi--
+ }
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for i := start; i < sz; i++ {
+ sub := nSumTarget(nums, n-1, i+1, target-nums[i])
+ for _, arr := range sub {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ arr = append(arr, nums[i])
+ res = append(res, arr)
+ }
+ for i < sz-1 && nums[i] == nums[i+1] {
+ i++
+ }
+ }
+ }
+ return res
+}
+```
+
+```java
+// by chatGPT (java)
+class Solution {
+ public List> threeSum(int[] nums) {
+ Arrays.sort(nums);
+ // n 为 3,从 nums[0] 开始计算和为 0 的三元组
+ return nSumTarget(nums, 3, 0, 0);
+ }
+
+ /* 注意:调用这个函数之前一定要先给 nums 排序 */
+ // n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+ public List> nSumTarget(
+ int[] nums, int n, int start, int target) {
+
+ int sz = nums.length;
+ List> res = new ArrayList<>();
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if (n < 2 || sz < n) return res;
+ // 2Sum 是 base case
+ if (n == 2) {
+ // 双指针那一套操作
+ int lo = start, hi = sz - 1;
+ while (lo < hi) {
+ int sum = nums[lo] + nums[hi];
+ int left = nums[lo], right = nums[hi];
+ if (sum < target) {
+ while (lo < hi && nums[lo] == left) lo++;
+ } else if (sum > target) {
+ while (lo < hi && nums[hi] == right) hi--;
+ } else {
+ List triplet = new ArrayList<>();
+ triplet.add(left);
+ triplet.add(right);
+ res.add(triplet);
+ while (lo < hi && nums[lo] == left) lo++;
+ while (lo < hi && nums[hi] == right) hi--;
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for (int i = start; i < sz; i++) {
+ List> sub =
+ nSumTarget(nums, n - 1, i + 1, target - nums[i]);
+ for (List arr : sub) {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ arr.add(nums[i]);
+ res.add(arr);
+ }
+ while (i < sz - 1 && nums[i] == nums[i + 1]) i++;
+ }
+ }
+ return res;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var threeSum = function(nums) {
+ nums.sort((a, b) => a - b);
+ // n 为 3,从 nums[0] 开始计算和为 0 的三元组
+ return nSumTarget(nums, 3, 0, 0);
+};
+
+/* 注意:调用这个函数之前一定要先给 nums 排序 */
+// n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+var nSumTarget = function(nums, n, start, target) {
+ var sz = nums.length;
+ var res = [];
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if (n < 2 || sz < n) return res;
+ // 2Sum 是 base case
+ if (n === 2) {
+ // 双指针那一套操作
+ var lo = start, hi = sz - 1;
+ while (lo < hi) {
+ var sum = nums[lo] + nums[hi];
+ var left = nums[lo], right = nums[hi];
+ if (sum < target) {
+ while (lo < hi && nums[lo] === left) lo++;
+ } else if (sum > target) {
+ while (lo < hi && nums[hi] === right) hi--;
+ } else {
+ res.push([left, right]);
+ while (lo < hi && nums[lo] === left) lo++;
+ while (lo < hi && nums[hi] === right) hi--;
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for (var i = start; i < sz; i++) {
+ var sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
+ for (var j = 0; j < sub.length; j++) {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ sub[j].push(nums[i]);
+ res.push(sub[j]);
+ }
+ while (i < sz - 1 && nums[i] === nums[i + 1]) i++;
+ }
+ }
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def threeSum(self, nums: List[int]) -> List[List[int]]:
+ nums.sort()
+ # n 为 3,从 nums[0] 开始计算和为 0 的三元组
+ return self.nSumTarget(nums, 3, 0, 0)
+
+ # 注意:调用这个函数之前一定要先给 nums 排序
+ # n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+ def nSumTarget(self, nums: List[int], n: int, start: int, target: int) -> List[List[int]]:
+ sz = len(nums)
+ res = []
+ # 至少是 2Sum,且数组大小不应该小于 n
+ if n < 2 or sz < n:
+ return res
+ # 2Sum 是 base case
+ if n == 2:
+ # 双指针那一套操作
+ lo, hi = start, sz - 1
+ while lo < hi:
+ _sum = nums[lo] + nums[hi]
+ left, right = nums[lo], nums[hi]
+ if _sum < target:
+ while lo < hi and nums[lo] == left:
+ lo += 1
+ elif _sum > target:
+ while lo < hi and nums[hi] == right:
+ hi -= 1
+ else:
+ res.append([left, right])
+ while lo < hi and nums[lo] == left:
+ lo += 1
+ while lo < hi and nums[hi] == right:
+ hi -= 1
+ else:
+ # n > 2 时,递归计算 (n-1)Sum 的结果
+ for i in range(start, sz):
+ if i > start and nums[i] == nums[i - 1]:
+ continue
+ sub = self.nSumTarget(nums, n - 1, i + 1, target - nums[i])
+ for arr in sub:
+ # (n-1)Sum 加上 nums[i] 就是 nSum
+ arr.append(nums[i])
+ res.append(arr)
+ return res
+```
+
+https://leetcode.cn/problems/1fGaJU 的多语言解法👆
+
+https://leetcode.cn/problems/2AoeFn 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ // 备忘录
+ int memo[100][100];
+
+ int uniquePaths(int m, int n) {
+ memset(memo, 0, sizeof(memo));
+ return dp(m - 1, n - 1);
+ }
+
+ // 定义:从 (0, 0) 到 (x, y) 有 dp(x, y) 条路径
+ int dp(int x, int y) {
+ // base case
+ if (x == 0 && y == 0) {
+ return 1;
+ }
+ if (x < 0 || y < 0) {
+ return 0;
+ }
+ // 避免冗余计算
+ if (memo[x][y] > 0) {
+ return memo[x][y];
+ }
+ // 状态转移方程:
+ // 到达 (x, y) 的路径数等于到达 (x - 1, y) 和 (x, y - 1) 路径数之和
+ memo[x][y] = dp(x - 1, y) + dp(x, y - 1);
+ return memo[x][y];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func uniquePaths(m int, n int) int {
+ // 备忘录
+ memo := make([][]int, m)
+ for i := range memo {
+ memo[i] = make([]int, n)
+ }
+ return dp(m-1, n-1, memo)
+}
+
+// 定义:从 (0, 0) 到 (x, y) 有 dp(x, y) 条路径
+func dp(x int, y int, memo [][]int) int {
+ // base case
+ if x == 0 && y == 0 {
+ return 1
+ }
+ if x < 0 || y < 0 {
+ return 0
+ }
+ // 避免冗余计算
+ if memo[x][y] > 0 {
+ return memo[x][y]
+ }
+ // 状态转移方程:
+ // 到达 (x, y) 的路径数等于到达 (x - 1, y) 和 (x, y - 1) 路径数之和
+ memo[x][y] = dp(x-1, y, memo) + dp(x, y-1, memo)
+ return memo[x][y]
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ // 备忘录
+ int[][] memo;
+
+ public int uniquePaths(int m, int n) {
+ memo = new int[m][n];
+ return dp(m - 1, n - 1);
+ }
+
+ // 定义:从 (0, 0) 到 (x, y) 有 dp(x, y) 条路径
+ int dp(int x, int y) {
+ // base case
+ if (x == 0 && y == 0) {
+ return 1;
+ }
+ if (x < 0 || y < 0) {
+ return 0;
+ }
+ // 避免冗余计算
+ if (memo[x][y] > 0) {
+ return memo[x][y];
+ }
+ // 状态转移方程:
+ // 到达 (x, y) 的路径数等于到达 (x - 1, y) 和 (x, y - 1) 路径数之和
+ memo[x][y] = dp(x - 1, y) + dp(x, y - 1);
+ return memo[x][y];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var uniquePaths = function(m, n) {
+ // 备忘录
+ let memo = new Array(m).fill().map(() => new Array(n).fill(0));
+ return dp(m - 1, n - 1);
+};
+
+// 定义:从 (0, 0) 到 (x, y) 有 dp(x, y) 条路径
+var dp = function(x, y) {
+ // base case
+ if (x === 0 && y === 0) {
+ return 1;
+ }
+ if (x < 0 || y < 0) {
+ return 0;
+ }
+ // 避免冗余计算
+ if (memo[x][y] > 0) {
+ return memo[x][y];
+ }
+ // 状态转移方程:
+ // 到达 (x, y) 的路径数等于到达 (x - 1, y) 和 (x, y - 1) 路径数之和
+ memo[x][y] = dp(x - 1, y) + dp(x, y - 1);
+ return memo[x][y];
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def __init__(self):
+ self.memo = None
+
+ def uniquePaths(self, m: int, n: int) -> int:
+ self.memo = [[0] * n for _ in range(m)]
+ return self.dp(m-1, n-1)
+
+ def dp(self, x: int, y: int) -> int:
+ # base case
+ if x == 0 and y == 0:
+ return 1
+ if x < 0 or y < 0:
+ return 0
+ # 避免冗余计算
+ if self.memo[x][y] > 0:
+ return self.memo[x][y]
+ # 状态转移方程:
+ # 到达 (x, y) 的路径数等于到达 (x - 1, y) 和 (x, y - 1) 路径数之和
+ self.memo[x][y] = self.dp(x - 1, y) + self.dp(x, y - 1)
+ return self.memo[x][y]
+```
+
+https://leetcode.cn/problems/2AoeFn 的多语言解法👆
+
+https://leetcode.cn/problems/3sum 的多语言解法👇
+
+```cpp
+// by labuladong (cpp)
+class Solution {
+ public:
+ vector> threeSum(vector& nums) {
+ sort(nums.begin(), nums.end());
+ // n 为 3,从 nums[0] 开始计算和为 0 的三元组
+ return nSumTarget(nums, 3, 0, 0);
+ }
+
+ /* 注意:调用这个函数之前一定要先给 nums 排序 */
+ // n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+ vector> nSumTarget(
+ vector& nums, int n, int start, int target) {
+
+ int sz = nums.size();
+ vector> res;
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if (n < 2 || sz < n) return res;
+ // 2Sum 是 base case
+ if (n == 2) {
+ // 双指针那一套操作
+ int lo = start, hi = sz - 1;
+ while (lo < hi) {
+ int sum = nums[lo] + nums[hi];
+ int left = nums[lo], right = nums[hi];
+ if (sum < target) {
+ while (lo < hi && nums[lo] == left) lo++;
+ } else if (sum > target) {
+ while (lo < hi && nums[hi] == right) hi--;
+ } else {
+ res.push_back({left, right});
+ while (lo < hi && nums[lo] == left) lo++;
+ while (lo < hi && nums[hi] == right) hi--;
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for (int i = start; i < sz; i++) {
+ vector>
+ sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
+ for (vector& arr : sub) {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ arr.push_back(nums[i]);
+ res.push_back(arr);
+ }
+ while (i < sz - 1 && nums[i] == nums[i + 1]) i++;
+ }
+ }
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func threeSum(nums []int) [][]int {
+ sort.Ints(nums)
+ // n 为 3,从 nums[0] 开始计算和为 0 的三元组
+ return nSumTarget(nums, 3, 0, 0)
+}
+
+/* 注意:调用这个函数之前一定要先给 nums 排序 */
+// n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+func nSumTarget(nums []int, n int, start int, target int) [][]int {
+ sz := len(nums)
+ var res [][]int
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if n < 2 || sz < n {
+ return res
+ }
+ // 2Sum 是 base case
+ if n == 2 {
+ // 双指针那一套操作
+ lo, hi := start, sz-1
+ for lo < hi {
+ sum := nums[lo] + nums[hi]
+ left, right := nums[lo], nums[hi]
+ if sum < target {
+ for lo < hi && nums[lo] == left {
+ lo++
+ }
+ } else if sum > target {
+ for lo < hi && nums[hi] == right {
+ hi--
+ }
+ } else {
+ res = append(res, []int{left, right})
+ for lo < hi && nums[lo] == left {
+ lo++
+ }
+ for lo < hi && nums[hi] == right {
+ hi--
+ }
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for i := start; i < sz; i++ {
+ sub := nSumTarget(nums, n-1, i+1, target-nums[i])
+ for _, arr := range sub {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ arr = append(arr, nums[i])
+ res = append(res, arr)
+ }
+ for i < sz-1 && nums[i] == nums[i+1] {
+ i++
+ }
+ }
+ }
+ return res
+}
+```
+
+```java
+// by chatGPT (java)
+class Solution {
+ public List> threeSum(int[] nums) {
+ Arrays.sort(nums);
+ // n 为 3,从 nums[0] 开始计算和为 0 的三元组
+ return nSumTarget(nums, 3, 0, 0);
+ }
+
+ /* 注意:调用这个函数之前一定要先给 nums 排序 */
+ // n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+ public List> nSumTarget(
+ int[] nums, int n, int start, int target) {
+
+ int sz = nums.length;
+ List> res = new ArrayList<>();
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if (n < 2 || sz < n) return res;
+ // 2Sum 是 base case
+ if (n == 2) {
+ // 双指针那一套操作
+ int lo = start, hi = sz - 1;
+ while (lo < hi) {
+ int sum = nums[lo] + nums[hi];
+ int left = nums[lo], right = nums[hi];
+ if (sum < target) {
+ while (lo < hi && nums[lo] == left) lo++;
+ } else if (sum > target) {
+ while (lo < hi && nums[hi] == right) hi--;
+ } else {
+ res.add(new ArrayList<>(Arrays.asList(left, right)));
+ while (lo < hi && nums[lo] == left) lo++;
+ while (lo < hi && nums[hi] == right) hi--;
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for (int i = start; i < sz; i++) {
+ List>
+ sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
+ for (List arr : sub) {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ arr.add(nums[i]);
+ res.add(arr);
+ }
+ while (i < sz - 1 && nums[i] == nums[i + 1]) i++;
+ }
+ }
+ return res;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var threeSum = function(nums) {
+ nums.sort((a, b) => a - b);
+ // n 为 3,从 nums[0] 开始计算和为 0 的三元组
+ return nSumTarget(nums, 3, 0, 0);
+}
+
+/* 注意:调用这个函数之前一定要先给 nums 排序 */
+// n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+var nSumTarget = function(nums, n, start, target) {
+ var sz = nums.length;
+ var res = [];
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if (n < 2 || sz < n) return res;
+ // 2Sum 是 base case
+ if (n == 2) {
+ // 双指针那一套操作
+ var lo = start, hi = sz - 1;
+ while (lo < hi) {
+ var sum = nums[lo] + nums[hi];
+ var left = nums[lo], right = nums[hi];
+ if (sum < target) {
+ while (lo < hi && nums[lo] == left) lo++;
+ } else if (sum > target) {
+ while (lo < hi && nums[hi] == right) hi--;
+ } else {
+ res.push([left, right]);
+ while (lo < hi && nums[lo] == left) lo++;
+ while (lo < hi && nums[hi] == right) hi--;
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for (var i = start; i < sz; i++) {
+ var sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
+ for (var j = 0; j < sub.length; j++) {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ sub[j].push(nums[i]);
+ res.push(sub[j]);
+ }
+ while (i < sz - 1 && nums[i] == nums[i + 1]) i++;
+ }
+ }
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def threeSum(self, nums: List[int]) -> List[List[int]]:
+ nums.sort()
+ # n 为 3,从 nums[0] 开始计算和为 0 的三元组
+ return self.nSumTarget(nums, 3, 0, 0)
+
+ # 注意:调用这个函数之前一定要先给 nums 排序
+ # n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+ def nSumTarget(self, nums: List[int], n: int, start: int, target: int) -> List[List[int]]:
+ sz = len(nums)
+ res = []
+ # 至少是 2Sum,且数组大小不应该小于 n
+ if n < 2 or sz < n:
+ return res
+ # 2Sum 是 base case
+ if n == 2:
+ # 双指针那一套操作
+ lo, hi = start, sz - 1
+ while lo < hi:
+ s = nums[lo] + nums[hi]
+ left, right = nums[lo], nums[hi]
+ if s < target:
+ while lo < hi and nums[lo] == left:
+ lo += 1
+ elif s > target:
+ while lo < hi and nums[hi] == right:
+ hi -= 1
+ else:
+ res.append([left, right])
+ while lo < hi and nums[lo] == left:
+ lo += 1
+ while lo < hi and nums[hi] == right:
+ hi -= 1
+ else:
+ # n > 2 时,递归计算 (n-1)Sum 的结果
+ for i in range(start, sz):
+ sub = self.nSumTarget(nums, n - 1, i + 1, target - nums[i])
+ for arr in sub:
+ # (n-1)Sum 加上 nums[i] 就是 nSum
+ arr.append(nums[i])
+ res.append(arr)
+ while i < sz - 1 and nums[i] == nums[i + 1]:
+ i += 1
+ return res
+```
+
+https://leetcode.cn/problems/3sum 的多语言解法👆
+
+https://leetcode.cn/problems/3sum-closest 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int threeSumClosest(vector& nums, int target) {
+ if (nums.size() < 3) {
+ return 0;
+ }
+ // 别忘了要先排序数组
+ sort(nums.begin(), nums.end());
+ // 记录三数之和与目标值的偏差
+ int delta = INT_MAX;
+ for (int i = 0; i < nums.size() - 2; i++) {
+ // 固定 nums[i] 为三数之和中的第一个数,
+ // 然后对 nums[i+1..] 搜索接近 target - nums[i] 的两数之和
+ int sum = nums[i] + twoSumClosest(nums, i + 1, target - nums[i]);
+ if (abs(delta) > abs(target - sum)) {
+ delta = target - sum;
+ }
+ }
+ return target - delta;
+ }
+
+ // 在 nums[start..] 搜索最接近 target 的两数之和
+ int twoSumClosest(vector& nums, int start, int target) {
+ int lo = start, hi = nums.size() - 1;
+ // 记录两数之和与目标值的偏差
+ int delta = INT_MAX;
+ while (lo < hi) {
+ int sum = nums[lo] + nums[hi];
+ if (abs(delta) > abs(target - sum)) {
+ delta = target - sum;
+ }
+ if (sum < target) {
+ lo++;
+ } else {
+ hi--;
+ }
+ }
+ return target - delta;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func threeSumClosest(nums []int, target int) int {
+ if len(nums) < 3 {
+ return 0
+ }
+ // 先排序数组
+ sort.Ints(nums)
+ // 记录三数之和与目标值的偏差
+ delta := math.MaxInt32
+ for i := 0; i < len(nums)-2; i++ {
+ // 固定 nums[i] 为三数之和中的第一个数,
+ // 然后对 nums[i+1..] 搜索接近 target - nums[i] 的两数之和
+ sum := nums[i] + twoSumClosest(nums, i+1, target-nums[i])
+ if int(math.Abs(float64(delta))) > int(math.Abs(float64(target-sum))) {
+ delta = target - sum
+ }
+ }
+ return target - delta
+}
+
+// 在 nums[start..] 搜索最接近 target 的两数之和
+func twoSumClosest(nums []int, start int, target int) int {
+ lo, hi := start, len(nums)-1
+ // 记录两数之和与目标值的偏差
+ delta := math.MaxInt32
+ for lo < hi {
+ sum := nums[lo] + nums[hi]
+ if int(math.Abs(float64(delta))) > int(math.Abs(float64(target-sum))) {
+ delta = target - sum
+ }
+ if sum < target {
+ lo++
+ } else {
+ hi--
+ }
+ }
+ return target - delta
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int threeSumClosest(int[] nums, int target) {
+ if (nums.length < 3) {
+ return 0;
+ }
+ // 别忘了要先排序数组
+ Arrays.sort(nums);
+ // 记录三数之和与目标值的偏差
+ int delta = Integer.MAX_VALUE;
+ for (int i = 0; i < nums.length - 2; i++) {
+ // 固定 nums[i] 为三数之和中的第一个数,
+ // 然后对 nums[i+1..] 搜索接近 target - nums[i] 的两数之和
+ int sum = nums[i] + twoSumClosest(nums, i + 1, target - nums[i]);
+ if (Math.abs(delta) > Math.abs(target - sum)) {
+ delta = target - sum;
+ }
+ }
+ return target - delta;
+ }
+
+ // 在 nums[start..] 搜索最接近 target 的两数之和
+ int twoSumClosest(int[] nums, int start, int target) {
+ int lo = start, hi = nums.length - 1;
+ // 记录两数之和与目标值的偏差
+ int delta = Integer.MAX_VALUE;
+ while (lo < hi) {
+ int sum = nums[lo] + nums[hi];
+ if (Math.abs(delta) > Math.abs(target - sum)) {
+ delta = target - sum;
+ }
+ if (sum < target) {
+ lo++;
+ } else {
+ hi--;
+ }
+ }
+ return target - delta;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var threeSumClosest = function(nums, target) {
+ if (nums.length < 3) {
+ return 0;
+ }
+ // 别忘了要先排序数组
+ nums.sort(function(a, b) {
+ return a - b;
+ });
+ // 记录三数之和与目标值的偏差
+ var delta = Number.MAX_SAFE_INTEGER;
+ for (var i = 0; i < nums.length - 2; i++) {
+ // 固定 nums[i] 为三数之和中的第一个数,
+ // 然后对 nums[i+1..] 搜索接近 target - nums[i] 的两数之和
+ var sum = nums[i] + twoSumClosest(nums, i + 1, target - nums[i]);
+ if (Math.abs(delta) > Math.abs(target - sum)) {
+ delta = target - sum;
+ }
+ }
+ return target - delta;
+};
+
+// 在 nums[start..] 搜索最接近 target 的两数之和
+var twoSumClosest = function(nums, start, target) {
+ var lo = start, hi = nums.length - 1;
+ // 记录两数之和与目标值的偏差
+ var delta = Number.MAX_SAFE_INTEGER;
+ while (lo < hi) {
+ var sum = nums[lo] + nums[hi];
+ if (Math.abs(delta) > Math.abs(target - sum)) {
+ delta = target - sum;
+ }
+ if (sum < target) {
+ lo++;
+ } else {
+ hi--;
+ }
+ }
+ return target - delta;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def threeSumClosest(self, nums: List[int], target: int) -> int:
+ if len(nums) < 3:
+ return 0
+ # 别忘了要先排序数组
+ nums.sort()
+ # 记录三数之和与目标值的偏差
+ delta = float('inf')
+ for i in range(len(nums) - 2):
+ # 固定 nums[i] 为三数之和中的第一个数,
+ # 然后对 nums[i+1..] 搜索接近 target - nums[i] 的两数之和
+ sum_ = nums[i] + self.twoSumClosest(nums, i + 1, target - nums[i])
+ if abs(delta) > abs(target - sum_):
+ delta = target - sum_
+ return target - delta
+
+ # 在 nums[start..] 搜索最接近 target 的两数之和
+ def twoSumClosest(self, nums: List[int], start: int, target: int) -> int:
+ lo, hi = start, len(nums) - 1
+ # 记录两数之和与目标值的偏差
+ delta = float('inf')
+ while lo < hi:
+ sum_ = nums[lo] + nums[hi]
+ if abs(delta) > abs(target - sum_):
+ delta = target - sum_
+ if sum_ < target:
+ lo += 1
+ else:
+ hi -= 1
+ return target - delta
+```
+
+https://leetcode.cn/problems/3sum-closest 的多语言解法👆
+
+https://leetcode.cn/problems/3sum-smaller 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int threeSumSmaller(vector& nums, int target) {
+ if (nums.size() < 3) {
+ return 0;
+ }
+ // 别忘了要先排序数组
+ sort(nums.begin(), nums.end());
+ int res = 0;
+ for (int i = 0; i < nums.size() - 2; i++) {
+ // 固定 nums[i] 为三数之和中的第一个数,
+ // 然后对 nums[i+1..] 搜索小于 target - nums[i] 的两数之和个数
+ res += twoSumSmaller(nums, i + 1, target - nums[i]);
+ }
+ return res;
+ }
+
+ // 在 nums[start..] 搜索小于 target 的两数之和个数
+ int twoSumSmaller(vector& nums, int start, int target) {
+ int lo = start, hi = nums.size() - 1;
+ int count = 0;
+ while (lo < hi) {
+ if (nums[lo] + nums[hi] < target) {
+ // nums[lo] 和 nums[lo+1..hi]
+ // 中的任一元素之和都小于 target
+ count += hi - lo;
+ lo++;
+ } else {
+ hi--;
+ }
+ }
+ return count;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func threeSumSmaller(nums []int, target int) int {
+ if len(nums) < 3 {
+ return 0
+ }
+ // 别忘了要先排序数组
+ sort.Ints(nums)
+ res := 0
+ for i := 0; i < len(nums) - 2; i++ {
+ // 固定 nums[i] 为三数之和中的第一个数,
+ // 然后对 nums[i+1..] 搜索小于 target - nums[i] 的两数之和个数
+ res += twoSumSmaller(nums, i + 1, target - nums[i])
+ }
+ return res
+}
+
+// 在 nums[start..] 搜索小于 target 的两数之和个数
+func twoSumSmaller(nums []int, start int, target int) int {
+ lo, hi := start, len(nums) - 1
+ count := 0
+ for lo < hi {
+ if nums[lo] + nums[hi] < target {
+ // nums[lo] 和 nums[lo+1..hi]
+ // 中的任一元素之和都小于 target
+ count += hi - lo
+ lo++
+ } else {
+ hi--
+ }
+ }
+ return count
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int threeSumSmaller(int[] nums, int target) {
+ if (nums.length < 3) {
+ return 0;
+ }
+ // 别忘了要先排序数组
+ Arrays.sort(nums);
+ int res = 0;
+ for (int i = 0; i < nums.length - 2; i++) {
+ // 固定 nums[i] 为三数之和中的第一个数,
+ // 然后对 nums[i+1..] 搜索小于 target - nums[i] 的两数之和个数
+ res += twoSumSmaller(nums, i + 1, target - nums[i]);
+ }
+ return res;
+ }
+
+ // 在 nums[start..] 搜索小于 target 的两数之和个数
+ int twoSumSmaller(int[] nums, int start, int target) {
+ int lo = start, hi = nums.length - 1;
+ int count = 0;
+ while (lo < hi) {
+ if (nums[lo] + nums[hi] < target) {
+ // nums[lo] 和 nums[lo+1..hi]
+ // 中的任一元素之和都小于 target
+ count += hi - lo;
+ lo++;
+ } else {
+ hi--;
+ }
+ }
+ return count;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var threeSumSmaller = function(nums, target) {
+ // 如果数组长度小于3,返回0
+ if(nums.length < 3) {
+ return 0;
+ }
+ // 将数组升序排序
+ nums.sort(function(a,b) {return a - b;});
+ // 定义变量res,初始化为0
+ var res = 0;
+ // 枚举第一个元素
+ for (var i = 0; i < nums.length - 2; i++) {
+ // 对第一个元素之后的元素搜索两数之和小于target-nums[i]的个数
+ res += twoSumSmaller(nums, i + 1, target - nums[i]);
+ }
+ // 返回答案
+ return res;
+
+ // 搜索nums[start..]内两数之和小于target的个数
+ function twoSumSmaller(nums, start, target) {
+ var lo = start, hi = nums.length - 1;
+ var count = 0;
+ while (lo < hi) {
+ // 如果nums[lo] + nums[hi] < target,这时nums[lo]和nums[lo + 1..hi]中任意一个数与nums[hi]相加都会小于target
+ if (nums[lo] + nums[hi] < target) {
+ // 计算加入nums[lo]时小于target的两数之和的个数,并将lo移动一位
+ count += hi - lo;
+ lo++;
+ } else {
+ // 如果nums[lo] + nums[hi] >= target,则将hi往前一位
+ hi--;
+ }
+ }
+ // 返回小于target的两数之和的个数
+ return count;
+ }
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def threeSumSmaller(self, nums: List[int], target: int) -> int:
+ if len(nums) < 3:
+ return 0
+ nums.sort()
+ res = 0
+ for i in range(len(nums) - 2):
+ # 固定 nums[i] 为三数之和中的第一个数,
+ # 然后对 nums[i+1..] 搜索小于 target - nums[i] 的两数之和个数
+ res += self.twoSumSmaller(nums, i + 1, target - nums[i])
+ return res
+
+ def twoSumSmaller(self, nums: List[int], start: int, target: int) -> int:
+ lo = start
+ hi = len(nums) - 1
+ count = 0
+ while lo < hi:
+ if nums[lo] + nums[hi] < target:
+ # nums[lo] 和 nums[lo+1..hi]
+ # 中的任一元素之和都小于 target
+ count += hi - lo
+ lo += 1
+ else:
+ hi -= 1
+ return count
+```
+
+https://leetcode.cn/problems/3sum-smaller 的多语言解法👆
+
+https://leetcode.cn/problems/3u1WK4 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
+ // p1 指向 A 链表头结点,p2 指向 B 链表头结点
+ ListNode *p1 = headA, *p2 = headB;
+ while (p1 != p2) {
+ // p1 走一步,如果走到 A 链表末尾,转到 B 链表
+ if (p1 == nullptr) p1 = headB;
+ else p1 = p1->next;
+ // p2 走一步,如果走到 B 链表末尾,转到 A 链表
+ if (p2 == nullptr) p2 = headA;
+ else p2 = p2->next;
+ }
+ return p1;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func getIntersectionNode(headA, headB *ListNode) *ListNode {
+ // p1 指向 A 链表头结点,p2 指向 B 链表头结点
+ p1, p2 := headA, headB
+ for p1 != p2 {
+ // p1 走一步,如果走到 A 链表末尾,转到 B 链表
+ if p1 == nil {
+ p1 = headB
+ } else {
+ p1 = p1.Next
+ }
+ // p2 走一步,如果走到 B 链表末尾,转到 A 链表
+ if p2 == nil {
+ p2 = headA
+ } else {
+ p2 = p2.Next
+ }
+ }
+ return p1
+}
+```
+
+```java
+// by labuladong (java)
+public class Solution {
+ public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
+ // p1 指向 A 链表头结点,p2 指向 B 链表头结点
+ ListNode p1 = headA, p2 = headB;
+ while (p1 != p2) {
+ // p1 走一步,如果走到 A 链表末尾,转到 B 链表
+ if (p1 == null) p1 = headB;
+ else p1 = p1.next;
+ // p2 走一步,如果走到 B 链表末尾,转到 A 链表
+ if (p2 == null) p2 = headA;
+ else p2 = p2.next;
+ }
+ return p1;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var getIntersectionNode = function(headA, headB) {
+ // p1 指向 A 链表头结点,p2 指向 B 链表头结点
+ let p1 = headA, p2 = headB;
+ while (p1 !== p2) {
+ // p1 走一步,如果走到 A 链表末尾,转到 B 链表
+ if (p1 === null) p1 = headB;
+ else p1 = p1.next;
+ // p2 走一步,如果走到 B 链表末尾,转到 A 链表
+ if (p2 === null) p2 = headA;
+ else p2 = p2.next;
+ }
+ return p1;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
+ # p1 指向 A 链表头结点,p2 指向 B 链表头结点
+ p1, p2 = headA, headB
+ while p1 != p2:
+ # p1 走一步,如果走到 A 链表末尾,转到 B 链表
+ if p1 is None:
+ p1 = headB
+ else:
+ p1 = p1.next
+ # p2 走一步,如果走到 B 链表末尾,转到 A 链表
+ if p2 is None:
+ p2 = headA
+ else:
+ p2 = p2.next
+ return p1
+```
+
+https://leetcode.cn/problems/3u1WK4 的多语言解法👆
+
+https://leetcode.cn/problems/4sum 的多语言解法👇
+
+```cpp
+// by labuladong (cpp)
+class Solution {
+ public:
+ vector> fourSum(vector& nums, int target) {
+ sort(nums.begin(), nums.end());
+ // n 为 4,从 nums[0] 开始计算和为 target 的四元组
+ return nSumTarget(nums, 4, 0, target);
+ }
+
+ /* 注意:调用这个函数之前一定要先给 nums 排序 */
+ // n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+ vector> nSumTarget(
+ vector& nums, int n, int start, int target) {
+
+ int sz = nums.size();
+ vector> res;
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if (n < 2 || sz < n) return res;
+ // 2Sum 是 base case
+ if (n == 2) {
+ // 双指针那一套操作
+ int lo = start, hi = sz - 1;
+ while (lo < hi) {
+ int sum = nums[lo] + nums[hi];
+ int left = nums[lo], right = nums[hi];
+ if (sum < target) {
+ while (lo < hi && nums[lo] == left) lo++;
+ } else if (sum > target) {
+ while (lo < hi && nums[hi] == right) hi--;
+ } else {
+ res.push_back({left, right});
+ while (lo < hi && nums[lo] == left) lo++;
+ while (lo < hi && nums[hi] == right) hi--;
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for (int i = start; i < sz; i++) {
+ vector>
+ sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
+ for (vector& arr : sub) {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ arr.push_back(nums[i]);
+ res.push_back(arr);
+ }
+ while (i < sz - 1 && nums[i] == nums[i + 1]) i++;
+ }
+ }
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func fourSum(nums []int, target int) [][]int {
+ sort.Ints(nums)
+ // n 为 4,从 nums[0] 开始计算和为 target 的四元组
+ return nSumTarget(nums, 4, 0, target)
+}
+
+/* 注意:调用这个函数之前一定要先给 nums 排序 */
+// n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+func nSumTarget(nums []int, n, start, target int) [][]int {
+ sz := len(nums)
+ res := [][]int{}
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if n < 2 || sz < n {
+ return res
+ }
+ // 2Sum 是 base case
+ if n == 2 {
+ // 双指针那一套操作
+ lo, hi := start, sz-1
+ for lo < hi {
+ sum := nums[lo] + nums[hi]
+ left, right := nums[lo], nums[hi]
+ if sum < target {
+ for lo < hi && nums[lo] == left {
+ lo++
+ }
+ } else if sum > target {
+ for lo < hi && nums[hi] == right {
+ hi--
+ }
+ } else {
+ res = append(res, []int{left, right})
+ for lo < hi && nums[lo] == left {
+ lo++
+ }
+ for lo < hi && nums[hi] == right {
+ hi--
+ }
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for i := start; i < sz; i++ {
+ sub := nSumTarget(nums, n-1, i+1, target-nums[i])
+ for _, arr := range sub {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ arr = append(arr, nums[i])
+ res = append(res, arr)
+ }
+ for i < sz-1 && nums[i] == nums[i+1] {
+ i++
+ }
+ }
+ }
+ return res
+}
+```
+
+```java
+// by chatGPT (java)
+class Solution {
+ public List> fourSum(int[] nums, int target) {
+ Arrays.sort(nums);
+ // n 为 4,从 nums[0] 开始计算和为 target 的四元组
+ return nSumTarget(nums, 4, 0, target);
+ }
+
+ /* 注意:调用这个函数之前一定要先给 nums 排序 */
+ // n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+ private List> nSumTarget(int[] nums, int n, int start, int target) {
+ int sz = nums.length;
+ List> res = new ArrayList<>();
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if (n < 2 || sz < n) return res;
+ // 2Sum 是 base case
+ if (n == 2) {
+ // 双指针那一套操作
+ int lo = start, hi = sz - 1;
+ while (lo < hi) {
+ int sum = nums[lo] + nums[hi];
+ int left = nums[lo], right = nums[hi];
+ if (sum < target) {
+ while (lo < hi && nums[lo] == left) lo++;
+ } else if (sum > target) {
+ while (lo < hi && nums[hi] == right) hi--;
+ } else {
+ res.add(new ArrayList<>(Arrays.asList(left, right)));
+ while (lo < hi && nums[lo] == left) lo++;
+ while (lo < hi && nums[hi] == right) hi--;
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for (int i = start; i < sz; i++) {
+ List> sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
+ for (List arr : sub) {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ arr.add(nums[i]);
+ res.add(arr);
+ }
+ while (i < sz - 1 && nums[i] == nums[i + 1]) i++;
+ }
+ }
+ return res;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var fourSum = function(nums, target) {
+ nums.sort((a, b) => a - b);
+ // n 为 4,从 nums[0] 开始计算和为 target 的四元组
+ return nSumTarget(nums, 4, 0, target);
+};
+
+/* 注意:调用这个函数之前一定要先给 nums 排序 */
+// n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+var nSumTarget = function(nums, n, start, target) {
+ var sz = nums.length;
+ var res = [];
+ // 至少是 2Sum,且数组大小不应该小于 n
+ if (n < 2 || sz < n) return res;
+ // 2Sum 是 base case
+ if (n === 2) {
+ // 双指针那一套操作
+ var lo = start, hi = sz - 1;
+ while (lo < hi) {
+ var sum = nums[lo] + nums[hi];
+ var left = nums[lo], right = nums[hi];
+ if (sum < target) {
+ while (lo < hi && nums[lo] === left) lo++;
+ } else if (sum > target) {
+ while (lo < hi && nums[hi] === right) hi--;
+ } else {
+ res.push([left, right]);
+ while (lo < hi && nums[lo] === left) lo++;
+ while (lo < hi && nums[hi] === right) hi--;
+ }
+ }
+ } else {
+ // n > 2 时,递归计算 (n-1)Sum 的结果
+ for (var i = start; i < sz; i++) {
+ var sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
+ for (var arr of sub) {
+ // (n-1)Sum 加上 nums[i] 就是 nSum
+ arr.push(nums[i]);
+ res.push(arr);
+ }
+ while (i < sz - 1 && nums[i] === nums[i + 1]) i++;
+ }
+ }
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
+ nums.sort()
+ # n 为 4,从 nums[0] 开始计算和为 target 的四元组
+ return self.nSumTarget(nums, 4, 0, target)
+
+ # 注意:调用这个函数之前一定要先给 nums 排序
+ # n 填写想求的是几数之和,start 从哪个索引开始计算(一般填 0),target 填想凑出的目标和
+ def nSumTarget(self, nums: List[int], n: int, start: int, target: int) -> List[List[int]]:
+ sz = len(nums)
+ res = []
+ # 至少是 2Sum,且数组大小不应该小于 n
+ if n < 2 or sz < n:
+ return res
+ # 2Sum 是 base case
+ if n == 2:
+ # 双指针那一套操作
+ lo, hi = start, sz - 1
+ while lo < hi:
+ s = nums[lo] + nums[hi]
+ left, right = nums[lo], nums[hi]
+ if s < target:
+ while lo < hi and nums[lo] == left:
+ lo += 1
+ elif s > target:
+ while lo < hi and nums[hi] == right:
+ hi -= 1
+ else:
+ res.append([left, right])
+ while lo < hi and nums[lo] == left:
+ lo += 1
+ while lo < hi and nums[hi] == right:
+ hi -= 1
+ else:
+ # n > 2 时,递归计算 (n-1)Sum 的结果
+ for i in range(start, sz):
+ sub = self.nSumTarget(nums, n - 1, i + 1, target - nums[i])
+ for arr in sub:
+ # (n-1)Sum 加上 nums[i] 就是 nSum
+ arr.append(nums[i])
+ res.append(arr)
+ while i < sz - 1 and nums[i] == nums[i + 1]:
+ i += 1
+ return res
+```
+
+https://leetcode.cn/problems/4sum 的多语言解法👆
+
+https://leetcode.cn/problems/8Zf90G 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int evalRPN(vector& tokens) {
+ stack stk;
+ for (const auto& token : tokens) {
+ if (string("+-*/").find(token) != string::npos) {
+ // 是个运算符,从栈顶拿出两个数字进行运算,运算结果入栈
+ int a = stk.top();
+ stk.pop();
+ int b = stk.top();
+ stk.pop();
+ switch (token[0]) {
+ case '+':
+ stk.push(b + a);
+ break;
+ case '*':
+ stk.push(b * a);
+ break;
+ // 对于减法和除法,顺序别搞反了,第二个数是被除(减)数
+ case '-':
+ stk.push(b - a);
+ break;
+ case '/':
+ stk.push(b / a);
+ break;
+ }
+ } else {
+ // 是个数字,直接入栈即可
+ stk.push(stoi(token));
+ }
+ }
+ // 最后栈中剩下一个数字,即是计算结果
+ return stk.top();
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func evalRPN(tokens []string) int {
+ stk := make([]int, 0)
+ for _, token := range tokens {
+ if strings.Contains("+-*/", token) {
+ // 是个运算符,从栈顶拿出两个数字进行运算,运算结果入栈
+ a, b := stk[len(stk)-1], stk[len(stk)-2]
+ stk = stk[:len(stk)-2]
+ switch token {
+ case "+":
+ stk = append(stk, a+b)
+ case "*":
+ stk = append(stk, a*b)
+ // 对于减法和除法,顺序别搞反了,第二个数是被除(减)数
+ case "-":
+ stk = append(stk, b-a)
+ case "/":
+ stk = append(stk, b/a)
+ }
+ } else {
+ // 是个数字,直接入栈即可
+ num, _ := strconv.Atoi(token)
+ stk = append(stk, num)
+ }
+ }
+ // 最后栈中剩下一个数字,即是计算结果
+ return stk[0]
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int evalRPN(String[] tokens) {
+ Stack stk = new Stack<>();
+ for (String token : tokens) {
+ if ("+-*/".contains(token)) {
+ // 是个运算符,从栈顶拿出两个数字进行运算,运算结果入栈
+ int a = stk.pop(), b = stk.pop();
+ switch (token) {
+ case "+":
+ stk.push(a + b);
+ break;
+ case "*":
+ stk.push(a * b);
+ break;
+ // 对于减法和除法,顺序别搞反了,第二个数是被除(减)数
+ case "-":
+ stk.push(b - a);
+ break;
+ case "/":
+ stk.push(b / a);
+ break;
+ }
+ } else {
+ // 是个数字,直接入栈即可
+ stk.push(Integer.parseInt(token));
+ }
+ }
+ // 最后栈中剩下一个数字,即是计算结果
+ return stk.pop();
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var evalRPN = function(tokens) {
+ let stk = [];
+ for (let i = 0; i < tokens.length; i++) {
+ let token = tokens[i];
+ if ("+-*/".includes(token)) {
+ // 是个运算符,从栈顶拿出两个数字进行运算,运算结果入栈
+ let a = stk.pop(), b = stk.pop();
+ switch (token) {
+ case "+":
+ stk.push(a + b);
+ break;
+ case "*":
+ stk.push(a * b);
+ break;
+ // 对于减法和除法,顺序别搞反了,第二个数是被除(减)数
+ case "-":
+ stk.push(b - a);
+ break;
+ case "/":
+ stk.push(parseInt(b / a));
+ break;
+ }
+ } else {
+ // 是个数字,直接入栈即可
+ stk.push(parseInt(token));
+ }
+ }
+ // 最后栈中剩下一个数字,即是计算结果
+ return stk.pop();
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def evalRPN(self, tokens: List[str]) -> int:
+ stk = []
+ for token in tokens:
+ if token in "+-*/":
+ # 是个运算符,从栈顶拿出两个数字进行运算,运算结果入栈
+ a = stk.pop()
+ b = stk.pop()
+ if token == "+":
+ stk.append(a + b)
+ elif token == "-":
+ stk.append(b - a)
+ elif token == "*":
+ stk.append(a * b)
+ else: # token == "/"
+ stk.append(int(b / a))
+ else:
+ # 是个数字,直接入栈即可
+ stk.append(int(token))
+ # 最后栈中剩下一个数字,即是计算结果
+ return stk.pop()
+```
+
+https://leetcode.cn/problems/8Zf90G 的多语言解法👆
+
+https://leetcode.cn/problems/B1IidL 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int peakIndexInMountainArray(vector& nums) {
+ // 取两端都闭的二分搜索
+ int left = 0, right = nums.size() - 1;
+ // 因为题目必然有解,所以设置 left == right 为结束条件
+ while (left < right) {
+ int mid = left + (right - left) / 2;
+ if (nums[mid] > nums[mid + 1]) {
+ // mid 本身就是峰值或其左侧有一个峰值
+ right = mid;
+ } else {
+ // mid 右侧有一个峰值
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func peakIndexInMountainArray(nums []int) int {
+ // 取两端都闭的二分搜索
+ left, right := 0, len(nums)-1
+ // 因为题目必然有解,所以设置 left == right 为结束条件
+ for left < right {
+ mid := left + (right-left)/2
+ if nums[mid] > nums[mid+1] {
+ // mid 本身就是峰值或其左侧有一个峰值
+ right = mid
+ } else {
+ // mid 右侧有一个峰值
+ left = mid + 1
+ }
+ }
+ return left
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int peakIndexInMountainArray(int[] nums) {
+ // 取两端都闭的二分搜索
+ int left = 0, right = nums.length - 1;
+ // 因为题目必然有解,所以设置 left == right 为结束条件
+ while (left < right) {
+ int mid = left + (right - left) / 2;
+ if (nums[mid] > nums[mid + 1]) {
+ // mid 本身就是峰值或其左侧有一个峰值
+ right = mid;
+ } else {
+ // mid 右侧有一个峰值
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var peakIndexInMountainArray = function(nums) {
+ // 取两端都闭的二分搜索
+ let left = 0, right = nums.length - 1;
+ // 因为题目必然有解,所以设置 left == right 为结束条件
+ while (left < right) {
+ let mid = left + Math.floor((right - left) / 2);
+ if (nums[mid] > nums[mid + 1]) {
+ // mid 本身就是峰值或其左侧有一个峰值
+ right = mid;
+ } else {
+ // mid 右侧有一个峰值
+ left = mid + 1;
+ }
+ }
+ return left;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def peakIndexInMountainArray(self, nums: List[int]) -> int:
+ # 取两端都闭的二分搜索
+ left, right = 0, len(nums) - 1
+ # 因为题目必然有解,所以设置 left == right 为结束条件
+ while left < right:
+ mid = left + (right - left) // 2
+ if nums[mid] > nums[mid + 1]:
+ # mid 本身就是峰值或其左侧有一个峰值
+ right = mid
+ else:
+ # mid 右侧有一个峰值
+ left = mid + 1
+ return left
+```
+
+https://leetcode.cn/problems/B1IidL 的多语言解法👆
+
+https://leetcode.cn/problems/FortPu 的多语言解法👇
+
+```cpp
+// by labuladong (cpp)
+class RandomizedSet {
+ public:
+ // 存储元素的值
+ vector nums;
+ // 记录每个元素对应在 nums 中的索引
+ unordered_map valToIndex;
+
+ bool insert(int val) {
+ // 若 val 已存在,不用再插入
+ if (valToIndex.count(val)) {
+ return false;
+ }
+ // 若 val 不存在,插入到 nums 尾部,
+ // 并记录 val 对应的索引值
+ valToIndex[val] = nums.size();
+ nums.push_back(val);
+ return true;
+ }
+
+ bool remove(int val) {
+ // 若 val 不存在,不用再删除
+ if (!valToIndex.count(val)) {
+ return false;
+ }
+ // 先拿到 val 的索引
+ int index = valToIndex[val];
+ // 将最后一个元素对应的索引修改为 index
+ valToIndex[nums.back()] = index;
+ // 交换 val 和最后一个元素
+ swap(nums[index], nums.back());
+ // 在数组中删除元素 val
+ nums.pop_back();
+ // 删除元素 val 对应的索引
+ valToIndex.erase(val);
+ return true;
+ }
+
+ int getRandom() {
+ // 随机获取 nums 中的一个元素
+ return nums[rand() % nums.size()];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+// 定义结构体
+type RandomizedSet struct {
+ // 存储元素的值
+ nums []int
+ // 记录每个元素对应在 nums 中的索引
+ valToIndex map[int]int
+}
+
+// 插入操作
+func (r *RandomizedSet) insert(val int) bool {
+ // 若 val 已存在,不用再插入
+ if _, ok := r.valToIndex[val]; ok {
+ return false
+ }
+ // 若 val 不存在,插入到 nums 尾部,
+ // 并记录 val 对应的索引值
+ r.valToIndex[val] = len(r.nums)
+ r.nums = append(r.nums, val)
+ return true
+}
+
+// 删除操作
+func (r *RandomizedSet) remove(val int) bool {
+ // 若 val 不存在,不用再删除
+ if _, ok := r.valToIndex[val]; !ok {
+ return false
+ }
+ // 先拿到 val 的索引
+ index := r.valToIndex[val]
+ // 将最后一个元素对应的索引修改为 index
+ r.valToIndex[r.nums[len(r.nums)-1]] = index
+ // 交换 val 和最后一个元素
+ r.nums[index], r.nums[len(r.nums)-1] = r.nums[len(r.nums)-1], r.nums[index]
+ // 在数组中删除元素 val
+ r.nums = r.nums[:len(r.nums)-1]
+ // 删除元素 val 对应的索引
+ delete(r.valToIndex, val)
+ return true
+}
+
+// 随机获取元素
+func (r *RandomizedSet) getRandom() int {
+ // 随机获取 nums 中的一个元素
+ return r.nums[rand.Intn(len(r.nums))]
+}
+```
+
+```java
+// by chatGPT (java)
+class RandomizedSet {
+ // 存储元素的值
+ List nums;
+ // 记录每个元素对应在 nums 中的索引
+ Map valToIndex;
+
+ public boolean insert(int val) {
+ // 若 val 已存在,不用再插入
+ if (valToIndex.containsKey(val)) {
+ return false;
+ }
+ // 若 val 不存在,插入到 nums 尾部,
+ // 并记录 val 对应的索引值
+ valToIndex.put(val, nums.size());
+ nums.add(val);
+ return true;
+ }
+
+ public boolean remove(int val) {
+ // 若 val 不存在,不用再删除
+ if (!valToIndex.containsKey(val)) {
+ return false;
+ }
+ // 先拿到 val 的索引
+ int index = valToIndex.get(val);
+ // 将最后一个元素对应的索引修改为 index
+ valToIndex.put(nums.get(nums.size()-1), index);
+ // 交换 val 和最后一个元素
+ Collections.swap(nums, index, nums.size()-1);
+ // 在数组中删除元素 val
+ nums.remove(nums.size()-1);
+ // 删除元素 val 对应的索引
+ valToIndex.remove(val);
+ return true;
+ }
+
+ public int getRandom() {
+ // 随机获取 nums 中的一个元素
+ return nums.get((int)(Math.random() * nums.size()));
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+/**
+ * Initialize your data structure here.
+ */
+var RandomizedSet = function() {
+ // 存储元素的值
+ this.nums = [];
+ // 记录每个元素对应在 nums 中的索引
+ this.valToIndex = new Map();
+};
+
+/**
+ * Inserts a value to the set. Returns true if the set did not already contain the specified element.
+ * @param {number} val
+ * @return {boolean}
+ */
+RandomizedSet.prototype.insert = function(val) {
+ // 若 val 已存在,不用再插入
+ if (this.valToIndex.has(val)) {
+ return false;
+ }
+ // 若 val 不存在,插入到 nums 尾部,
+ // 并记录 val 对应的索引值
+ this.valToIndex.set(val, this.nums.length);
+ this.nums.push(val);
+ return true;
+};
+
+/**
+ * Removes a value from the set. Returns true if the set contained the specified element.
+ * @param {number} val
+ * @return {boolean}
+ */
+RandomizedSet.prototype.remove = function(val) {
+ // 若 val 不存在,不用再删除
+ if (!this.valToIndex.has(val)) {
+ return false;
+ }
+ // 先拿到 val 的索引
+ const index = this.valToIndex.get(val);
+ // 将最后一个元素对应的索引修改为 index
+ this.valToIndex.set(this.nums[this.nums.length - 1], index);
+ // 交换 val 和最后一个元素
+ [this.nums[index], this.nums[this.nums.length - 1]] = [this.nums[this.nums.length - 1], this.nums[index]];
+ // 在数组中删除元素 val
+ this.nums.pop();
+ // 删除元素 val 对应的索引
+ this.valToIndex.delete(val);
+ return true;
+};
+
+/**
+ * Get a random element from the set.
+ * @return {number}
+ */
+RandomizedSet.prototype.getRandom = function() {
+ // 随机获取 nums 中的一个元素
+ return this.nums[Math.floor(Math.random() * this.nums.length)];
+};
+```
+
+```python
+# by chatGPT (python)
+class RandomizedSet:
+ def __init__(self):
+ # 存储元素的值
+ self.nums = []
+ # 记录每个元素对应在 nums 中的索引
+ self.valToIndex = {}
+
+ def insert(self, val: int) -> bool:
+ # 若 val 已存在,不用再插入
+ if val in self.valToIndex:
+ return False
+ # 若 val 不存在,插入到 nums 尾部,
+ # 并记录 val 对应的索引值
+ self.valToIndex[val] = len(self.nums)
+ self.nums.append(val)
+ return True
+
+ def remove(self, val: int) -> bool:
+ # 若 val 不存在,不用再删除
+ if val not in self.valToIndex:
+ return False
+ # 先拿到 val 的索引
+ index = self.valToIndex[val]
+ # 将最后一个元素对应的索引修改为 index
+ self.valToIndex[self.nums[-1]] = index
+ # 交换 val 和最后一个元素
+ self.nums[index], self.nums[-1] = self.nums[-1], self.nums[index]
+ # 在数组中删除元素 val
+ self.nums.pop()
+ # 删除元素 val 对应的索引
+ self.valToIndex.pop(val)
+ return True
+
+ def getRandom(self) -> int:
+ # 随机获取 nums 中的一个元素
+ return self.nums[random.randint(0, len(self.nums) - 1)]
+```
+
+https://leetcode.cn/problems/FortPu 的多语言解法👆
+
+https://leetcode.cn/problems/Gu0c2T 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+private:
+ // 备忘录
+ vector memo;
+ // dp 函数
+ int dp(vector& nums, int start) {
+ if (start >= nums.size()) {
+ return 0;
+ }
+ // 避免重复计算
+ if (memo[start] != -1) {
+ return memo[start];
+ }
+ int res = max(dp(nums, start + 1),
+ nums[start] + dp(nums, start + 2));
+ // 记入备忘录
+ memo[start] = res;
+ return res;
+ }
+
+public:
+ // 主函数
+ int rob(vector& nums) {
+ // 初始化备忘录
+ memo.resize(nums.size(), -1);
+ // 强盗从第 0 间房子开始抢劫
+ return dp(nums, 0);
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+import (
+ "fmt"
+)
+
+func rob(nums []int) int {
+ // 初始化备忘录
+ memo := make([]int, len(nums))
+ for i := 0; i < len(memo); i++ {
+ memo[i] = -1
+ }
+ // 强盗从第 0 间房子开始抢劫
+ return dp(nums, 0, memo)
+}
+
+// 返回 dp[start..] 能抢到的最大值
+func dp(nums []int, start int, memo []int) int {
+ if start >= len(nums) {
+ return 0
+ }
+ // 避免重复计算
+ if memo[start] != -1 {
+ return memo[start]
+ }
+
+ res := max(dp(nums, start+1, memo), nums[start]+dp(nums, start+2, memo))
+ // 记入备忘录
+ memo[start] = res
+ return res
+}
+
+func max(x, y int) int {
+ if x > y {
+ return x
+ }
+ return y
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ // 备忘录
+ private int[] memo;
+ // 主函数
+ public int rob(int[] nums) {
+ // 初始化备忘录
+ memo = new int[nums.length];
+ Arrays.fill(memo, -1);
+ // 强盗从第 0 间房子开始抢劫
+ return dp(nums, 0);
+ }
+
+ // 返回 dp[start..] 能抢到的最大值
+ private int dp(int[] nums, int start) {
+ if (start >= nums.length) {
+ return 0;
+ }
+ // 避免重复计算
+ if (memo[start] != -1) return memo[start];
+
+ int res = Math.max(dp(nums, start + 1),
+ nums[start] + dp(nums, start + 2));
+ // 记入备忘录
+ memo[start] = res;
+ return res;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var rob = function(nums) {
+ // 备忘录
+ const memo = new Array(nums.length).fill(-1);
+
+ // 返回 dp[start..] 能抢到的最大值
+ const dp = (start) => {
+ if (start >= nums.length) {
+ return 0;
+ }
+ // 避免重复计算
+ if (memo[start] != -1) return memo[start];
+
+ const res = Math.max(dp(start + 1), nums[start] + dp(start + 2));
+ // 记入备忘录
+ memo[start] = res;
+ return res;
+ }
+
+ // 强盗从第 0 间房子开始抢劫
+ return dp(0);
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def __init__(self):
+ # 备忘录
+ self.memo = None
+
+ # 主函数
+ def rob(self, nums: List[int]) -> int:
+ # 初始化备忘录
+ self.memo = [-1] * len(nums)
+ # 强盗从第 0 间房子开始抢劫
+ return self.dp(nums, 0)
+
+ # 返回 dp[start..] 能抢到的最大值
+ def dp(self, nums: List[int], start: int) -> int:
+ if start >= len(nums):
+ return 0
+ # 避免重复计算
+ if self.memo[start] != -1:
+ return self.memo[start]
+ res = max(self.dp(nums, start + 1),
+ nums[start] + self.dp(nums, start + 2))
+ # 记入备忘录
+ self.memo[start] = res
+ return res
+```
+
+https://leetcode.cn/problems/Gu0c2T 的多语言解法👆
+
+https://leetcode.cn/problems/IDBivT 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ vector generateParenthesis(int n) {
+ if (n == 0) return {};
+ // 记录所有合法的括号组合
+ vector res;
+ // 回溯过程中的路径
+ string track;
+ // 可用的左括号和右括号数量初始化为 n
+ backtrack(n, n, track, res);
+ return res;
+ }
+
+ // 可用的左括号数量为 left 个,可用的右括号数量为 rgiht 个
+ void backtrack(int left, int right,
+ string& track, vector& res) {
+ // 若左括号剩下的多,说明不合法
+ if (right < left) return;
+ // 数量小于 0 肯定是不合法的
+ if (left < 0 || right < 0) return;
+ // 当所有括号都恰好用完时,得到一个合法的括号组合
+ if (left == 0 && right == 0) {
+ res.push_back(track);
+ return;
+ }
+
+ // 尝试放一个左括号
+ track.push_back('('); // 选择
+ backtrack(left - 1, right, track, res);
+ track.pop_back(); // 撤消选择
+
+ // 尝试放一个右括号
+ track.push_back(')'); // 选择
+ backtrack(left, right - 1, track, res);
+ track.pop_back(); // 撤消选择
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func generateParenthesis(n int) []string {
+ if n == 0 {
+ return []string{}
+ }
+ // 记录所有合法的括号组合
+ var res []string
+ // 回溯过程中的路径
+ var track string
+ // 可用的左括号和右括号数量初始化为 n
+ backtrack(n, n, &track, &res)
+ return res
+}
+
+// 可用的左括号数量为 left 个,可用的右括号数量为 right 个
+func backtrack(left, right int, track *string, res *[]string) {
+ // 若左括号剩下的多,说明不合法
+ if right < left {
+ return
+ }
+ // 数量小于 0 肯定是不合法的
+ if left < 0 || right < 0 {
+ return
+ }
+ // 当所有括号都恰好用完时,得到一个合法的括号组合
+ if left == 0 && right == 0 {
+ *res = append(*res, *track)
+ return
+ }
+
+ // 尝试放一个左括号
+ *track += "(" // 选择
+ backtrack(left-1, right, track, res)
+ *track = (*track)[:len(*track)-1] // 撤消选择
+
+ // 尝试放一个右括号
+ *track += ")" // 选择
+ backtrack(left, right-1, track, res)
+ *track = (*track)[:len(*track)-1] // 撤消选择
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public:
+ vector generateParenthesis(int n) {
+ if (n == 0) return {};
+ // 记录所有合法的括号组合
+ vector res;
+ // 回溯过程中的路径
+ string track;
+ // 可用的左括号和右括号数量初始化为 n
+ backtrack(n, n, track, res);
+ return res;
+ }
+
+ // 可用的左括号数量为 left 个,可用的右括号数量为 rgiht 个
+ void backtrack(int left, int right,
+ string& track, vector& res) {
+ // 若左括号剩下的多,说明不合法
+ if (right < left) return;
+ // 数量小于 0 肯定是不合法的
+ if (left < 0 || right < 0) return;
+ // 当所有括号都恰好用完时,得到一个合法的括号组合
+ if (left == 0 && right == 0) {
+ res.push_back(track);
+ return;
+ }
+
+ // 尝试放一个左括号
+ track.push_back('('); // 选择
+ backtrack(left - 1, right, track, res);
+ track.pop_back(); // 撤消选择
+
+ // 尝试放一个右括号
+ track.push_back(')'); // 选择
+ backtrack(left, right - 1, track, res);
+ track.pop_back(); // 撤消选择
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var generateParenthesis = function(n) {
+ if (n === 0) return [];
+ // 记录所有合法的括号组合
+ var res = [];
+ // 回溯过程中的路径
+ var track = "";
+ // 可用的左括号和右括号数量初始化为 n
+ backtrack(n, n, track, res);
+ return res;
+};
+
+// 可用的左括号数量为 left 个,可用的右括号数量为 rgiht 个
+var backtrack = function(left, right, track, res) {
+ // 若左括号剩下的多,说明不合法
+ if (right < left) return;
+ // 数量小于 0 肯定是不合法的
+ if (left < 0 || right < 0) return;
+ // 当所有括号都恰好用完时,得到一个合法的括号组合
+ if (left === 0 && right === 0) {
+ res.push(track);
+ return;
+ }
+
+ // 尝试放一个左括号
+ track += '('; // 选择
+ backtrack(left - 1, right, track, res);
+ track = track.substring(0, track.length - 1); // 撤消选择
+
+ // 尝试放一个右括号
+ track += ')'; // 选择
+ backtrack(left, right - 1, track, res);
+ track = track.substring(0, track.length - 1); // 撤消选择
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def generateParenthesis(self, n: int) -> List[str]:
+ if n == 0:
+ return []
+ # 记录所有合法的括号组合
+ res = []
+ # 回溯过程中的路径
+ track = ""
+ # 可用的左括号和右括号数量初始化为 n
+ self.backtrack(n, n, track, res)
+ return res
+
+ # 可用的左括号数量为 left 个,可用的右括号数量为 rgiht 个
+ def backtrack(self, left: int, right: int, track: str, res: List[str]) -> None:
+ # 若右括号剩下的多,说明不合法
+ if right < left:
+ return
+ # 数量小于 0 肯定是不合法的
+ if left < 0 or right < 0:
+ return
+ # 当所有括号都恰好用完时,得到一个合法的括号组合
+ if left == 0 and right == 0:
+ res.append(track)
+ return
+
+ # 尝试放一个左括号
+ track += '(' # 选择
+ self.backtrack(left - 1, right, track, res)
+ track = track[:-1] # 撤消选择
+
+ # 尝试放一个右括号
+ track += ')' # 选择
+ self.backtrack(left, right - 1, track, res)
+ track = track[:-1] # 撤消选择
+```
+
+https://leetcode.cn/problems/IDBivT 的多语言解法👆
+
+https://leetcode.cn/problems/M1oyTv 的多语言解法👇
+
+```cpp
+// by labuladong (cpp)
+class Solution {
+ public:
+ string minWindow(string s, string t) {
+ unordered_map need, window;
+ for (char c : t) need[c]++;
+
+ int left = 0, right = 0;
+ int valid = 0;
+ // 记录最小覆盖子串的起始索引及长度
+ int start = 0, len = INT_MAX;
+ /**
+ 
+ */
+ while (right < s.size()) {
+ // c 是将移入窗口的字符
+ char c = s[right];
+ // 右移窗口
+ right++;
+ // 进行窗口内数据的一系列更新
+ if (need.count(c)) {
+ window[c]++;
+ if (window[c] == need[c])
+ valid++;
+ }
+
+ // 判断左侧窗口是否要收缩
+ while (valid == need.size()) {
+ /**
+ 
+ */
+ // 在这里更新最小覆盖子串
+ if (right - left < len) {
+ start = left;
+ len = right - left;
+ }
+ // d 是将移出窗口的字符
+ char d = s[left];
+ // 左移窗口
+ left++;
+ // 进行窗口内数据的一系列更新
+ if (need.count(d)) {
+ if (window[d] == need[d])
+ valid--;
+ window[d]--;
+ }
+ }
+ /**
+ 
+ */
+ }
+ // 返回最小覆盖子串
+ return len == INT_MAX ?
+ "" : s.substr(start, len);
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func minWindow(s string, t string) string {
+ need := make(map[byte]int)
+ window := make(map[byte]int)
+ for i := 0; i < len(t); i++ {
+ need[t[i]]++
+ }
+
+ left, right, valid := 0, 0, 0
+ // 记录最小覆盖子串的起始索引及长度
+ start, len := 0, math.MaxInt32
+ /**
+ 
+ */
+ for right < len(s) {
+ // c 是将移入窗口的字符
+ c := s[right]
+ // 右移窗口
+ right++
+ // 进行窗口内数据的一系列更新
+ if _, ok := need[c]; ok {
+ window[c]++
+ if window[c] == need[c] {
+ valid++
+ }
+ }
+
+ // 判断左侧窗口是否要收缩
+ for valid == len(need) {
+ /**
+ 
+ */
+ // 在这里更新最小覆盖子串
+ if right-left < len {
+ start = left
+ len = right - left
+ }
+
+ // d 是将移出窗口的字符
+ d := s[left]
+ // 左移窗口
+ left++
+ // 进行窗口内数据的一系列更新
+ if _, ok := need[d]; ok {
+ if window[d] == need[d] {
+ valid--
+ }
+ window[d]--
+ }
+ }
+ /**
+ 
+ */
+ }
+ // 返回最小覆盖子串
+ if len == math.MaxInt32 {
+ return ""
+ }
+ return s[start : start+len]
+}
+```
+
+```java
+// by chatGPT (java)
+class Solution {
+ public String minWindow(String s, String t) {
+ HashMap need = new HashMap<>();
+ HashMap window = new HashMap<>();
+ for (char c : t.toCharArray()) {
+ need.put(c, need.getOrDefault(c, 0) + 1);
+ }
+ int left = 0, right = 0;
+ int valid = 0;
+ // 记录最小覆盖子串的起始索引及长度
+ int start = 0, len = Integer.MAX_VALUE;
+ /**
+ 
+ */
+ while (right < s.length()) {
+ // c 是将移入窗口的字符
+ char c = s.charAt(right);
+ // 右移窗口
+ right++;
+ // 进行窗口内数据的一系列更新
+ if (need.containsKey(c)) {
+ window.put(c, window.getOrDefault(c, 0) + 1);
+ if (window.get(c).equals(need.get(c))) {
+ valid++;
+ }
+ }
+
+ // 判断左侧窗口是否要收缩
+ while (valid == need.size()) {
+ /**
+ 
+ */
+ // 在这里更新最小覆盖子串
+ if (right - left < len) {
+ start = left;
+ len = right - left;
+ }
+ // d 是将移出窗口的字符
+ char d = s.charAt(left);
+ // 左移窗口
+ left++;
+ // 进行窗口内数据的一系列更新
+ if (need.containsKey(d)) {
+ if (window.get(d).equals(need.get(d))) {
+ valid--;
+ }
+ window.put(d, window.get(d) - 1);
+ }
+ }
+ /**
+ 
+ */
+ }
+ // 返回最小覆盖子串
+ return len == Integer.MAX_VALUE ?
+ "" : s.substring(start, start + len);
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var minWindow = function(s, t) {
+ var need = new Map();
+ var window = new Map();
+ for (var c of t) {
+ need.set(c, need.has(c) ? need.get(c) + 1 : 1);
+ }
+
+ var left = 0, right = 0;
+ var valid = 0;
+ // 记录最小覆盖子串的起始索引及长度
+ var start = 0, len = Number.MAX_SAFE_INTEGER;
+ /**
+ 
+ */
+ while (right < s.length) {
+ // c 是将移入窗口的字符
+ var c = s[right];
+ // 右移窗口
+ right++;
+ // 进行窗口内数据的一系列更新
+ if (need.has(c)) {
+ window.set(c, window.has(c) ? window.get(c) + 1 : 1);
+ if (window.get(c) === need.get(c))
+ valid++;
+ }
+
+ // 判断左侧窗口是否要收缩
+ while (valid === need.size) {
+ /**
+ 
+ */
+ // 在这里更新最小覆盖子串
+ if (right - left < len) {
+ start = left;
+ len = right - left;
+ }
+ // d 是将移出窗口的字符
+ var d = s[left];
+ // 左移窗口
+ left++;
+ // 进行窗口内数据的一系列更新
+ if (need.has(d)) {
+ if (window.get(d) === need.get(d))
+ valid--;
+ window.set(d, window.get(d) - 1);
+ }
+ }
+ /**
+ 
+ */
+ }
+ // 返回最小覆盖子串
+ return len === Number.MAX_SAFE_INTEGER ?
+ "" : s.substring(start, start + len);
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def minWindow(self, s: str, t: str) -> str:
+ from collections import defaultdict
+ need, window = defaultdict(int), defaultdict(int)
+ for c in t:
+ need[c] += 1
+
+ left, right = 0, 0
+ valid = 0
+ # 记录最小覆盖子串的起始索引及长度
+ start, length = 0, float('inf')
+ # 
+ while right < len(s):
+ # c 是将移入窗口的字符
+ c = s[right]
+ # 右移窗口
+ right += 1
+ # 进行窗口内数据的一系列更新
+ if c in need:
+ window[c] += 1
+ if window[c] == need[c]:
+ valid += 1
+
+ # 判断左侧窗口是否要收缩
+ while valid == len(need):
+ # 
+ # 在这里更新最小覆盖子串
+ if right - left < length:
+ start = left
+ length = right - left
+ # d 是将移出窗口的字符
+ d = s[left]
+ # 左移窗口
+ left += 1
+ # 进行窗口内数据的一系列更新
+ if d in need:
+ if window[d] == need[d]:
+ valid -= 1
+ window[d] -= 1
+ # 
+ # 返回最小覆盖子串
+ return '' if length == float('inf') else s[start:start+length]
+```
+
+https://leetcode.cn/problems/M1oyTv 的多语言解法👆
+
+https://leetcode.cn/problems/MPnaiL 的多语言解法👇
+
+```cpp
+// by labuladong (cpp)
+class Solution {
+ public:
+
+ // 判断 s 中是否存在 t 的排列
+ bool checkInclusion(string t, string s) {
+ unordered_map need, window;
+ for (char c : t) need[c]++;
+
+ int left = 0, right = 0;
+ int valid = 0;
+ while (right < s.size()) {
+ char c = s[right];
+ right++;
+ // 进行窗口内数据的一系列更新
+ if (need.count(c)) {
+ window[c]++;
+ if (window[c] == need[c])
+ valid++;
+ }
+
+ // 判断左侧窗口是否要收缩
+ while (right - left >= t.size()) {
+ // 在这里判断是否找到了合法的子串
+ if (valid == need.size())
+ return true;
+ char d = s[left];
+ left++;
+ // 进行窗口内数据的一系列更新
+ if (need.count(d)) {
+ if (window[d] == need[d])
+ valid--;
+ window[d]--;
+ }
+ }
+ }
+ // 未找到符合条件的子串
+ return false;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func checkInclusion(t string, s string) bool {
+ need := make(map[byte]int)
+ window := make(map[byte]int)
+ for i := range t {
+ need[t[i]]++
+ }
+
+ left, right := 0, 0
+ valid := 0
+ for right < len(s) {
+ c := s[right]
+ right++
+ // 进行窗口内数据的一系列更新
+ if _, ok := need[c]; ok {
+ window[c]++
+ if window[c] == need[c] {
+ valid++
+ }
+ }
+
+ // 判断左侧窗口是否要收缩
+ for right-left >= len(t) {
+ // 在这里判断是否找到了合法的子串
+ if valid == len(need) {
+ return true
+ }
+ d := s[left]
+ left++
+ // 进行窗口内数据的一系列更新
+ if _, ok := need[d]; ok {
+ if window[d] == need[d] {
+ valid--
+ }
+ window[d]--
+ }
+ }
+ }
+ // 未找到符合条件的子串
+ return false
+}
+```
+
+```java
+// by chatGPT (java)
+class Solution {
+ public boolean checkInclusion(String t, String s) {
+ Map need = new HashMap<>();
+ Map window = new HashMap<>();
+ for (char c : t.toCharArray()) need.put(c, need.getOrDefault(c, 0) + 1);
+
+ int left = 0, right = 0;
+ int valid = 0;
+ while (right < s.length()) {
+ char c = s.charAt(right);
+ right++;
+ // 进行窗口内数据的一系列更新
+ if (need.containsKey(c)) {
+ window.put(c, window.getOrDefault(c, 0) + 1);
+ if (window.get(c).equals(need.get(c)))
+ valid++;
+ }
+
+ // 判断左侧窗口是否要收缩
+ while (right - left >= t.length()) {
+ // 在这里判断是否找到了合法的子串
+ if (valid == need.size())
+ return true;
+ char d = s.charAt(left);
+ left++;
+ // 进行窗口内数据的一系列更新
+ if (need.containsKey(d)) {
+ if (window.get(d).equals(need.get(d)))
+ valid--;
+ window.put(d, window.get(d) - 1);
+ }
+ }
+ }
+ // 未找到符合条件的子串
+ return false;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var checkInclusion = function(t, s) {
+ const need = new Map();
+ const window = new Map();
+ for (let c of t) {
+ need.set(c, (need.get(c) || 0) + 1);
+ }
+
+ let left = 0, right = 0;
+ let valid = 0;
+ while (right < s.length) {
+ const c = s[right];
+ right++;
+ // 进行窗口内数据的一系列更新
+ if (need.has(c)) {
+ window.set(c, (window.get(c) || 0) + 1);
+ if (window.get(c) === need.get(c)) {
+ valid++;
+ }
+ }
+
+ // 判断左侧窗口是否要收缩
+ while (right - left >= t.length) {
+ // 在这里判断是否找到了合法的子串
+ if (valid === need.size) {
+ return true;
+ }
+ const d = s[left];
+ left++;
+ // 进行窗口内数据的一系列更新
+ if (need.has(d)) {
+ if (window.get(d) === need.get(d)) {
+ valid--;
+ }
+ window.set(d, (window.get(d) || 0) - 1);
+ }
+ }
+ }
+ // 未找到符合条件的子串
+ return false;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def checkInclusion(self, t: str, s: str) -> bool:
+ need, window = {}, {}
+ for c in t:
+ need[c] = need.get(c, 0) + 1
+
+ left, right = 0, 0
+ valid = 0
+ while right < len(s):
+ c = s[right]
+ right += 1
+ # 进行窗口内数据的一系列更新
+ if c in need:
+ window[c] = window.get(c, 0) + 1
+ if window[c] == need[c]:
+ valid += 1
+
+ # 判断左侧窗口是否要收缩
+ while right - left >= len(t):
+ # 在这里判断是否找到了合法的子串
+ if valid == len(need):
+ return True
+ d = s[left]
+ left += 1
+ # 进行窗口内数据的一系列更新
+ if d in need:
+ if window[d] == need[d]:
+ valid -= 1
+ window[d] -= 1
+
+ # 未找到符合条件的子串
+ return False
+```
+
+https://leetcode.cn/problems/MPnaiL 的多语言解法👆
+
+https://leetcode.cn/problems/N6YdxV 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int searchInsert(vector& nums, int target) {
+ return left_bound(nums, target);
+ }
+
+ // 搜索左侧边界的二分算法
+ int left_bound(vector& nums, int target) {
+ if (nums.size() == 0) return -1;
+ int left = 0;
+ int right = nums.size(); // 注意
+
+ while (left < right) { // 注意
+ int mid = left + (right - left) / 2;
+ if (nums[mid] == target) {
+ right = mid;
+ } else if (nums[mid] < target) {
+ left = mid + 1;
+ } else if (nums[mid] > target) {
+ right = mid; // 注意
+ }
+ }
+ return left;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func searchInsert(nums []int, target int) int {
+ return leftBound(nums, target)
+}
+
+//搜索左侧边界的二分算法
+func leftBound(nums []int, target int) int {
+ if len(nums) == 0 {
+ return -1
+ }
+ left, right := 0, len(nums)
+
+ for left < right {
+ mid := left + (right - left)/2
+ if nums[mid] == target {
+ right = mid
+ } else if nums[mid] < target {
+ left = mid + 1
+ } else if nums[mid] > target {
+ right = mid
+ }
+ }
+ return left
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int searchInsert(int[] nums, int target) {
+ return left_bound(nums, target);
+ }
+
+ // 搜索左侧边界的二分算法
+ int left_bound(int[] nums, int target) {
+ if (nums.length == 0) return -1;
+ int left = 0;
+ int right = nums.length; // 注意
+
+ while (left < right) { // 注意
+ int mid = left + (right - left) / 2;
+ if (nums[mid] == target) {
+ right = mid;
+ } else if (nums[mid] < target) {
+ left = mid + 1;
+ } else if (nums[mid] > target) {
+ right = mid; // 注意
+ }
+ }
+ return left;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var Solution = function() {};
+
+Solution.prototype.searchInsert = function(nums, target) {
+ return this.left_bound(nums, target);
+};
+
+// 搜索左侧边界的二分算法
+Solution.prototype.left_bound = function(nums, target) {
+ if (nums.length == 0) return -1;
+ var left = 0;
+ var right = nums.length; // 注意
+
+ while (left < right) { // 注意
+ var mid = left + Math.floor((right - left) / 2);
+ if (nums[mid] == target) {
+ right = mid;
+ } else if (nums[mid] < target) {
+ left = mid + 1;
+ } else if (nums[mid] > target) {
+ right = mid; // 注意
+ }
+ }
+ return left;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def searchInsert(self, nums: List[int], target: int) -> int:
+ return self.left_bound(nums, target)
+
+ # 搜索左侧边界的二分算法
+ def left_bound(self, nums: List[int], target: int) -> int:
+ if len(nums) == 0:
+ return -1
+ left, right = 0, len(nums) # 注意
+
+ while left < right: # 注意
+ mid = left + (right - left) // 2
+ if nums[mid] == target:
+ right = mid
+ elif nums[mid] < target:
+ left = mid + 1
+ elif nums[mid] > target:
+ right = mid # 注意
+
+ return left
+```
+
+https://leetcode.cn/problems/N6YdxV 的多语言解法👆
+
+https://leetcode.cn/problems/NUPfPr 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ bool canPartition(vector& nums) {
+ int sum = 0;
+ for (int num : nums) sum += num;
+ // 和为奇数时,不可能划分成两个和相等的集合
+ if (sum % 2 != 0) return false;
+ int n = nums.size();
+ sum = sum / 2;
+ vector> dp(n + 1, vector(sum + 1, false));
+ // base case
+ for (int i = 0; i <= n; i++)
+ dp[i][0] = true;
+
+ for (int i = 1; i <= n; i++) {
+ for (int j = 1; j <= sum; j++) {
+ if (j - nums[i - 1] < 0) {
+ // 背包容量不足,不能装入第 i 个物品
+ dp[i][j] = dp[i - 1][j];
+ } else {
+ // 装入或不装入背包
+ dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]];
+ }
+ }
+ }
+ return dp[n][sum];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func canPartition(nums []int) bool {
+ sum := 0
+ for _, num := range nums {
+ sum += num
+ }
+ // 和为奇数时,不可能划分成两个和相等的集合
+ if sum%2 != 0 {
+ return false
+ }
+ n := len(nums)
+ sum = sum / 2
+ dp := make([][]bool, n+1)
+ for i := 0; i <= n; i++ {
+ dp[i] = make([]bool, sum+1)
+ // base case
+ dp[i][0] = true
+ }
+
+ for i := 1; i <= n; i++ {
+ for j := 1; j <= sum; j++ {
+ if j-nums[i-1] < 0 {
+ // 背包容量不足,不能装入第 i 个物品
+ dp[i][j] = dp[i-1][j]
+ } else {
+ // 装入或不装入背包
+ dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i-1]]
+ }
+ }
+ }
+ return dp[n][sum]
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public boolean canPartition(int[] nums) {
+ int sum = 0;
+ for (int num : nums) sum += num;
+ // 和为奇数时,不可能划分成两个和相等的集合
+ if (sum % 2 != 0) return false;
+ int n = nums.length;
+ sum = sum / 2;
+ boolean[][] dp = new boolean[n + 1][sum + 1];
+ // base case
+ for (int i = 0; i <= n; i++)
+ dp[i][0] = true;
+
+ for (int i = 1; i <= n; i++) {
+ for (int j = 1; j <= sum; j++) {
+ if (j - nums[i - 1] < 0) {
+ // 背包容量不足,不能装入第 i 个物品
+ dp[i][j] = dp[i - 1][j];
+ } else {
+ // 装入或不装入背包
+ dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]];
+ }
+ }
+ }
+ return dp[n][sum];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var canPartition = function(nums) {
+ let sum = 0;
+ for (let num of nums) {
+ sum += num;
+ }
+ // 和为奇数时,不可能划分成两个和相等的集合
+ if (sum % 2 !== 0) {
+ return false;
+ }
+ let n = nums.length;
+ sum = sum / 2;
+ let dp = new Array(n + 1).fill(false).map(() => new Array(sum + 1).fill(false));
+ // base case
+ for (let i = 0; i <= n; i++) {
+ dp[i][0] = true;
+ }
+
+ for (let i = 1; i <= n; i++) {
+ for (let j = 1; j <= sum; j++) {
+ if (j - nums[i - 1] < 0) {
+ // 背包容量不足,不能装入第 i 个物品
+ dp[i][j] = dp[i - 1][j];
+ } else {
+ // 装入或不装入背包
+ dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]];
+ }
+ }
+ }
+ return dp[n][sum];
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def canPartition(self, nums: List[int]) -> bool:
+ sum = 0
+ for num in nums:
+ sum += num
+ # 和为奇数时,不可能划分成两个和相等的集合
+ if sum % 2 != 0:
+ return False
+ n = len(nums)
+ sum = sum // 2
+ dp = [[False] * (sum + 1) for _ in range(n + 1)]
+ # base case
+ for i in range(n + 1):
+ dp[i][0] = True
+
+ for i in range(1, n + 1):
+ for j in range(1, sum + 1):
+ if j - nums[i - 1] < 0:
+ # 背包容量不足,不能装入第 i 个物品
+ dp[i][j] = dp[i - 1][j]
+ else:
+ # 装入或不装入背包
+ dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i - 1]]
+ return dp[n][sum]
+```
+
+https://leetcode.cn/problems/NUPfPr 的多语言解法👆
+
+https://leetcode.cn/problems/O4NDxx 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class NumMatrix {
+private:
+ // preSum[i][j] 记录矩阵 [0, 0, i, j] 的元素和
+ vector> preSum;
+
+public:
+ NumMatrix(vector>& matrix) {
+ int m = matrix.size(), n = matrix[0].size();
+ if (m == 0 || n == 0) return;
+ // 构造前缀和矩阵
+ preSum = vector>(m + 1, vector(n + 1, 0));
+ for (int i = 1; i <= m; i++) {
+ for (int j = 1; j <= n; j++) {
+ // 计算每个矩阵 [0, 0, i, j] 的元素和
+ preSum[i][j] = preSum[i-1][j] + preSum[i][j-1] + matrix[i - 1][j - 1] - preSum[i-1][j-1];
+ }
+ }
+ }
+
+ // 计算子矩阵 [x1, y1, x2, y2] 的元素和
+ int sumRegion(int x1, int y1, int x2, int y2) {
+ // 目标矩阵之和由四个相邻矩阵运算获得
+ return preSum[x2+1][y2+1] - preSum[x1][y2+1] - preSum[x2+1][y1] + preSum[x1][y1];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+type NumMatrix struct {
+ // preSum[i][j] 记录矩阵 [0, 0, i, j] 的元素和
+ preSum [][]int
+}
+
+func Constructor(matrix [][]int) NumMatrix {
+ m, n := len(matrix), len(matrix[0])
+ if m == 0 || n == 0 {
+ return NumMatrix{}
+ }
+ // 构造前缀和矩阵
+ preSum := make([][]int, m+1)
+ for i := range preSum {
+ preSum[i] = make([]int, n+1)
+ }
+ for i := 1; i <= m; i++ {
+ for j := 1; j <= n; j++ {
+ // 计算每个矩阵 [0, 0, i, j] 的元素和
+ preSum[i][j] = preSum[i-1][j] + preSum[i][j-1] + matrix[i-1][j-1] - preSum[i-1][j-1]
+ }
+ }
+ return NumMatrix{preSum}
+}
+
+// 计算子矩阵 [x1, y1, x2, y2] 的元素和
+func (this *NumMatrix) SumRegion(x1 int, y1 int, x2 int, y2 int) int {
+ // 目标矩阵之和由四个相邻矩阵运算获得
+ return this.preSum[x2+1][y2+1] - this.preSum[x1][y2+1] - this.preSum[x2+1][y1] + this.preSum[x1][y1]
+}
+```
+
+```java
+// by labuladong (java)
+class NumMatrix {
+ // preSum[i][j] 记录矩阵 [0, 0, i-1, j-1] 的元素和
+ private int[][] preSum;
+
+ public NumMatrix(int[][] matrix) {
+ int m = matrix.length, n = matrix[0].length;
+ if (m == 0 || n == 0) return;
+ // 构造前缀和矩阵
+ preSum = new int[m + 1][n + 1];
+ for (int i = 1; i <= m; i++) {
+ for (int j = 1; j <= n; j++) {
+ // 计算每个矩阵 [0, 0, i, j] 的元素和
+ preSum[i][j] = preSum[i-1][j] + preSum[i][j-1] + matrix[i - 1][j - 1] - preSum[i-1][j-1];
+ }
+ }
+ }
+
+ // 计算子矩阵 [x1, y1, x2, y2] 的元素和
+ public int sumRegion(int x1, int y1, int x2, int y2) {
+ // 目标矩阵之和由四个相邻矩阵运算获得
+ return preSum[x2+1][y2+1] - preSum[x1][y2+1] - preSum[x2+1][y1] + preSum[x1][y1];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var NumMatrix = function(matrix) {
+ // preSum[i][j] 记录矩阵 [0, 0, i, j] 的元素和
+ var preSum;
+
+ var m = matrix.length, n = matrix[0].length;
+ if (m == 0 || n == 0) return;
+ // 构造前缀和矩阵
+ preSum = new Array(m + 1);
+ for (var i = 0; i <= m; i++) {
+ preSum[i] = new Array(n + 1).fill(0);
+ }
+ for (var i = 1; i <= m; i++) {
+ for (var j = 1; j <= n; j++) {
+ // 计算每个矩阵 [0, 0, i, j] 的元素和
+ preSum[i][j] = preSum[i-1][j] + preSum[i][j-1] + matrix[i - 1][j - 1] - preSum[i-1][j-1];
+ }
+ }
+
+ // 计算子矩阵 [x1, y1, x2, y2] 的元素和
+ this.sumRegion = function(x1, y1, x2, y2) {
+ // 目标矩阵之和由四个相邻矩阵运算获得
+ return preSum[x2+1][y2+1] - preSum[x1][y2+1] - preSum[x2+1][y1] + preSum[x1][y1];
+ }
+};
+```
+
+```python
+# by chatGPT (python)
+class NumMatrix:
+ def __init__(self, matrix: List[List[int]]):
+ m, n = len(matrix), len(matrix[0])
+ if m == 0 or n == 0:
+ return
+ # 构造前缀和矩阵
+ self.preSum = [[0] * (n + 1) for _ in range(m + 1)]
+ for i in range(1, m + 1):
+ for j in range(1, n + 1):
+ # 计算每个矩阵 [0, 0, i, j] 的元素和
+ self.preSum[i][j] = self.preSum[i - 1][j] + self.preSum[i][j - 1] + matrix[i - 1][j - 1] - self.preSum[i - 1][j - 1]
+
+ # 计算子矩阵 [x1, y1, x2, y2] 的元素和
+ def sumRegion(self, x1: int, y1: int, x2: int, y2: int) -> int:
+ # 目标矩阵之和由四个相邻矩阵运算获得
+ return self.preSum[x2 + 1][y2 + 1] - self.preSum[x1][y2 + 1] - self.preSum[x2 + 1][y1] + self.preSum[x1][y1]
+```
+
+https://leetcode.cn/problems/O4NDxx 的多语言解法👆
+
+https://leetcode.cn/problems/OrIXps 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class LRUCache {
+ int cap;
+ unordered_map cache;
+ list keys;
+
+public:
+ LRUCache(int capacity) {
+ this->cap = capacity;
+ }
+
+ int get(int key) {
+ auto it = cache.find(key);
+ if (it == cache.end()) {
+ return -1;
+ }
+ // 将 key 变为最近使用
+ makeRecently(key);
+ return it->second;
+ }
+
+ void put(int key, int val) {
+ auto it = cache.find(key);
+ if (it != cache.end()) {
+ // 修改 key 的值
+ it->second = val;
+ // 将 key 变为最近使用
+ makeRecently(key);
+ return;
+ }
+
+ if (cache.size() >= this->cap) {
+ // 链表头部就是最久未使用的 key
+ int oldestKey = keys.front();
+ keys.pop_front();
+ cache.erase(oldestKey);
+ }
+ // 将新的 key 添加链表尾部
+ keys.push_back(key);
+ cache[key] = val;
+ }
+
+private:
+ void makeRecently(int key) {
+ int val = cache[key];
+ // 删除 key,重新插入到队尾
+ keys.remove(key);
+ keys.push_back(key);
+ cache[key] = val;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+type LRUCache struct {
+ cap int
+ cache map[int]int
+}
+
+// Constructor 创建一个 LRU Cache 实例
+func Constructor(capacity int) LRUCache {
+ return LRUCache{
+ cap: capacity,
+ cache: make(map[int]int),
+ }
+}
+
+// Get 获取一个 key 的值
+func (this *LRUCache) Get(key int) int {
+ if val, ok := this.cache[key]; ok {
+ this.makeRecently(key)
+ return val
+ }
+ return -1
+}
+
+// Put 插入一个 key/value
+func (this *LRUCache) Put(key int, value int) {
+ if _, ok := this.cache[key]; ok {
+ this.cache[key] = value
+ this.makeRecently(key)
+ return
+ }
+ if len(this.cache) >= this.cap {
+ this.removeLeastRecently()
+ }
+ this.cache[key] = value
+}
+
+// makeRecently 将一个元素标记为最近使用的
+func (this *LRUCache) makeRecently(key int) {
+ val := this.cache[key]
+ delete(this.cache, key)
+ this.cache[key] = val
+}
+
+// removeLeastRecently 移除最近未使用的元素
+func (this *LRUCache) removeLeastRecently() {
+ for k := range this.cache {
+ delete(this.cache, k)
+ break
+ }
+}
+```
+
+```java
+// by labuladong (java)
+class LRUCache {
+ int cap;
+ LinkedHashMap cache = new LinkedHashMap<>();
+ public LRUCache(int capacity) {
+ this.cap = capacity;
+ }
+
+ public int get(int key) {
+ if (!cache.containsKey(key)) {
+ return -1;
+ }
+ // 将 key 变为最近使用
+ makeRecently(key);
+ return cache.get(key);
+ }
+
+ public void put(int key, int val) {
+ if (cache.containsKey(key)) {
+ // 修改 key 的值
+ cache.put(key, val);
+ // 将 key 变为最近使用
+ makeRecently(key);
+ return;
+ }
+
+ if (cache.size() >= this.cap) {
+ // 链表头部就是最久未使用的 key
+ int oldestKey = cache.keySet().iterator().next();
+ cache.remove(oldestKey);
+ }
+ // 将新的 key 添加链表尾部
+ cache.put(key, val);
+ }
+
+ private void makeRecently(int key) {
+ int val = cache.get(key);
+ // 删除 key,重新插入到队尾
+ cache.remove(key);
+ cache.put(key, val);
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var LRUCache = function(capacity) {
+ this.cap = capacity;
+ this.cache = new Map();
+};
+
+LRUCache.prototype.get = function(key) {
+ if (!this.cache.has(key)) {
+ return -1;
+ }
+ // 将 key 变为最近使用
+ this.makeRecently(key);
+ return this.cache.get(key);
+};
+
+LRUCache.prototype.put = function(key, val) {
+ if (this.cache.has(key)) {
+ // 修改 key 的值
+ this.cache.set(key, val);
+ // 将 key 变为最近使用
+ this.makeRecently(key);
+ return;
+ }
+
+ if (this.cache.size >= this.cap) {
+ // 链表头部就是最久未使用的 key
+ const oldestKey = this.cache.keys().next().value;
+ this.cache.delete(oldestKey);
+ }
+ // 将新的 key 添加链表尾部
+ this.cache.set(key, val);
+};
+
+LRUCache.prototype.makeRecently = function(key) {
+ const val = this.cache.get(key);
+ // 删除 key,重新插入到队尾
+ this.cache.delete(key);
+ this.cache.set(key, val);
+};
+```
+
+```python
+# by chatGPT (python)
+class LRUCache:
+ def __init__(self, capacity: int):
+ self.cap = capacity
+ self.cache = {}
+
+ def get(self, key: int) -> int:
+ if key not in self.cache:
+ return -1
+ # 将 key 变为最近使用
+ self.makeRecently(key)
+ return self.cache[key]
+
+ def put(self, key: int, val: int) -> None:
+ if key in self.cache:
+ # 修改 key 的值
+ self.cache[key] = val
+ # 将 key 变为最近使用
+ self.makeRecently(key)
+ return
+
+ if len(self.cache) >= self.cap:
+ # 链表头部就是最久未使用的 key
+ oldest_key = next(iter(self.cache))
+ self.cache.pop(oldest_key)
+
+ # 将新的 key 添加链表尾部
+ self.cache[key] = val
+
+ def makeRecently(self, key: int) -> None:
+ val = self.cache[key]
+ # 删除 key,重新插入到队尾
+ del self.cache[key]
+ self.cache[key] = val
+```
+
+https://leetcode.cn/problems/OrIXps 的多语言解法👆
+
+https://leetcode.cn/problems/PzWKhm 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int rob(vector& nums) {
+ int n = nums.size();
+ if (n == 1) return nums[0];
+
+ vector memo1(n, -1);
+ vector memo2(n, -1);
+ // 两次调用使用两个不同的备忘录
+ return max(
+ dp(nums, 0, n - 2, memo1),
+ dp(nums, 1, n - 1, memo2)
+ );
+ }
+
+ // 定义:计算闭区间 [start,end] 的最优结果
+ int dp(vector& nums, int start, int end, vector& memo) {
+ if (start > end) {
+ return 0;
+ }
+
+ if (memo[start] != -1) {
+ return memo[start];
+ }
+ // 状态转移方程
+ int res = max(
+ dp(nums, start + 2, end, memo) + nums[start],
+ dp(nums, start + 1, end, memo)
+ );
+
+ memo[start] = res;
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+import "fmt"
+
+func rob(nums []int) int {
+ n := len(nums)
+ if n == 1 {
+ return nums[0]
+ }
+
+ memo1 := make([]int, n)
+ memo2 := make([]int, n)
+ for i := range memo1 {
+ memo1[i] = -1
+ memo2[i] = -1
+ }
+ // 两次调用使用两个不同的备忘录
+ return max(dp(nums, 0, n - 2, memo1), dp(nums, 1, n - 1, memo2))
+}
+
+// 定义:计算闭区间 [start,end] 的最优结果
+func dp(nums []int, start, end int, memo []int) int {
+ if start > end {
+ return 0
+ }
+
+ if memo[start] != -1 {
+ return memo[start]
+ }
+ // 状态转移方程
+ res := max(dp(nums, start + 2, end, memo) + nums[start], dp(nums, start + 1, end, memo))
+
+ memo[start] = res
+ return res
+}
+
+func max(x, y int) int {
+ if x > y {
+ return x
+ }
+ return y
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+
+ public int rob(int[] nums) {
+ int n = nums.length;
+ if (n == 1) return nums[0];
+
+ int[] memo1 = new int[n];
+ int[] memo2 = new int[n];
+ Arrays.fill(memo1, -1);
+ Arrays.fill(memo2, -1);
+ // 两次调用使用两个不同的备忘录
+ return Math.max(
+ dp(nums, 0, n - 2, memo1),
+ dp(nums, 1, n - 1, memo2)
+ );
+ }
+
+ // 定义:计算闭区间 [start,end] 的最优结果
+ int dp(int[] nums, int start, int end, int[] memo) {
+ if (start > end) {
+ return 0;
+ }
+
+ if (memo[start] != -1) {
+ return memo[start];
+ }
+ // 状态转移方程
+ int res = Math.max(
+ dp(nums, start + 2, end, memo) + nums[start],
+ dp(nums, start + 1, end, memo)
+ );
+
+ memo[start] = res;
+ return res;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var rob = function(nums) {
+ const n = nums.length;
+ if (n === 1) return nums[0];
+
+ const memo1 = new Array(n).fill(-1);
+ const memo2 = new Array(n).fill(-1);
+ // 两次调用使用两个不同的备忘录
+ return Math.max(
+ dp(nums, 0, n - 2, memo1),
+ dp(nums, 1, n - 1, memo2)
+ );
+};
+
+// 定义:计算闭区间 [start,end] 的最优结果
+function dp(nums, start, end, memo) {
+ if (start > end) {
+ return 0;
+ }
+
+ if (memo[start] !== -1) {
+ return memo[start];
+ }
+ // 状态转移方程
+ const res = Math.max(
+ dp(nums, start + 2, end, memo) + nums[start],
+ dp(nums, start + 1, end, memo)
+ );
+
+ memo[start] = res;
+ return res;
+}
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def rob(self, nums: List[int]) -> int:
+ n = len(nums)
+ if n == 1:
+ return nums[0]
+ memo1 = [-1]*n
+ memo2 = [-1]*n
+ # 两次调用使用两个不同的备忘录
+ return max(
+ self.dp(nums, 0, n-2, memo1),
+ self.dp(nums, 1, n-1, memo2)
+ )
+
+ # 定义:计算闭区间 [start,end] 的最优结果
+ def dp(self, nums: List[int], start: int, end: int, memo: List[int]) -> int:
+ if start > end:
+ return 0
+ if memo[start] != -1:
+ return memo[start]
+ # 状态转移方程
+ res = max(
+ self.dp(nums, start+2, end, memo) + nums[start],
+ self.dp(nums, start+1, end, memo)
+ )
+ memo[start] = res
+ return res
+```
+
+https://leetcode.cn/problems/PzWKhm 的多语言解法👆
+
+https://leetcode.cn/problems/QA2IGt 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ vector findOrder(int numCourses, vector>& prerequisites) {
+ // 建图,和环检测算法相同
+ vector> graph(numCourses);
+ for (auto& edge : prerequisites) {
+ int from = edge[1], to = edge[0];
+ graph[from].push_back(to);
+ }
+ // 计算入度,和环检测算法相同
+ vector indegree(numCourses);
+ for (auto& edge : prerequisites) {
+ int from = edge[1], to = edge[0];
+ indegree[to]++;
+ }
+
+ // 根据入度初始化队列中的节点,和环检测算法相同
+ queue q;
+ for (int i = 0; i < numCourses; i++) {
+ if (indegree[i] == 0) {
+ q.push(i);
+ }
+ }
+
+ // 记录拓扑排序结果
+ vector res(numCourses);
+ // 记录遍历节点的顺序(索引)
+ int count = 0;
+ // 开始执行 BFS 算法
+ while (!q.empty()) {
+ int cur = q.front();
+ q.pop();
+ // 弹出节点的顺序即为拓扑排序结果
+ res[count] = cur;
+ count++;
+ for (int next : graph[cur]) {
+ indegree[next]--;
+ if (indegree[next] == 0) {
+ q.push(next);
+ }
+ }
+ }
+
+ if (count != numCourses) {
+ // 存在环,拓扑排序不存在
+ return {};
+ }
+
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+// 主函数
+func findOrder(numCourses int, prerequisites [][]int) []int {
+ // 建图,和环检测算法相同
+ graph := buildGraph(numCourses, prerequisites)
+ // 计算入度,和环检测算法相同
+ indegree := make([]int, numCourses)
+ for _, edge := range prerequisites {
+ _, to := edge[1], edge[0]
+ indegree[to]++
+ }
+
+ // 根据入度初始化队列中的节点,和环检测算法相同
+ q := make([]int, 0)
+ for i := 0; i < numCourses; i++ {
+ if indegree[i] == 0 {
+ q = append(q, i)
+ }
+ }
+
+ // 记录拓扑排序结果
+ res := make([]int, numCourses)
+ // 记录遍历节点的顺序(索引)
+ count := 0
+ // 开始执行 BFS 算法
+ for len(q) > 0 {
+ cur := q[0]
+ q = q[1:]
+ // 弹出节点的顺序即为拓扑排序结果
+ res[count] = cur
+ count++
+ for _, next := range graph[cur] {
+ indegree[next]--
+ if indegree[next] == 0 {
+ q = append(q, next)
+ }
+ }
+ }
+
+ if count != numCourses {
+ // 存在环,拓扑排序不存在
+ return []int{}
+ }
+
+ return res
+}
+
+// 建图函数
+func buildGraph(numCourses int, prerequisites [][]int) [] []int {
+ // 图中共有 numCourses 个节点
+ graph := make([][]int, numCourses)
+ for i := 0; i < numCourses; i++ {
+ graph[i] = make([]int, 0)
+ }
+ for _, edge := range prerequisites {
+ from, to := edge[1], edge[0]
+ // 修完课程 from 才能修课程 to
+ // 在图中添加一条从 from 指向 to 的有向边
+ graph[from] = append(graph[from], to)
+ }
+ return graph
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ // 主函数
+ public int[] findOrder(int numCourses, int[][] prerequisites) {
+ // 建图,和环检测算法相同
+ List[] graph = buildGraph(numCourses, prerequisites);
+ // 计算入度,和环检测算法相同
+ int[] indegree = new int[numCourses];
+ for (int[] edge : prerequisites) {
+ int from = edge[1], to = edge[0];
+ indegree[to]++;
+ }
+
+ // 根据入度初始化队列中的节点,和环检测算法相同
+ Queue q = new LinkedList<>();
+ for (int i = 0; i < numCourses; i++) {
+ if (indegree[i] == 0) {
+ q.offer(i);
+ /**
+ 
+ */
+ }
+ }
+
+ // 记录拓扑排序结果
+ int[] res = new int[numCourses];
+ // 记录遍历节点的顺序(索引)
+ int count = 0;
+ // 开始执行 BFS 算法
+ while (!q.isEmpty()) {
+ int cur = q.poll();
+ // 弹出节点的顺序即为拓扑排序结果
+ res[count] = cur;
+ count++;
+ for (int next : graph[cur]) {
+ /**
+ 
+ */
+ indegree[next]--;
+ if (indegree[next] == 0) {
+ q.offer(next);
+ }
+ }
+ }
+
+ if (count != numCourses) {
+ // 存在环,拓扑排序不存在
+ return new int[]{};
+ }
+
+ return res;
+ }
+
+ // 建图函数
+ List[] buildGraph(int numCourses, int[][] prerequisites) {
+ // 图中共有 numCourses 个节点
+ List[] graph = new LinkedList[numCourses];
+ for (int i = 0; i < numCourses; i++) {
+ graph[i] = new LinkedList<>();
+ }
+ for (int[] edge : prerequisites) {
+ int from = edge[1], to = edge[0];
+ // 修完课程 from 才能修课程 to
+ // 在图中添加一条从 from 指向 to 的有向边
+ graph[from].add(to);
+ }
+ return graph;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var findOrder = function(numCourses, prerequisites) {
+ // 建图,和环检测算法相同
+ const graph = buildGraph(numCourses, prerequisites);
+ // 计算入度,和环检测算法相同
+ const indegree = new Array(numCourses).fill(0);
+ for (const [from, to] of prerequisites) {
+ indegree[to]++;
+ }
+
+ // 根据入度初始化队列中的节点,和环检测算法相同
+ const q = [];
+ for (let i = 0; i < numCourses; i++) {
+ if (indegree[i] === 0) {
+ q.push(i);
+ /**
+ 
+ */
+ }
+ }
+
+ // 记录拓扑排序结果
+ const res = new Array(numCourses);
+ // 记录遍历节点的顺序(索引)
+ let count = 0;
+ // 开始执行 BFS 算法
+ while (q.length > 0) {
+ const cur = q.shift();
+ // 弹出节点的顺序即为拓扑排序结果
+ res[count] = cur;
+ count++;
+ for (const next of graph[cur]) {
+ /**
+ 
+ */
+ indegree[next]--;
+ if (indegree[next] === 0) {
+ q.push(next);
+ }
+ }
+ }
+
+ if (count !== numCourses) {
+ // 存在环,拓扑排序不存在
+ return [];
+ }
+
+ return res;
+};
+
+// 建图函数
+function buildGraph(numCourses, prerequisites) {
+ // 图中共有 numCourses 个节点
+ const graph = new Array(numCourses).map(() => []);
+ for (const [from, to] of prerequisites) {
+ // 修完课程 from 才能修课程 to
+ // 在图中添加一条从 from 指向 to 的有向边
+ graph[from].push(to);
+ }
+ return graph;
+}
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
+ # 建图,和环检测算法相同
+ graph = self.buildGraph(numCourses, prerequisites)
+ # 计算入度,和环检测算法相同
+ indegree = [0] * numCourses
+ for edge in prerequisites:
+ from_, to = edge[1], edge[0]
+ indegree[to] += 1
+
+ # 根据入度初始化队列中的节点,和环检测算法相同
+ q = collections.deque()
+ for i in range(numCourses):
+ if indegree[i] == 0:
+ q.append(i)
+
+ # 记录拓扑排序结果
+ res = [0] * numCourses
+ # 记录遍历节点的顺序(索引)
+ count = 0
+ # 开始执行 BFS 算法
+ while q:
+ cur = q.popleft()
+ # 弹出节点的顺序即为拓扑排序结果
+ res[count] = cur
+ count += 1
+ for next_ in graph[cur]:
+ indegree[next_] -= 1
+ if indegree[next_] == 0:
+ q.append(next_)
+
+ if count != numCourses:
+ # 存在环,拓扑排序不存在
+ return []
+
+ return res
+
+ # 建图函数
+ def buildGraph(self, numCourses: int, prerequisites: List[List[int]]) -> List[List[int]]:
+ # 图中共有 numCourses 个节点
+ graph = [[] for _ in range(numCourses)]
+ for edge in prerequisites:
+ from_, to = edge[1], edge[0]
+ # 修完课程 from 才能修课程 to
+ # 在图中添加一条从 from 指向 to 的有向边
+ graph[from_].append(to)
+ return graph
+```
+
+https://leetcode.cn/problems/QA2IGt 的多语言解法👆
+
+https://leetcode.cn/problems/SLwz0R 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ // 主函数
+ ListNode* removeNthFromEnd(ListNode* head, int n) {
+ // 虚拟头结点
+ ListNode* dummy = new ListNode(-1);
+ dummy->next = head;
+ // 删除倒数第 n 个,要先找倒数第 n + 1 个节点
+ ListNode* x = findFromEnd(dummy, n + 1);
+ // 删掉倒数第 n 个节点
+ x->next = x->next->next;
+ return dummy->next;
+ }
+
+ // 返回链表的倒数第 k 个节点
+ ListNode* findFromEnd(ListNode* head, int k) {
+ ListNode* p1 = head;
+ // p1 先走 k 步
+ for (int i = 0; i < k; i++) {
+ p1 = p1->next;
+ }
+ ListNode* p2 = head;
+ // p1 和 p2 同时走 n - k 步
+ while (p1 != nullptr) {
+ p2 = p2->next;
+ p1 = p1->next;
+ }
+ // p2 现在指向第 n - k 个节点
+ return p2;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+// removeNthFromEnd 主函数
+func removeNthFromEnd(head *ListNode, n int) *ListNode {
+ // 虚拟头结点
+ dummy := &ListNode{-1, head}
+ // 删除倒数第 n 个,要先找倒数第 n + 1 个节点
+ x := findFromEnd(dummy, n + 1)
+ // 删掉倒数第 n 个节点
+ x.Next = x.Next.Next
+ return dummy.Next
+}
+
+// findFromEnd 返回链表的倒数第 k 个节点
+func findFromEnd(head *ListNode, k int) *ListNode {
+ p1 := head
+ // p1 先走 k 步
+ for i := 0; i < k; i++ {
+ p1 = p1.Next
+ }
+ p2 := head
+ // p1 和 p2 同时走 n - k 步
+ for p1 != nil {
+ p2 = p2.Next
+ p1 = p1.Next
+ }
+ // p2 现在指向第 n - k 个节点
+ return p2
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ // 主函数
+ public ListNode removeNthFromEnd(ListNode head, int n) {
+ // 虚拟头结点
+ ListNode dummy = new ListNode(-1);
+ dummy.next = head;
+ // 删除倒数第 n 个,要先找倒数第 n + 1 个节点
+ ListNode x = findFromEnd(dummy, n + 1);
+ // 删掉倒数第 n 个节点
+ x.next = x.next.next;
+ return dummy.next;
+ }
+
+ // 返回链表的倒数第 k 个节点
+ ListNode findFromEnd(ListNode head, int k) {
+ ListNode p1 = head;
+ // p1 先走 k 步
+ for (int i = 0; i < k; i++) {
+ p1 = p1.next;
+ }
+ ListNode p2 = head;
+ // p1 和 p2 同时走 n - k 步
+ while (p1 != null) {
+ p2 = p2.next;
+ p1 = p1.next;
+ }
+ // p2 现在指向第 n - k 个节点
+ return p2;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var removeNthFromEnd = function(head, n) {
+ // 虚拟头结点
+ var dummy = new ListNode(-1);
+ dummy.next = head;
+ // 删除倒数第 n 个,要先找倒数第 n + 1 个节点
+ var x = findFromEnd(dummy, n + 1);
+ // 删掉倒数第 n 个节点
+ x.next = x.next.next;
+ return dummy.next;
+};
+
+// 返回链表的倒数第 k 个节点
+var findFromEnd = function(head, k) {
+ var p1 = head;
+ // p1 先走 k 步
+ for (var i = 0; i < k; i++) {
+ p1 = p1.next;
+ }
+ var p2 = head;
+ // p1 和 p2 同时走 n - k 步
+ while (p1 != null) {
+ p2 = p2.next;
+ p1 = p1.next;
+ }
+ // p2 现在指向第 n - k 个节点
+ return p2;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
+ # 虚拟头结点
+ dummy = ListNode(-1)
+ dummy.next = head
+ # 删除倒数第 n 个,要先找倒数第 n + 1 个节点
+ x = self.findFromEnd(dummy, n + 1)
+ # 删掉倒数第 n 个节点
+ x.next = x.next.next
+ return dummy.next
+
+ # 返回链表的倒数第 k 个节点
+ def findFromEnd(self, head: ListNode, k: int) -> ListNode:
+ p1 = head
+ # p1 先走 k 步
+ for i in range(k):
+ p1 = p1.next
+ p2 = head
+ # p1 和 p2 同时走 n - k 步
+ while p1:
+ p2 = p2.next
+ p1 = p1.next
+ # p2 现在指向第 n - k 个节点
+ return p2
+```
+
+https://leetcode.cn/problems/SLwz0R 的多语言解法👆
+
+https://leetcode.cn/problems/SsGoHC 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ vector> merge(vector>& intervals) {
+ vector> res;
+ // 按区间的 start 升序排列
+ sort(intervals.begin(), intervals.end(), [](vector& a, vector& b) {
+ return a[0] < b[0];
+ });
+
+ res.push_back(intervals[0]);
+ for (int i = 1; i < intervals.size(); i++) {
+ vector& curr = intervals[i];
+ // res 中最后一个元素的引用
+ vector& last = res.back();
+ if (curr[0] <= last[1]) {
+ last[1] = max(last[1], curr[1]);
+ } else {
+ // 处理下一个待合并区间
+ res.push_back(curr);
+ }
+ }
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func merge(intervals [][]int) [][]int {
+ res := [][]int{}
+ // 按区间的 start 升序排列
+ sort.Slice(intervals, func(i, j int) bool {
+ return intervals[i][0] < intervals[j][0]
+ })
+
+ res = append(res, intervals[0])
+ for i := 1; i < len(intervals); i++ {
+ curr := intervals[i]
+ // res 中最后一个元素的引用
+ last := res[len(res)-1]
+ if curr[0] <= last[1] {
+ last[1] = max(last[1], curr[1])
+ } else {
+ // 处理下一个待合并区间
+ res = append(res, curr)
+ }
+ }
+ return res
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int[][] merge(int[][] intervals) {
+ LinkedList res = new LinkedList<>();
+ // 按区间的 start 升序排列
+ Arrays.sort(intervals, (a, b) -> {
+ return a[0] - b[0];
+ });
+
+ res.add(intervals[0]);
+ for (int i = 1; i < intervals.length; i++) {
+ int[] curr = intervals[i];
+ // res 中最后一个元素的引用
+ int[] last = res.getLast();
+ if (curr[0] <= last[1]) {
+ last[1] = Math.max(last[1], curr[1]);
+ } else {
+ // 处理下一个待合并区间
+ res.add(curr);
+ }
+ }
+ return res.toArray(new int[0][0]);
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var merge = function(intervals) {
+ let res = [];
+ // 按区间的 start 升序排列
+ intervals.sort((a, b) => {
+ return a[0] - b[0];
+ });
+
+ res.push(intervals[0]);
+ for (let i = 1; i < intervals.length; i++) {
+ let curr = intervals[i];
+ // res 中最后一个元素的引用
+ let last = res[res.length - 1];
+ if (curr[0] <= last[1]) {
+ last[1] = Math.max(last[1], curr[1]);
+ } else {
+ // 处理下一个待合并区间
+ res.push(curr);
+ }
+ }
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def merge(self, intervals: List[List[int]]) -> List[List[int]]:
+ res = []
+ # 按区间的 start 升序排列
+ intervals.sort(key=lambda x: x[0])
+ res.append(intervals[0])
+ for curr in intervals[1:]:
+ # res 中最后一个元素的引用
+ last = res[-1]
+ if curr[0] <= last[1]:
+ last[1] = max(last[1], curr[1])
+ else:
+ # 处理下一个待合并区间
+ res.append(curr)
+ return res
+```
+
+https://leetcode.cn/problems/SsGoHC 的多语言解法👆
+
+https://leetcode.cn/problems/TVdhkn 的多语言解法👇
+
+```cpp
+// by labuladong (cpp)
+class Solution {
+ public:
+ vector> res;
+ vector> subsets(vector& nums) {
+ // 记录走过的路径
+ vector track;
+ backtrack(nums, 0, track);
+ return res;
+ }
+
+ void backtrack(vector& nums, int start, vector& track) {
+ res.push_back(track);
+ for (int i = start; i < nums.size(); i++) {
+ // 做选择
+ track.push_back(nums[i]);
+ // 回溯
+ backtrack(nums, i + 1, track);
+ // 撤销选择
+ track.pop_back();
+ }
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+// LeetCode Solution for Subsets
+func subsets(nums []int) [][]int {
+ var res [][]int
+ backtrack := func(nums []int, start int, track []int) {
+ tmp := make([]int, len(track))
+ copy(tmp, track)
+ res = append(res, tmp)
+ for i := start; i < len(nums); i++ {
+ // 做选择
+ track = append(track, nums[i])
+ // 回溯
+ backtrack(nums, i+1, track)
+ // 撤销选择
+ track = track[:len(track)-1]
+ }
+ }
+ backtrack(nums, 0, []int{})
+ return res
+}
+```
+
+```java
+// by chatGPT (java)
+class Solution {
+ List> res = new ArrayList<>();
+
+ public List> subsets(int[] nums) {
+ List track = new ArrayList<>();
+ backtrack(nums, 0, track);
+ return res;
+ }
+
+ private void backtrack(int[] nums, int start, List track) {
+ res.add(new ArrayList<>(track));
+ for (int i = start; i < nums.length; i++) {
+ // 做选择
+ track.add(nums[i]);
+ // 回溯
+ backtrack(nums, i + 1, track);
+ // 撤销选择
+ track.remove(track.size() - 1);
+ }
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var subsets = function(nums) {
+ // 记录走过的路径
+ var res = [];
+ var backtrack = function(nums, start, track) {
+ res.push(track.slice()); // 添加路径的拷贝
+ for (var i = start; i < nums.length; i++) {
+ // 做选择
+ track.push(nums[i]);
+ // 回溯
+ backtrack(nums, i + 1, track);
+ // 撤销选择
+ track.pop();
+ }
+ }
+ var track = [];
+ backtrack(nums, 0, track);
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def __init__(self):
+ self.res = []
+
+ def subsets(self, nums: List[int]) -> List[List[int]]:
+ # 记录走过的路径
+ track = []
+ self.backtrack(nums, 0, track)
+ return self.res
+
+ def backtrack(self, nums: List[int], start: int, track: List[int]) -> None:
+ self.res.append(track[:])
+ for i in range(start, len(nums)):
+ # 做选择
+ track.append(nums[i])
+ # 回溯
+ self.backtrack(nums, i + 1, track)
+ # 撤销选择
+ track.pop()
+```
+
+https://leetcode.cn/problems/TVdhkn 的多语言解法👆
+
+https://leetcode.cn/problems/UHnkqh 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ ListNode* reverseList(ListNode* head) {
+ if (head == nullptr || head->next == nullptr) {
+ return head;
+ }
+ ListNode* last = reverseList(head->next);
+ /**
+ 
+ */
+ head->next->next = head;
+ /**
+ 
+ */
+ head->next = nullptr;
+ /**
+ 
+ */
+ return last;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func removeNthFromEnd(head *ListNode, n int) *ListNode {
+ // 哑节点,方便处理删除头节点的情况
+ dummy := &ListNode{Val: 0, Next: head}
+
+ // 快指针先走 n 步
+ fast := head
+ for i := 0; i < n; i++ {
+ fast = fast.Next
+ }
+
+ // 慢指针和快指针一起走,直到快指针到达链表尾部
+ slow := dummy
+ for fast != nil {
+ slow = slow.Next
+ fast = fast.Next
+ }
+
+ // 删除倒数第 n 个节点
+ slow.Next = slow.Next.Next
+
+ // 返回头节点
+ return dummy.Next
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public ListNode reverseList(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+ ListNode last = reverseList(head.next);
+ /**
+ 
+ */
+ head.next.next = head;
+ /**
+ 
+ */
+ head.next = null;
+ /**
+ 
+ */
+ return last;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+/**
+ * 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
+ *
+ * 示例 1:
+ *
+ * 输入: "abcabcbb"
+ * 输出: 3
+ * 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
+ *
+ * 示例 2:
+ *
+ * 输入: "bbbbb"
+ * 输出: 1
+ * 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
+ *
+ * 示例 3:
+ *
+ * 输入: "pwwkew"
+ * 输出: 3
+ * 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
+ * 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
+ */
+
+var lengthOfLongestSubstring = function(s) {
+ let n = s.length, ans = 0;
+ let index = new Map(); // 存储字符上一次出现的位置
+ // i为左指针,j为右指针
+ for (let j = 0, i = 0; j < n; j++) {
+ if (index.has(s[j])) {
+ // 如果有重复的字符,移动左指针到上一个同样字符的后一个位置
+ i = Math.max(index.get(s[j]) + 1, i);
+ }
+ ans = Math.max(ans, j - i + 1); // 更新结果
+ index.set(s[j], j); // 更新字符的位置
+ }
+ return ans;
+};
+```
+
+```python
+# by chatGPT (python)
+# 请保留所有中文注释!
+class Solution:
+ def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
+ # 新建一个虚拟节点,避免特判头节点的情况
+ dummy = ListNode(0, head)
+ # 快指针先走n步
+ fast = head
+ for i in range(n):
+ fast = fast.next
+ # 慢指针开始走,与快指针保持n步的距离
+ slow = dummy
+ while fast is not None:
+ fast = fast.next
+ slow = slow.next
+ # 此时slow指向的是倒数第n+1个节点,删除下一个节点即可
+ slow.next = slow.next.next
+ return dummy.next
+```
+
+https://leetcode.cn/problems/UHnkqh 的多语言解法👆
+
+https://leetcode.cn/problems/VabMRr 的多语言解法👇
+
+```cpp
+// by labuladong (cpp)
+class Solution {
+ public:
+ vector findAnagrams(string s, string t) {
+ unordered_map need, window;
+ for (char c : t) need[c]++;
+
+ int left = 0, right = 0;
+ int valid = 0;
+ vector res; // 记录结果
+ while (right < s.size()) {
+ char c = s[right];
+ right++;
+ // 进行窗口内数据的一系列更新
+ if (need.count(c)) {
+ window[c]++;
+ if (window[c] == need[c])
+ valid++;
+ }
+ // 判断左侧窗口是否要收缩
+ while (right - left >= t.size()) {
+ // 当窗口符合条件时,把起始索引加入 res
+ if (valid == need.size())
+ res.push_back(left);
+ char d = s[left];
+ left++;
+ // 进行窗口内数据的一系列更新
+ if (need.count(d)) {
+ if (window[d] == need[d])
+ valid--;
+ window[d]--;
+ }
+ }
+ }
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func findAnagrams(s string, t string) []int {
+ need, window := make(map[byte]int), make(map[byte]int)
+ for i := range t {
+ need[t[i]]++
+ }
+
+ left, right := 0, 0
+ valid := 0
+ var res []int
+ for right < len(s) {
+ c := s[right]
+ right++
+ // 进行窗口内数据的一系列更新
+ update := func(c byte) {
+ if _, ok := need[c]; ok {
+ window[c]++
+ if window[c] == need[c] {
+ valid++
+ }
+ }
+ }
+ update(c)
+ // 判断左侧窗口是否要收缩
+ for right - left >= len(t) {
+ // 当窗口符合条件时,把起始索引加入 res
+ if valid == len(need) {
+ res = append(res, left)
+ }
+ d := s[left]
+ left++
+ // 进行窗口内数据的一系列更新
+ update := func(d byte) {
+ if _, ok := need[d]; ok {
+ if window[d] == need[d] {
+ valid--
+ }
+ window[d]--
+ }
+ }
+ update(d)
+ }
+ }
+ return res
+}
+```
+
+```java
+// by chatGPT (java)
+class Solution {
+ public List findAnagrams(String s, String t) {
+ Map need = new HashMap<>();
+ Map window = new HashMap<>();
+ for (char c : t.toCharArray()) {
+ need.put(c, need.getOrDefault(c, 0) + 1);
+ }
+
+ int left = 0, right = 0, valid = 0;
+ List res = new ArrayList<>(); // 记录结果
+ while (right < s.length()) {
+ char c = s.charAt(right);
+ right++;
+ // 进行窗口内数据的一系列更新
+ if (need.containsKey(c)) {
+ window.put(c, window.getOrDefault(c, 0) + 1);
+ if (window.get(c).equals(need.get(c))) {
+ valid++;
+ }
+ }
+ // 判断左侧窗口是否要收缩
+ while (right - left >= t.length()) {
+ // 当窗口符合条件时,把起始索引加入 res
+ if (valid == need.size()) {
+ res.add(left);
+ }
+ char d = s.charAt(left);
+ left++;
+ // 进行窗口内数据的一系列更新
+ if (need.containsKey(d)) {
+ if (window.get(d).equals(need.get(d))) {
+ valid--;
+ }
+ window.put(d, window.get(d) - 1);
+ }
+ }
+ }
+ return res;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var findAnagrams = function(s, t) {
+ var need = {}, window = {};
+ for (var i = 0; i < t.length; i++) {
+ var c = t[i];
+ need[c] = (need[c] || 0) + 1;
+ }
+
+ var left = 0, right = 0;
+ var valid = 0;
+ var res = [];
+ while (right < s.length) {
+ var c = s[right];
+ right++;
+
+ // 进行窗口内数据的一系列更新
+ if (need.hasOwnProperty(c)) {
+ window[c] = (window[c] || 0) + 1;
+ if (window[c] === need[c])
+ valid++;
+ }
+
+ // 判断左侧窗口是否要收缩
+ while (right - left >= t.length) {
+ // 当窗口符合条件时,把起始索引加入 res
+ if (valid === Object.keys(need).length)
+ res.push(left);
+ var d = s[left];
+ left++;
+
+ // 进行窗口内数据的一系列更新
+ if (need.hasOwnProperty(d)) {
+ if (window[d] === need[d])
+ valid--;
+ window[d]--;
+ }
+ }
+ }
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def findAnagrams(self, s: str, t: str) -> List[int]:
+ need, window = {}, {}
+ for c in t:
+ need[c] = need.get(c, 0) + 1 # 统计目标字符串中字符出现次数
+
+ left, right = 0, 0
+ valid = 0
+ res = []
+ while right < len(s):
+ c = s[right] # 移入窗口的字符
+ right += 1
+ # 进行窗口内数据的更新
+ if c in need:
+ window[c] = window.get(c, 0) + 1
+ if window[c] == need[c]:
+ valid += 1
+
+ # 判断左侧窗口是否要收缩
+ while right - left >= len(t):
+ # 当窗口符合条件时,把起始索引加入 res
+ if valid == len(need):
+ res.append(left)
+ d = s[left] # 移出窗口的字符
+ left += 1
+ # 进行窗口内数据的更新
+ if d in need:
+ if window[d] == need[d]:
+ valid -= 1
+ window[d] -= 1
+
+ return res
+```
+
+https://leetcode.cn/problems/VabMRr 的多语言解法👆
+
+https://leetcode.cn/problems/VvJkup 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ vector> res;
+
+ /* 主函数,输入一组不重复的数字,返回它们的全排列 */
+ vector> permute(vector& nums) {
+ // 记录「路径」
+ vector track;
+ // 「路径」中的元素会被标记为 true,避免重复使用
+ vector used(nums.size(), false);
+
+ backtrack(nums, track, used);
+ return res;
+ }
+
+ // 路径:记录在 track 中
+ // 选择列表:nums 中不存在于 track 的那些元素(used[i] 为 false)
+ // 结束条件:nums 中的元素全都在 track 中出现
+ void backtrack(vector& nums, vector& track, vector& used) {
+ // 触发结束条件
+ if (track.size() == nums.size()) {
+ res.push_back(track);
+ return;
+ }
+
+ for (int i = 0; i < nums.size(); i++) {
+ // 排除不合法的选择
+ if (used[i]) {
+ /**
+ 
+ */
+ // nums[i] 已经在 track 中,跳过
+ continue;
+ }
+ // 做选择
+ track.push_back(nums[i]);
+ used[i] = true;
+ // 进入下一层决策树
+ backtrack(nums, track, used);
+ // 取消选择
+ track.pop_back();
+ used[i] = false;
+ }
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func permute(nums []int) [][]int {
+ res := [][]int{}
+
+ /* backtrack 函数会用到的参数 */
+ var backtrack func(nums, track []int, used []bool)
+ backtrack = func(nums, track []int, used []bool) {
+ // 「取消选择」的过程是撤销上一次的选择,所以不需要结束条件
+ if len(track) == len(nums) {
+ temp := make([]int, len(track))
+ copy(temp, track)
+ res = append(res, temp)
+ return
+ }
+
+ for i := 0; i < len(nums); i++ {
+ // 排除不合法的选择
+ if used[i] {
+ continue
+ }
+ // 做选择
+ track = append(track, nums[i])
+ used[i] = true
+ // 进入下一层决策树
+ backtrack(nums, track, used)
+ // 「取消选择」,进行回溯
+ track = track[:len(track)-1]
+ used[i] = false
+ }
+ }
+
+ backtrack(nums, []int{}, make([]bool, len(nums)))
+ return res
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+
+ List> res = new LinkedList<>();
+
+ /* 主函数,输入一组不重复的数字,返回它们的全排列 */
+ List> permute(int[] nums) {
+ // 记录「路径」
+ LinkedList track = new LinkedList<>();
+ // 「路径」中的元素会被标记为 true,避免重复使用
+ boolean[] used = new boolean[nums.length];
+
+ backtrack(nums, track, used);
+ return res;
+ }
+
+ // 路径:记录在 track 中
+ // 选择列表:nums 中不存在于 track 的那些元素(used[i] 为 false)
+ // 结束条件:nums 中的元素全都在 track 中出现
+ void backtrack(int[] nums, LinkedList track, boolean[] used) {
+ // 触发结束条件
+ if (track.size() == nums.length) {
+ res.add(new LinkedList(track));
+ return;
+ }
+
+ for (int i = 0; i < nums.length; i++) {
+ // 排除不合法的选择
+ if (used[i]) {
+ /**
+ 
+ */
+ // nums[i] 已经在 track 中,跳过
+ continue;
+ }
+ // 做选择
+ track.add(nums[i]);
+ used[i] = true;
+ // 进入下一层决策树
+ backtrack(nums, track, used);
+ // 取消选择
+ track.removeLast();
+ used[i] = false;
+ }
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var permute = function(nums) {
+ const res = [];
+
+ const backtrack = (track, used) => {
+ if (track.length === nums.length) {
+ res.push([...track]);
+ return;
+ }
+
+ for (let i = 0; i < nums.length; i++) {
+ if (used[i]) {
+ // nums[i] 已经在 track 中,跳过
+ continue;
+ }
+ track.push(nums[i]);
+ used[i] = true;
+ backtrack(track, used);
+ track.pop();
+ used[i] = false;
+ }
+ };
+
+ backtrack([], []);
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def __init__(self):
+ self.res = []
+
+ def permute(self, nums: List[int]) -> List[List[int]]:
+ track = []
+ used = [False] * len(nums)
+ self.backtrack(nums, track, used)
+ return self.res
+
+ def backtrack(self, nums: List[int], track: List[int], used: List[bool]) -> None:
+ if len(track) == len(nums):
+ self.res.append(track.copy())
+ return
+
+ for i in range(len(nums)):
+ if used[i]:
+ # nums[i] 已经在 track 中,跳过
+ continue
+ track.append(nums[i])
+ used[i] = True
+ self.backtrack(nums, track, used)
+ track.pop()
+ used[i] = False
+```
+
+https://leetcode.cn/problems/VvJkup 的多语言解法👆
+
+https://leetcode.cn/problems/WhsWhI 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int longestConsecutive(vector& nums) {
+ // 转化成哈希集合,方便快速查找是否存在某个元素
+ unordered_set set;
+ for (int num : nums) {
+ set.insert(num);
+ }
+
+ int res = 0;
+
+ for (int num : set) {
+ if (set.count(num - 1)) {
+ // num 不是连续子序列的第一个,跳过
+ continue;
+ }
+ // num 是连续子序列的第一个,开始向上计算连续子序列的长度
+ int curNum = num;
+ int curLen = 1;
+
+ while (set.count(curNum + 1)) {
+ curNum += 1;
+ curLen += 1;
+ }
+ // 更新最长连续序列的长度
+ res = max(res, curLen);
+ }
+
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func longestConsecutive(nums []int) int {
+ // 转化成哈希集合,方便快速查找是否存在某个元素
+ set := make(map[int]bool)
+ for _, num := range nums {
+ set[num] = true
+ }
+
+ res := 0
+
+ for num := range set {
+ if set[num-1] {
+ // num 不是连续子序列的第一个,跳过
+ continue
+ }
+ // num 是连续子序列的第一个,开始向上计算连续子序列的长度
+ curNum := num
+ curLen := 1
+
+ for set[curNum+1] {
+ curNum += 1
+ curLen += 1
+ }
+ // 更新最长连续序列的长度
+ res = max(res, curLen)
+ }
+
+ return res
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int longestConsecutive(int[] nums) {
+ // 转化成哈希集合,方便快速查找是否存在某个元素
+ HashSet set = new HashSet();
+ for (int num : nums) {
+ set.add(num);
+ }
+
+ int res = 0;
+
+ for (int num : set) {
+ if (set.contains(num - 1)) {
+ // num 不是连续子序列的第一个,跳过
+ continue;
+ }
+ // num 是连续子序列的第一个,开始向上计算连续子序列的长度
+ int curNum = num;
+ int curLen = 1;
+
+ while (set.contains(curNum + 1)) {
+ curNum += 1;
+ curLen += 1;
+ }
+ // 更新最长连续序列的长度
+ res = Math.max(res, curLen);
+ }
+
+ return res;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var longestConsecutive = function(nums) {
+ // 转化成哈希集合,方便快速查找是否存在某个元素
+ const set = new Set(nums);
+ let res = 0;
+
+ for (const num of set) {
+ if (set.has(num - 1)) {
+ // num 不是连续子序列的第一个,跳过
+ continue;
+ }
+ // num 是连续子序列的第一个,开始向上计算连续子序列的长度
+ let curNum = num;
+ let curLen = 1;
+
+ while (set.has(curNum + 1)) {
+ curNum += 1;
+ curLen += 1;
+ }
+ // 更新最长连续序列的长度
+ res = Math.max(res, curLen);
+ }
+
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def longestConsecutive(self, nums: List[int]) -> int:
+ # 转化成哈希集合,方便快速查找是否存在某个元素
+ num_set = set(nums)
+
+ res = 0
+
+ for num in num_set:
+ if num - 1 in num_set:
+ # num 不是连续子序列的第一个,跳过
+ continue
+ # num 是连续子序列的第一个,开始向上计算连续子序列的长度
+ cur_num = num
+ cur_len = 1
+
+ while cur_num + 1 in num_set:
+ cur_num += 1
+ cur_len += 1
+ # 更新最长连续序列的长度
+ res = max(res, cur_len)
+
+ return res
+```
+
+https://leetcode.cn/problems/WhsWhI 的多语言解法👆
+
+https://leetcode.cn/problems/XltzEq 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ bool isPalindrome(string s) {
+ // 先把所有字符转化成小写,并过滤掉空格和标点这类字符
+ string filtered;
+ for (int i = 0; i < s.length(); i++) {
+ char c = s[i];
+ if (isalnum(c)) { // 使用isalnum函数判断是否为字母或数字
+ filtered += tolower(c); // 使用tolower函数将字符转换为小写
+ }
+ }
+
+ // 然后对剩下的这些目标字符执行双指针算法,判断回文串
+ s = filtered;
+ // 一左一右两个指针相向而行
+ int left = 0, right = s.length() - 1;
+ while (left < right) {
+ if (s[left] != s[right]) {
+ return false;
+ }
+ left++;
+ right--;
+ }
+ return true;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func isPalindrome(s string) bool {
+ // 先把所有字符转化成小写,并过滤掉空格和标点这类字符
+ sb := strings.Builder{}
+ for _, c := range s {
+ if unicode.IsLetter(c) || unicode.IsDigit(c) {
+ sb.WriteRune(unicode.ToLower(c))
+ }
+ }
+
+ // 然后对剩下的这些目标字符执行双指针算法,判断回文串
+ s = sb.String()
+ // 一左一右两个指针相向而行
+ left, right := 0, len(s)-1
+ for left < right {
+ if s[left] != s[right] {
+ return false
+ }
+ left++
+ right--
+ }
+ return true
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public boolean isPalindrome(String s) {
+ // 先把所有字符转化成小写,并过滤掉空格和标点这类字符
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (Character.isLetterOrDigit(c)) {
+ sb.append(Character.toLowerCase(c));
+ }
+ }
+
+ // 然后对剩下的这些目标字符执行双指针算法,判断回文串
+ s = sb.toString();
+ // 一左一右两个指针相向而行
+ int left = 0, right = s.length() - 1;
+ while (left < right) {
+ if (s.charAt(left) != s.charAt(right)) {
+ return false;
+ }
+ left++;
+ right--;
+ }
+ return true;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var isPalindrome = function(s) {
+ // 先把所有字符转化成小写,并过滤掉空格和标点这类字符
+ let sb = '';
+ for (let i = 0; i < s.length; i++) {
+ let c = s.charAt(i);
+ if (/[0-9a-zA-Z]/.test(c)) {
+ sb += c.toLowerCase();
+ }
+ }
+
+ // 然后对剩下的这些目标字符执行双指针算法,判断回文串
+ s = sb;
+ // 一左一右两个指针相向而行
+ let left = 0, right = s.length - 1;
+ while (left < right) {
+ if (s.charAt(left) !== s.charAt(right)) {
+ return false;
+ }
+ left++;
+ right--;
+ }
+ return true;
+}
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def isPalindrome(self, s: str) -> bool:
+ # 先把所有字符转化成小写,并过滤掉空格和标点这类字符
+ sb = []
+ for c in s:
+ if c.isalnum():
+ sb.append(c.lower())
+
+ # 然后对剩下的这些目标字符执行双指针算法,判断回文串
+ s = ''.join(sb)
+ # 一左一右两个指针相向而行
+ left, right = 0, len(s) - 1
+ while left < right:
+ if s[left] != s[right]:
+ return False
+ left += 1
+ right -= 1
+ return True
+```
+
+https://leetcode.cn/problems/XltzEq 的多语言解法👆
+
+https://leetcode.cn/problems/YaVDxD 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int findTargetSumWays(vector& nums, int target) {
+ if (nums.empty()) return 0;
+ return dp(nums, 0, target);
+ }
+
+ // 备忘录
+ unordered_map memo;
+
+ int dp(vector& nums, int i, int remain) {
+ // base case
+ if (i == nums.size()) {
+ if (remain == 0) return 1;
+ return 0;
+ }
+ // 把它俩转成字符串才能作为哈希表的键
+ string key = to_string(i) + "," + to_string(remain);
+ // 避免重复计算
+ if (memo.count(key)) {
+ return memo[key];
+ }
+ // 还是穷举
+ int result = dp(nums, i + 1, remain - nums[i]) + dp(nums, i + 1, remain + nums[i]);
+ // 记入备忘录
+ memo[key] = result;
+ return result;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func findTargetSumWays(nums []int, target int) int {
+ if len(nums) == 0 {
+ return 0
+ }
+ //初始化备忘录
+ memo := make(map[string]int)
+ return dp(nums, 0, target, memo)
+}
+
+func dp(nums []int, i int, remain int, memo map[string]int) int {
+ //基本情况
+ if i == len(nums) {
+ if remain == 0 {
+ return 1
+ }
+ return 0
+ }
+ key := fmt.Sprintf("%d,%d", i, remain)
+ //避免重复计算
+ if _, ok := memo[key]; ok {
+ return memo[key]
+ }
+ //穷举
+ result := dp(nums, i+1, remain-nums[i], memo) + dp(nums, i+1, remain+nums[i], memo)
+ //记录结果到备忘录
+ memo[key] = result
+ return result
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int findTargetSumWays(int[] nums, int target) {
+ if (nums.length == 0) return 0;
+ return dp(nums, 0, target);
+ }
+
+ // 备忘录
+ HashMap memo = new HashMap<>();
+
+ int dp(int[] nums, int i, int remain) {
+ // base case
+ if (i == nums.length) {
+ if (remain == 0) return 1;
+ return 0;
+ }
+ // 把它俩转成字符串才能作为哈希表的键
+ String key = i + "," + remain;
+ // 避免重复计算
+ if (memo.containsKey(key)) {
+ return memo.get(key);
+ }
+ // 还是穷举
+ int result = dp(nums, i + 1, remain - nums[i]) + dp(nums, i + 1, remain + nums[i]);
+ // 记入备忘录
+ memo.put(key, result);
+ return result;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var findTargetSumWays = function(nums, target) {
+ if (nums.length === 0) return 0;
+ // 备忘录
+ let memo = new Map();
+
+ function dp(nums, i, remain) {
+ // base case
+ if (i === nums.length) {
+ if (remain === 0) return 1;
+ return 0;
+ }
+ // 把它俩转成字符串才能作为哈希表的键
+ let key = i + "," + remain;
+ // 避免重复计算
+ if (memo.has(key)) {
+ return memo.get(key);
+ }
+ // 还是穷举
+ let result = dp(nums, i + 1, remain - nums[i]) + dp(nums, i + 1, remain + nums[i]);
+ // 记入备忘录
+ memo.set(key, result);
+ return result;
+ }
+
+ return dp(nums, 0, target);
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def __init__(self):
+ self.memo = {}
+
+ def findTargetSumWays(self, nums: List[int], target: int) -> int:
+ if len(nums) == 0:
+ return 0
+ return self.dp(nums, 0, target)
+
+ def dp(self, nums: List[int], i: int, remain: int) -> int:
+ # base case
+ if i == len(nums):
+ if remain == 0:
+ return 1
+ return 0
+ # 把它俩转成字符串才能作为哈希表的键
+ key = str(i) + "," + str(remain)
+ # 避免重复计算
+ if key in self.memo:
+ return self.memo[key]
+ # 还是穷举
+ result = self.dp(nums, i + 1, remain - nums[i]) + self.dp(nums, i + 1, remain + nums[i])
+ # 记入备忘录
+ self.memo[key] = result
+ return result
+```
+
+https://leetcode.cn/problems/YaVDxD 的多语言解法👆
+
+https://leetcode.cn/problems/Ygoe9J 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+ vector> res;
+ list track;
+
+public:
+ vector> combinationSum(vector& candidates, int target) {
+ if (candidates.empty()) {
+ return res;
+ }
+ backtrack(candidates, 0, target, 0);
+ return res;
+ }
+
+ // 回溯算法主函数
+ void backtrack(vector& candidates, int start, int target, int sum) {
+ if (sum == target) {
+ // 找到目标和
+ res.push_back(vector(track.begin(), track.end()));
+ return;
+ }
+
+ if (sum > target) {
+ // 超过目标和,直接结束
+ return;
+ }
+
+ // 回溯算法框架
+ for (int i = start; i < candidates.size(); i++) {
+ // 选择 candidates[i]
+ track.push_back(candidates[i]);
+ sum += candidates[i];
+ // 递归遍历下一层回溯树
+ backtrack(candidates, i, target, sum);
+ // 撤销选择 candidates[i]
+ sum -= candidates[i];
+ track.pop_back();
+ }
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func combinationSum(candidates []int, target int) [][]int {
+ res := [][]int{}
+ if len(candidates) == 0 {
+ return res
+ }
+ backtrack(candidates, []int{}, target, 0, &res)
+ return res
+}
+
+// 回溯算法框架
+func backtrack(candidates []int, path []int, target, sum int, res *[][]int) {
+ if sum == target {
+ // 找到目标和
+ *res = append(*res, append([]int{}, path...))
+ return
+ }
+ if sum > target {
+ // 超过目标和,直接结束
+ return
+ }
+ for i := 0; i < len(candidates); i++ {
+ // 选择 candidates[i]
+ path = append(path, candidates[i])
+ sum += candidates[i]
+ // 递归遍历下一层回溯树
+ backtrack(candidates[i:], path, target, sum, res)
+ // 撤销选择 candidates[i]
+ sum -= candidates[i]
+ path = path[:len(path)-1]
+ }
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ List> res = new LinkedList<>();
+
+ public List> combinationSum(int[] candidates, int target) {
+ if (candidates.length == 0) {
+ return res;
+ }
+ backtrack(candidates, 0, target, 0);
+ return res;
+ }
+
+ // 记录回溯的路径
+ LinkedList track = new LinkedList<>();
+
+ // 回溯算法主函数
+ void backtrack(int[] candidates, int start, int target, int sum) {
+ if (sum == target) {
+ // 找到目标和
+ res.add(new LinkedList<>(track));
+ return;
+ }
+
+ if (sum > target) {
+ // 超过目标和,直接结束
+ return;
+ }
+
+ // 回溯算法框架
+ for (int i = start; i < candidates.length; i++) {
+ // 选择 candidates[i]
+ track.add(candidates[i]);
+ sum += candidates[i];
+ // 递归遍历下一层回溯树
+ backtrack(candidates, i, target, sum);
+ // 撤销选择 candidates[i]
+ sum -= candidates[i];
+ track.removeLast();
+ }
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var combinationSum = function(candidates, target) {
+ var res = [];
+ if (candidates.length === 0) {
+ return res;
+ }
+
+ // 记录回溯的路径
+ var track = [];
+
+ // 回溯算法主函数
+ var backtrack = function(candidates, start, target, sum) {
+ if (sum === target) {
+ // 找到目标和
+ res.push([...track]);
+ return;
+ }
+
+ if (sum > target) {
+ // 超过目标和,直接结束
+ return;
+ }
+
+ // 回溯算法框架
+ for (var i = start; i < candidates.length; i++) {
+ // 选择 candidates[i]
+ track.push(candidates[i]);
+ sum += candidates[i];
+ // 递归遍历下一层回溯树
+ backtrack(candidates, i, target, sum);
+ // 撤销选择 candidates[i]
+ sum -= candidates[i];
+ track.pop();
+ }
+ };
+
+ backtrack(candidates, 0, target, 0);
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def __init__(self):
+ self.res = []
+ self.track = []
+
+ def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
+ if not candidates:
+ return self.res
+ self.backtrack(candidates, 0, target, 0)
+ return self.res
+
+ # 记录回溯的路径
+ def backtrack(self, candidates, start, target, summation):
+ if summation == target:
+ # 找到目标和
+ self.res.append(self.track[:])
+ return
+ if summation > target:
+ # 超过目标和,直接结束
+ return
+ # 回溯算法框架
+ for i in range(start, len(candidates)):
+ # 选择 candidates[i]
+ self.track.append(candidates[i])
+ summation += candidates[i]
+ # 递归遍历下一层回溯树
+ self.backtrack(candidates, i, target, summation)
+ # 撤销选择 candidates[i]
+ summation -= candidates[i]
+ self.track.pop()
+```
+
+https://leetcode.cn/problems/Ygoe9J 的多语言解法👆
+
+https://leetcode.cn/problems/ZL6zAn 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int maxAreaOfIsland(vector>& grid) {
+ // 记录岛屿的最大面积
+ int res = 0;
+ int m = grid.size(), n = grid[0].size();
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ if (grid[i][j] == 1) {
+ // 淹没岛屿,并更新最大岛屿面积
+ res = max(res, dfs(grid, i, j));
+ }
+ }
+ }
+ return res;
+ }
+
+ // 淹没与 (i, j) 相邻的陆地,并返回淹没的陆地面积
+ int dfs(vector>& grid, int i, int j) {
+ int m = grid.size(), n = grid[0].size();
+ if (i < 0 || j < 0 || i >= m || j >= n) {
+ // 超出索引边界
+ return 0;
+ }
+ if (grid[i][j] == 0) {
+ // 已经是海水了
+ return 0;
+ }
+ // 将 (i, j) 变成海水
+ grid[i][j] = 0;
+
+ return dfs(grid, i + 1, j)
+ + dfs(grid, i, j + 1)
+ + dfs(grid, i - 1, j)
+ + dfs(grid, i, j - 1) + 1;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+// 记录岛屿的最大面积
+func maxAreaOfIsland(grid [][]int) int {
+ res := 0
+ m, n := len(grid), len(grid[0])
+ for i := 0; i < m; i++ {
+ for j := 0; j < n; j++ {
+ if grid[i][j] == 1 {
+ // 淹没岛屿,并更新最大岛屿面积
+ res = max(res, dfs(grid, i, j))
+ }
+ }
+ }
+ return res
+}
+
+// 淹没与 (i, j) 相邻的陆地,并返回淹没的陆地面积
+func dfs(grid [][]int, i, j int) int {
+ m, n := len(grid), len(grid[0])
+ if i < 0 || j < 0 || i >= m || j >= n {
+ // 超出索引边界
+ return 0
+ }
+ if grid[i][j] == 0 {
+ // 已经是海水了
+ return 0
+ }
+ // 将 (i, j) 变成海水
+ grid[i][j] = 0
+
+ return dfs(grid, i+1, j) +
+ dfs(grid, i, j+1) +
+ dfs(grid, i-1, j) +
+ dfs(grid, i, j-1) + 1
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int maxAreaOfIsland(int[][] grid) {
+ // 记录岛屿的最大面积
+ int res = 0;
+ int m = grid.length, n = grid[0].length;
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ if (grid[i][j] == 1) {
+ // 淹没岛屿,并更新最大岛屿面积
+ res = Math.max(res, dfs(grid, i, j));
+ }
+ }
+ }
+ return res;
+ }
+
+ // 淹没与 (i, j) 相邻的陆地,并返回淹没的陆地面积
+ int dfs(int[][] grid, int i, int j) {
+ int m = grid.length, n = grid[0].length;
+ if (i < 0 || j < 0 || i >= m || j >= n) {
+ // 超出索引边界
+ return 0;
+ }
+ if (grid[i][j] == 0) {
+ // 已经是海水了
+ return 0;
+ }
+ // 将 (i, j) 变成海水
+ grid[i][j] = 0;
+
+ return dfs(grid, i + 1, j)
+ + dfs(grid, i, j + 1)
+ + dfs(grid, i - 1, j)
+ + dfs(grid, i, j - 1) + 1;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var maxAreaOfIsland = function(grid) {
+ let res = 0;
+ let m = grid.length, n = grid[0].length;
+
+ function dfs(grid, i, j) {
+ if (i < 0 || j < 0 || i >= m || j >= n) {
+ // 超出索引边界
+ return 0;
+ }
+ if (grid[i][j] == 0) {
+ // 已经是海水了
+ return 0;
+ }
+ // 将 (i, j) 变成海水
+ grid[i][j] = 0;
+
+ return dfs(grid, i + 1, j)
+ + dfs(grid, i, j + 1)
+ + dfs(grid, i - 1, j)
+ + dfs(grid, i, j - 1) + 1;
+ }
+
+ for (let i = 0; i < m; i++) {
+ for (let j = 0; j < n; j++) {
+ if (grid[i][j] == 1) {
+ res = Math.max(res, dfs(grid, i, j));
+ }
+ }
+ }
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
+ # 记录岛屿的最大面积
+ res = 0
+ m, n = len(grid), len(grid[0])
+ for i in range(m):
+ for j in range(n):
+ if grid[i][j] == 1:
+ # 淹没岛屿,并更新最大岛屿面积
+ res = max(res, self.dfs(grid, i, j))
+ return res
+
+ # 淹没与 (i, j) 相邻的陆地,并返回淹没的陆地面积
+ def dfs(self, grid: List[List[int]], i: int, j: int) -> int:
+ m, n = len(grid), len(grid[0])
+ if i < 0 or j < 0 or i >= m or j >= n:
+ # 超出索引边界
+ return 0
+ if grid[i][j] == 0:
+ # 已经是海水了
+ return 0
+ # 将 (i, j) 变成海水
+ grid[i][j] = 0
+
+ return (self.dfs(grid, i + 1, j)
+ + self.dfs(grid, i, j + 1)
+ + self.dfs(grid, i - 1, j)
+ + self.dfs(grid, i, j - 1) + 1)
+```
+
+https://leetcode.cn/problems/ZL6zAn 的多语言解法👆
+
+https://leetcode.cn/problems/aMhZSa 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ bool isPalindrome(ListNode* head) {
+ ListNode *slow, *fast;
+ slow = fast = head;
+ while (fast != nullptr && fast->next != nullptr) {
+ slow = slow->next;
+ fast = fast->next->next;
+ }
+
+ if (fast != nullptr)
+ slow = slow->next;
+
+ ListNode *left = head;
+ ListNode *right = reverse(slow);
+ while (right != nullptr) {
+ if (left->val != right->val)
+ return false;
+ left = left->next;
+ right = right->next;
+ }
+
+ return true;
+ }
+
+ ListNode* reverse(ListNode* head) {
+ ListNode *pre = nullptr, *cur = head;
+ while (cur != nullptr) {
+ ListNode *next = cur->next;
+ cur->next = pre;
+ pre = cur;
+ cur = next;
+ }
+ return pre;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func isPalindrome(head *ListNode) bool {
+ slow, fast := head, head
+ for fast != nil && fast.Next != nil {
+ slow = slow.Next
+ fast = fast.Next.Next
+ }
+ if fast != nil {
+ slow = slow.Next
+ }
+ left, right := head, reverse(slow)
+ for right != nil {
+ if left.Val != right.Val {
+ return false
+ }
+ left = left.Next
+ right = right.Next
+ }
+ return true
+}
+
+func reverse(head *ListNode) *ListNode {
+ var pre *ListNode
+ cur := head
+ for cur != nil {
+ next := cur.Next
+ cur.Next = pre
+ pre = cur
+ cur = next
+ }
+ return pre
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public boolean isPalindrome(ListNode head) {
+ ListNode slow, fast;
+ slow = fast = head;
+ while (fast != null && fast.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+ }
+
+ if (fast != null)
+ slow = slow.next;
+
+ ListNode left = head;
+ ListNode right = reverse(slow);
+ while (right != null) {
+ if (left.val != right.val)
+ return false;
+ left = left.next;
+ right = right.next;
+ }
+
+ return true;
+ }
+
+ ListNode reverse(ListNode head) {
+ ListNode pre = null, cur = head;
+ while (cur != null) {
+ ListNode next = cur.next;
+ cur.next = pre;
+ pre = cur;
+ cur = next;
+ }
+ return pre;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var isPalindrome = function(head) {
+ let slow, fast;
+ slow = fast = head;
+ while (fast != null && fast.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+ }
+
+ if (fast != null)
+ slow = slow.next;
+
+ let left = head;
+ let right = reverse(slow);
+ while (right != null) {
+ if (left.val != right.val)
+ return false;
+ left = left.next;
+ right = right.next;
+ }
+
+ return true;
+};
+
+var reverse = function(head) {
+ let pre = null, cur = head;
+ while (cur != null) {
+ let next = cur.next;
+ cur.next = pre;
+ pre = cur;
+ cur = next;
+ }
+ return pre;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def isPalindrome(self, head: ListNode) -> bool:
+ slow, fast = head, head
+ while fast and fast.next:
+ slow = slow.next
+ fast = fast.next.next
+
+ if fast:
+ slow = slow.next
+
+ left = head
+ right = self.reverse(slow)
+ while right:
+ if left.val != right.val:
+ return False
+ left = left.next
+ right = right.next
+
+ return True
+
+ def reverse(self, head: ListNode) -> ListNode:
+ pre, cur = None, head
+ while cur:
+ nxt = cur.next
+ cur.next = pre
+ pre = cur
+ cur = nxt
+ return pre
+```
+
+https://leetcode.cn/problems/aMhZSa 的多语言解法👆
+
+https://leetcode.cn/problems/add-binary 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ string addBinary(string a, string b) {
+ // 先把输入的这两个二进制串反转,低位放在前面,方便处理进位
+ reverse(a.begin(), a.end());
+ reverse(b.begin(), b.end());
+ // 存储结果
+ string res = "";
+
+ int m = a.size(), n = b.size();
+ // carry 记录进位
+ int carry = 0;
+ int i = 0;
+
+ // 开始类似 [2. 两数相加](#2) 的加法模拟逻辑
+ // 只是这里运算的是二进制字符串
+ while (i < max(m, n) || carry > 0) {
+ int val = carry;
+ val += i < m ? (a[i] - '0') : 0;
+ val += i < n ? (b[i] - '0') : 0;
+ res.push_back(val % 2 + '0');
+ carry = val / 2;
+ i++;
+ }
+
+ reverse(res.begin(), res.end());
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func addBinary(a string, b string) string {
+ // 先把输入的这两个二进制串反转,低位放在前面,方便处理进位
+ reverse := func(str string) string {
+ reversed := []rune(str)
+ for i, j := 0, len(reversed)-1; i < j; i, j = i+1, j-1 {
+ reversed[i], reversed[j] = reversed[j], reversed[i]
+ }
+ return string(reversed)
+ }
+ a = reverse(a)
+ b = reverse(b)
+ // 存储结果
+ var sb strings.Builder
+
+ m, n := len(a), len(b)
+ // carry 记录进位
+ carry := 0
+ i := 0
+
+ // 开始类似 [2. 两数相加](#2) 的加法模拟逻辑
+ // 只是这里运算的是二进制字符串
+ for i < max(m, n) || carry > 0 {
+ val := carry
+ if i < m {
+ val += int(a[i] - '0')
+ }
+ if i < n {
+ val += int(b[i] - '0')
+ }
+ sb.WriteString(strconv.Itoa(val % 2))
+ carry = val / 2
+ i++
+ }
+
+ return reverse(sb.String())
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public String addBinary(String a, String b) {
+ // 先把输入的这两个二进制串反转,低位放在前面,方便处理进位
+ a = new StringBuilder(a).reverse().toString();
+ b = new StringBuilder(b).reverse().toString();
+ // 存储结果
+ StringBuilder sb = new StringBuilder();
+
+ int m = a.length(), n = b.length();
+ // carry 记录进位
+ int carry = 0;
+ int i = 0;
+
+ // 开始类似 [2. 两数相加](#2) 的加法模拟逻辑
+ // 只是这里运算的是二进制字符串
+ while (i < Math.max(m, n) || carry > 0) {
+ int val = carry;
+ val += i < m ? (a.charAt(i) - '0') : 0;
+ val += i < n ? (b.charAt(i) - '0') : 0;
+ sb.append(val % 2);
+ carry = val / 2;
+ i++;
+ }
+
+ return sb.reverse().toString();
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var addBinary = function(a, b) {
+ // 先把输入的这两个二进制串反转,低位放在前面,方便处理进位
+ a = a.split("").reverse().join("");
+ b = b.split("").reverse().join("");
+ // 存储结果
+ var sb = "";
+
+ var m = a.length, n = b.length;
+ // carry 记录进位
+ var carry = 0;
+ var i = 0;
+
+ // 开始类似 [2. 两数相加](#2) 的加法模拟逻辑
+ // 只是这里运算的是二进制字符串
+ while (i < Math.max(m, n) || carry > 0) {
+ var val = carry;
+ val += i < m ? parseInt(a.charAt(i)) : 0;
+ val += i < n ? parseInt(b.charAt(i)) : 0;
+ sb += (val % 2);
+ carry = Math.floor(val / 2);
+ i++;
+ }
+
+ return sb.split("").reverse().join("");
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def addBinary(self, a: str, b: str) -> str:
+ # 先把输入的这两个二进制串反转,低位放在前面,方便处理进位
+ a = a[::-1]
+ b = b[::-1]
+ # 存储结果
+ sb = []
+
+ m, n = len(a), len(b)
+ # carry 记录进位
+ carry = 0
+ i = 0
+
+ # 开始类似 [2. 两数相加](#2) 的加法模拟逻辑
+ # 只是这里运算的是二进制字符串
+ while i < max(m, n) or carry > 0:
+ val = carry
+ val += int(a[i]) if i < m else 0
+ val += int(b[i]) if i < n else 0
+ sb.append(str(val % 2))
+ carry = val // 2
+ i += 1
+
+ return "".join(sb[::-1])
+```
+
+https://leetcode.cn/problems/add-binary 的多语言解法👆
+
+https://leetcode.cn/problems/add-two-numbers 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
+ // 在两条链表上的指针
+ ListNode *p1 = l1, *p2 = l2;
+ // 虚拟头结点(构建新链表时的常用技巧)
+ ListNode *dummy = new ListNode(-1);
+ // 指针 p 负责构建新链表
+ ListNode *p = dummy;
+ // 记录进位
+ int carry = 0;
+ // 开始执行加法,两条链表走完且没有进位时才能结束循环
+ while (p1 != nullptr || p2 != nullptr || carry > 0) {
+ // 先加上上次的进位
+ int val = carry;
+ if (p1 != nullptr) {
+ val += p1->val;
+ p1 = p1->next;
+ }
+ if (p2 != nullptr) {
+ val += p2->val;
+ p2 = p2->next;
+ }
+ // 处理进位情况
+ carry = val / 10;
+ val = val % 10;
+ // 构建新节点
+ p->next = new ListNode(val);
+ p = p->next;
+ }
+ // 返回结果链表的头结点(去除虚拟头结点)
+ return dummy->next;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
+ // 在两条链表上的指针
+ p1, p2 := l1, l2
+ // 虚拟头结点(构建新链表时的常用技巧)
+ dummy := &ListNode{-1, nil}
+ // 指针 p 负责构建新链表
+ p := dummy
+ // 记录进位
+ carry := 0
+ // 开始执行加法,两条链表走完且没有进位时才能结束循环
+ for p1 != nil || p2 != nil || carry > 0 {
+ // 先加上上次的进位
+ val := carry
+ if p1 != nil {
+ val += p1.Val
+ p1 = p1.Next
+ }
+ if p2 != nil {
+ val += p2.Val
+ p2 = p2.Next
+ }
+ // 处理进位情况
+ carry = val / 10
+ val = val % 10
+ // 构建新节点
+ p.Next = &ListNode{val, nil}
+ p = p.Next
+ }
+ // 返回结果链表的头结点(去除虚拟头结点)
+ return dummy.Next
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
+ // 在两条链表上的指针
+ ListNode p1 = l1, p2 = l2;
+ // 虚拟头结点(构建新链表时的常用技巧)
+ ListNode dummy = new ListNode(-1);
+ // 指针 p 负责构建新链表
+ ListNode p = dummy;
+ // 记录进位
+ int carry = 0;
+ // 开始执行加法,两条链表走完且没有进位时才能结束循环
+ while (p1 != null || p2 != null || carry > 0) {
+ // 先加上上次的进位
+ int val = carry;
+ if (p1 != null) {
+ val += p1.val;
+ p1 = p1.next;
+ }
+ if (p2 != null) {
+ val += p2.val;
+ p2 = p2.next;
+ }
+ // 处理进位情况
+ carry = val / 10;
+ val = val % 10;
+ // 构建新节点
+ p.next = new ListNode(val);
+ p = p.next;
+ }
+ // 返回结果链表的头结点(去除虚拟头结点)
+ return dummy.next;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var addTwoNumbers = function(l1, l2) {
+ // 在两条链表上的指针
+ let p1 = l1, p2 = l2;
+ // 虚拟头结点(构建新链表时的常用技巧)
+ let dummy = new ListNode(-1);
+ // 指针 p 负责构建新链表
+ let p = dummy;
+ // 记录进位
+ let carry = 0;
+ // 开始执行加法,两条链表走完且没有进位时才能结束循环
+ while (p1 !== null || p2 !== null || carry > 0) {
+ // 先加上上次的进位
+ let val = carry;
+ if (p1 !== null) {
+ val += p1.val;
+ p1 = p1.next;
+ }
+ if (p2 !== null) {
+ val += p2.val;
+ p2 = p2.next;
+ }
+ // 处理进位情况
+ carry = Math.floor(val / 10);
+ val = val % 10;
+ // 构建新节点
+ p.next = new ListNode(val);
+ p = p.next;
+ }
+ // 返回结果链表的头结点(去除虚拟头结点)
+ return dummy.next;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
+ # 在两条链表上的指针
+ p1, p2 = l1, l2
+ # 虚拟头结点(构建新链表时的常用技巧)
+ dummy = ListNode(-1)
+ # 指针 p 负责构建新链表
+ p = dummy
+ # 记录进位
+ carry = 0
+ # 开始执行加法,两条链表走完且没有进位时才能结束循环
+ while p1 or p2 or carry:
+ # 先加上上次的进位
+ val = carry
+ if p1:
+ val += p1.val
+ p1 = p1.next
+ if p2:
+ val += p2.val
+ p2 = p2.next
+ # 处理进位情况
+ carry, val = divmod(val, 10)
+ # 构建新节点
+ p.next = ListNode(val)
+ p = p.next
+ # 返回结果链表的头结点(去除虚拟头结点)
+ return dummy.next
+```
+
+https://leetcode.cn/problems/add-two-numbers 的多语言解法👆
+
+https://leetcode.cn/problems/add-two-numbers-ii 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
+ // 把链表元素转入栈中
+ stack stk1, stk2;
+ while (l1 != nullptr) {
+ stk1.push(l1->val);
+ l1 = l1->next;
+ }
+ while (l2 != nullptr) {
+ stk2.push(l2->val);
+ l2 = l2->next;
+ }
+
+ // 接下来基本上是复用我在第 2 题的代码逻辑
+ // 注意新节点要直接插入到 dummy 后面
+
+ // 虚拟头结点(构建新链表时的常用技巧)
+ ListNode* dummy = new ListNode(-1);
+
+ // 记录进位
+ int carry = 0;
+ // 开始执行加法,两条链表走完且没有进位时才能结束循环
+ while (!stk1.empty() || !stk2.empty() || carry > 0) {
+ // 先加上上次的进位
+ int val = carry;
+ if (!stk1.empty()) {
+ val += stk1.top();
+ stk1.pop();
+ }
+ if (!stk2.empty()) {
+ val += stk2.top();
+ stk2.pop();
+ }
+ // 处理进位情况
+ carry = val / 10;
+ val = val % 10;
+ // 构建新节点,直接接在 dummy 后面
+ ListNode* newNode = new ListNode(val);
+ newNode->next = dummy->next;
+ dummy->next = newNode;
+ }
+ // 返回结果链表的头结点(去除虚拟头结点)
+ ListNode* result = dummy->next;
+ delete dummy;
+ return result;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
+ // 把链表元素转入栈中
+ stk1 := []int{}
+ for l1 != nil {
+ stk1 = append(stk1, l1.Val)
+ l1 = l1.Next
+ }
+ stk2 := []int{}
+ for l2 != nil {
+ stk2 = append(stk2, l2.Val)
+ l2 = l2.Next
+ }
+
+ // 接下来基本上是复用我在第 2 题的代码逻辑
+ // 注意新节点要直接插入到 dummy 后面
+
+ // 虚拟头结点(构建新链表时的常用技巧)
+ dummy := &ListNode{-1, nil}
+
+ // 记录进位
+ carry := 0
+ // 开始执行加法,两条链表走完且没有进位时才能结束循环
+ for len(stk1) > 0 || len(stk2) > 0 || carry > 0 {
+ // 先加上上次的进位
+ val := carry
+ if len(stk1) > 0 {
+ val += stk1[len(stk1)-1]
+ stk1 = stk1[:len(stk1)-1]
+ }
+ if len(stk2) > 0 {
+ val += stk2[len(stk2)-1]
+ stk2 = stk2[:len(stk2)-1]
+ }
+ // 处理进位情况
+ carry = val / 10
+ val = val % 10
+ // 构建新节点,直接接在 dummy 后面
+ newNode := &ListNode{val, dummy.Next}
+ dummy.Next = newNode
+ }
+ // 返回结果链表的头结点(去除虚拟头结点)
+ return dummy.Next
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
+ // 把链表元素转入栈中
+ Stack stk1 = new Stack<>();
+ while (l1 != null) {
+ stk1.push(l1.val);
+ l1 = l1.next;
+ }
+ Stack stk2 = new Stack<>();
+ while (l2 != null) {
+ stk2.push(l2.val);
+ l2 = l2.next;
+ }
+
+ // 接下来基本上是复用我在第 2 题的代码逻辑
+ // 注意新节点要直接插入到 dummy 后面
+
+ // 虚拟头结点(构建新链表时的常用技巧)
+ ListNode dummy = new ListNode(-1);
+
+ // 记录进位
+ int carry = 0;
+ // 开始执行加法,两条链表走完且没有进位时才能结束循环
+ while (!stk1.isEmpty() || !stk2.isEmpty() || carry > 0) {
+ // 先加上上次的进位
+ int val = carry;
+ if (!stk1.isEmpty()) {
+ val += stk1.pop();
+ }
+ if (!stk2.isEmpty()) {
+ val += stk2.pop();
+ }
+ // 处理进位情况
+ carry = val / 10;
+ val = val % 10;
+ // 构建新节点,直接接在 dummy 后面
+ ListNode newNode = new ListNode(val);
+ newNode.next = dummy.next;
+ dummy.next = newNode;
+ }
+ // 返回结果链表的头结点(去除虚拟头结点)
+ return dummy.next;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var addTwoNumbers = function(l1, l2) {
+ // 把链表元素转入栈中
+ const stk1 = [];
+ while (l1 !== null) {
+ stk1.push(l1.val);
+ l1 = l1.next;
+ }
+ const stk2 = [];
+ while (l2 !== null) {
+ stk2.push(l2.val);
+ l2 = l2.next;
+ }
+
+ // 接下来基本上是复用我在第 2 题的代码逻辑
+ // 注意新节点要直接插入到 dummy 后面
+
+ // 虚拟头结点(构建新链表时的常用技巧)
+ const dummy = new ListNode(-1);
+
+ // 记录进位
+ let carry = 0;
+ // 开始执行加法,两条链表走完且没有进位时才能结束循环
+ while (stk1.length || stk2.length || carry > 0) {
+ // 先加上上次的进位
+ let val = carry;
+ if (stk1.length) {
+ val += stk1.pop();
+ }
+ if (stk2.length) {
+ val += stk2.pop();
+ }
+ // 处理进位情况
+ carry = Math.floor(val / 10);
+ val = val % 10;
+ // 构建新节点,直接接在 dummy 后面
+ const newNode = new ListNode(val);
+ newNode.next = dummy.next;
+ dummy.next = newNode;
+ }
+ // 返回结果链表的头结点(去除虚拟头结点)
+ return dummy.next;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
+ # 把链表元素转入栈中
+ stk1 = []
+ while l1:
+ stk1.append(l1.val)
+ l1 = l1.next
+ stk2 = []
+ while l2:
+ stk2.append(l2.val)
+ l2 = l2.next
+
+ # 接下来基本上是复用我在第 2 题的代码逻辑
+ # 注意新节点要直接插入到 dummy 后面
+
+ # 虚拟头结点(构建新链表时的常用技巧)
+ dummy = ListNode(-1)
+
+ # 记录进位
+ carry = 0
+ # 开始执行加法,两条链表走完且没有进位时才能结束循环
+ while stk1 or stk2 or carry > 0:
+ # 先加上上次的进位
+ val = carry
+ if stk1:
+ val += stk1.pop()
+ if stk2:
+ val += stk2.pop()
+ # 处理进位情况
+ carry = val // 10
+ val = val % 10
+ # 构建新节点,直接接在 dummy 后面
+ newNode = ListNode(val)
+ newNode.next = dummy.next
+ dummy.next = newNode
+ # 返回结果链表的头结点(去除虚拟头结点)
+ return dummy.next
+```
+
+https://leetcode.cn/problems/add-two-numbers-ii 的多语言解法👆
+
+https://leetcode.cn/problems/advantage-shuffle 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ vector advantageCount(vector& nums1, vector& nums2) {
+ int n = nums1.size();
+ // 给 nums2 降序排序
+ priority_queue> maxpq;
+ for (int i = 0; i < n; i++) {
+ maxpq.push({i, nums2[i]});
+ }
+ // 给 nums1 升序排序
+ sort(nums1.begin(), nums1.end());
+
+ // nums1[left] 是最小值,nums1[right] 是最大值
+ int left = 0, right = n - 1;
+ vector res(n);
+
+ while (!maxpq.empty()) {
+ auto [i, maxval] = maxpq.top(); maxpq.pop();
+ // maxval 是 nums2 中的最大值,i 是对应索引
+ if (maxval < nums1[right]) {
+ // 如果 nums1[right] 能胜过 maxval,那就自己上
+ res[i] = nums1[right];
+ right--;
+ } else {
+ // 否则用最小值混一下,养精蓄锐
+ res[i] = nums1[left];
+ left++;
+ }
+ }
+ return res;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func advantageCount(nums1 []int, nums2 []int) []int {
+ n := len(nums1)
+ // 给 nums2 降序排序
+ maxpq := make(PriorityQueue, 0)
+ heap.Init(&maxpq)
+ for i := 0; i < n; i++ {
+ heap.Push(&maxpq, []int{i, nums2[i]})
+ }
+ // 给 nums1 升序排序
+ sort.Ints(nums1)
+
+ // nums1[left] 是最小值,nums1[right] 是最大值
+ left, right := 0, n-1
+ res := make([]int, n)
+
+ for maxpq.Len() > 0 {
+ pair := heap.Pop(&maxpq).([]int)
+ // maxval 是 nums2 中的最大值,i 是对应索引
+ i, maxval := pair[0], pair[1]
+ if maxval < nums1[right] {
+ // 如果 nums1[right] 能胜过 maxval,那就自己上
+ res[i] = nums1[right]
+ right--
+ } else {
+ // 否则用最小值混一下,养精蓄锐
+ res[i] = nums1[left]
+ left++
+ }
+ }
+ return res
+}
+
+// 定义一个优先队列类型 PriorityQueue,用于按照指定比较函数排序
+type PriorityQueue [][]int
+
+func (pq PriorityQueue) Len() int {
+ return len(pq)
+}
+
+func (pq PriorityQueue) Less(i, j int) bool {
+ return pq[i][1] > pq[j][1]
+}
+
+func (pq PriorityQueue) Swap(i, j int) {
+ pq[i], pq[j] = pq[j], pq[i]
+}
+
+func (pq *PriorityQueue) Push(x interface{}) {
+ item := x.([]int)
+ *pq = append(*pq, item)
+}
+
+func (pq *PriorityQueue) Pop() interface{} {
+ old := *pq
+ n := len(old)
+ item := old[n-1]
+ *pq = old[0 : n-1]
+ return item
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int[] advantageCount(int[] nums1, int[] nums2) {
+ int n = nums1.length;
+ // 给 nums2 降序排序
+ PriorityQueue maxpq = new PriorityQueue<>(
+ (int[] pair1, int[] pair2) -> {
+ return pair2[1] - pair1[1];
+ }
+ );
+ for (int i = 0; i < n; i++) {
+ maxpq.offer(new int[]{i, nums2[i]});
+ }
+ // 给 nums1 升序排序
+ Arrays.sort(nums1);
+
+ // nums1[left] 是最小值,nums1[right] 是最大值
+ int left = 0, right = n - 1;
+ int[] res = new int[n];
+
+ while (!maxpq.isEmpty()) {
+ int[] pair = maxpq.poll();
+ // maxval 是 nums2 中的最大值,i 是对应索引
+ int i = pair[0], maxval = pair[1];
+ if (maxval < nums1[right]) {
+ // 如果 nums1[right] 能胜过 maxval,那就自己上
+ res[i] = nums1[right];
+ right--;
+ } else {
+ // 否则用最小值混一下,养精蓄锐
+ res[i] = nums1[left];
+ left++;
+ }
+ }
+ return res;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var advantageCount = function(nums1, nums2) {
+ var n = nums1.length;
+ //给 nums2 降序排序
+ var maxpq = new PriorityQueue((pair1, pair2) => pair2[1] - pair1[1]);
+ for (var i = 0; i < n; i++) {
+ maxpq.offer([i, nums2[i]]);
+ }
+ //给 nums1 升序排序
+ nums1.sort((a, b) => a - b);
+ // nums1[left] 是最小值,nums1[right] 是最大值
+ var left = 0, right = n - 1;
+ var res = new Array(n);
+
+ while (!maxpq.isEmpty()) {
+ var pair = maxpq.poll();
+ // maxval 是 nums2 中的最大值,i 是对应索引
+ var i = pair[0], maxval = pair[1];
+ if (maxval < nums1[right]) {
+ // 如果 nums1[right] 能胜过 maxval,那就自己上
+ res[i] = nums1[right];
+ right--;
+ } else {
+ // 否则用最小值混一下,养精蓄锐
+ res[i] = nums1[left];
+ left++;
+ }
+ }
+ return res;
+}
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def advantageCount(self, nums1: List[int], nums2: List[int]) -> List[int]:
+ n = len(nums1)
+ # 给 nums2 降序排序
+ maxpq = []
+ for i in range(n):
+ maxpq.append([i, nums2[i]])
+ maxpq.sort(key=lambda x: -x[1])
+
+ # 给 nums1 升序排序
+ nums1.sort()
+
+ # nums1[left] 是最小值,nums1[right] 是最大值
+ left, right = 0, n - 1
+ res = [0] * n
+
+ while maxpq:
+ pair = maxpq.pop(0)
+ # maxval 是 nums2 中的最大值,i 是对应索引
+ i, maxval = pair[0], pair[1]
+ if maxval < nums1[right]:
+ # 如果 nums1[right] 能胜过 maxval,那就自己上
+ res[i] = nums1[right]
+ right -= 1
+ else:
+ # 否则用最小值混一下,养精蓄锐
+ res[i] = nums1[left]
+ left += 1
+ return res
+```
+
+https://leetcode.cn/problems/advantage-shuffle 的多语言解法👆
+
+https://leetcode.cn/problems/all-paths-from-source-to-target 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+ // 记录所有路径
+ vector> res;
+
+public:
+ vector> allPathsSourceTarget(vector>& graph) {
+ deque path;
+ traverse(graph, 0, path);
+ return res;
+ }
+
+ /* 图的遍历框架 */
+ void traverse(vector>& graph, int s, deque& path) {
+
+ // 添加节点 s 到路径
+ path.push_back(s);
+
+ int n = graph.size();
+ if (s == n - 1) {
+ // 到达终点
+ res.push_back(vector(path.begin(), path.end()));
+ path.pop_back();
+ return;
+ }
+
+ // 递归每个相邻节点
+ for (int v : graph[s]) {
+ traverse(graph, v, path);
+ }
+
+ // 从路径移出节点 s
+ path.pop_back();
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func allPathsSourceTarget(graph [][]int) [][]int {
+ res := [][]int{}
+ path := []int{}
+
+ var traverse func(graph [][]int, s int, path []int)
+ traverse = func(graph [][]int, s int, path []int) {
+ // 添加节点 s 到路径
+ path = append(path, s)
+
+ n := len(graph)
+ if s == n - 1 {
+ // 到达终点
+ tmp := make([]int, len(path))
+ copy(tmp, path)
+ res = append(res, tmp)
+ path = path[:len(path) - 1]
+ return
+ }
+
+ // 递归每个相邻节点
+ for _, v := range graph[s] {
+ traverse(graph, v, path)
+ }
+
+ // 从路径移出节点 s
+ path = path[:len(path) - 1]
+ }
+
+ traverse(graph, 0, path)
+ return res
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ // 记录所有路径
+ List> res = new LinkedList<>();
+
+ public List> allPathsSourceTarget(int[][] graph) {
+ LinkedList path = new LinkedList<>();
+ traverse(graph, 0, path);
+ return res;
+ }
+
+ /* 图的遍历框架 */
+ void traverse(int[][] graph, int s, LinkedList path) {
+
+ // 添加节点 s 到路径
+ path.addLast(s);
+
+ int n = graph.length;
+ if (s == n - 1) {
+ // 到达终点
+ res.add(new LinkedList<>(path));
+ path.removeLast();
+ return;
+ }
+
+ // 递归每个相邻节点
+ for (int v : graph[s]) {
+ traverse(graph, v, path);
+ }
+
+ // 从路径移出节点 s
+ path.removeLast();
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var allPathsSourceTarget = function(graph) {
+ // 记录所有路径
+ var res = [];
+
+ var traverse = function(graph, s, path) {
+ // 添加节点 s 到路径
+ path.push(s);
+
+ var n = graph.length;
+ if (s === n - 1) {
+ // 到达终点
+ res.push(path.slice());
+ path.pop();
+ return;
+ }
+
+ // 递归每个相邻节点
+ for (var i = 0; i < graph[s].length; i++) {
+ traverse(graph, graph[s][i], path);
+ }
+
+ // 从路径移出节点 s
+ path.pop();
+ };
+
+ var path = [];
+ traverse(graph, 0, path);
+
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+from typing import List
+
+class Solution:
+ def __init__(self):
+ # 记录所有路径
+ self.res = []
+
+ def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
+ path = []
+ self.traverse(graph, 0, path)
+ return self.res
+
+ """ 图的遍历框架 """
+ def traverse(self, graph: List[List[int]], s: int, path: List[int]) -> None:
+ # 添加节点 s 到路径
+ path.append(s)
+
+ n = len(graph)
+ if s == n - 1:
+ # 到达终点
+ self.res.append(path[:])
+ path.pop()
+ return
+
+ # 递归每个相邻节点
+ for v in graph[s]:
+ self.traverse(graph, v, path)
+
+ # 从路径移出节点 s
+ path.pop()
+```
+
+https://leetcode.cn/problems/all-paths-from-source-to-target 的多语言解法👆
+
+https://leetcode.cn/problems/bP4bmD 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+ // 记录所有路径
+ vector> res;
+
+public:
+ vector> allPathsSourceTarget(vector>& graph) {
+ deque path;
+ traverse(graph, 0, path);
+ return res;
+ }
+
+ /* 图的遍历框架 */
+ void traverse(vector>& graph, int s, deque& path) {
+
+ // 添加节点 s 到路径
+ path.push_back(s);
+
+ int n = graph.size();
+ if (s == n - 1) {
+ // 到达终点
+ res.push_back(vector(path.begin(), path.end()));
+ path.pop_back();
+ return;
+ }
+
+ // 递归每个相邻节点
+ for (int v : graph[s]) {
+ traverse(graph, v, path);
+ }
+
+ // 从路径移出节点 s
+ path.pop_back();
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func allPathsSourceTarget(graph [][]int) [][]int {
+ // 记录所有路径
+ res := [][]int{}
+ var traverse func(graph [][]int, s int, path []int)
+
+ traverse = func(graph [][]int, s int, path []int) {
+ // 添加节点 s 到路径
+ path = append(path, s)
+
+ n := len(graph)
+ if s == n-1 {
+ // 到达终点
+ tmp := make([]int, len(path))
+ copy(tmp, path)
+ res = append(res, tmp)
+ path = path[:len(path)-1]
+ return
+ }
+
+ // 递归每个相邻节点
+ for _, v := range graph[s] {
+ traverse(graph, v, path)
+ }
+
+ // 从路径移出节点 s
+ path = path[:len(path)-1]
+ }
+
+ path := make([]int, 0)
+ traverse(graph, 0, path)
+ return res
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ // 记录所有路径
+ List> res = new LinkedList<>();
+
+ public List> allPathsSourceTarget(int[][] graph) {
+ LinkedList path = new LinkedList<>();
+ traverse(graph, 0, path);
+ return res;
+ }
+
+ /* 图的遍历框架 */
+ void traverse(int[][] graph, int s, LinkedList path) {
+
+ // 添加节点 s 到路径
+ path.addLast(s);
+
+ int n = graph.length;
+ if (s == n - 1) {
+ // 到达终点
+ res.add(new LinkedList<>(path));
+ path.removeLast();
+ return;
+ }
+
+ // 递归每个相邻节点
+ for (int v : graph[s]) {
+ traverse(graph, v, path);
+ }
+
+ // 从路径移出节点 s
+ path.removeLast();
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var allPathsSourceTarget = function(graph) {
+ // 记录所有路径
+ let res = [];
+
+ let traverse = function(graph, s, path) {
+ // 添加节点 s 到路径
+ path.push(s);
+
+ let n = graph.length;
+ if (s == n - 1) {
+ // 到达终点
+ res.push([...path]);
+ path.pop();
+ return;
+ }
+
+ // 递归每个相邻节点
+ for (let v of graph[s]) {
+ traverse(graph, v, path);
+ }
+
+ // 从路径移出节点 s
+ path.pop();
+ };
+
+ let path = [];
+ traverse(graph, 0, path);
+
+ return res;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ # 记录所有路径
+ res = []
+
+ def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
+ path = []
+ self.traverse(graph, 0, path)
+ return self.res
+
+ # 图的遍历框架
+ def traverse(self, graph: List[List[int]], s: int, path: List[int]) -> None:
+
+ # 添加节点 s 到路径
+ path.append(s)
+
+ n = len(graph)
+ if s == n - 1:
+ # 到达终点
+ self.res.append(path[:])
+ path.pop()
+ return
+
+ # 递归每个相邻节点
+ for v in graph[s]:
+ self.traverse(graph, v, path)
+
+ # 从路径移出节点 s
+ path.pop()
+```
+
+https://leetcode.cn/problems/bP4bmD 的多语言解法👆
+
+https://leetcode.cn/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int translateNum(int num) {
+ string s = to_string(num);
+ int n = s.length();
+ if (n < 1) {
+ return 0;
+ }
+ // 定义:dp[i] 表示 s[0..i-1] 的解码方式数量
+ vector dp(n + 1);
+ // base case: s 为空或者 s 只有一个字符的情况
+ dp[0] = 1;
+ dp[1] = 1;
+
+ // 注意 dp 数组和 s 之间的索引偏移一位
+ for (int i = 2; i <= n; i++) {
+ char c = s[i - 1], d = s[i - 2];
+ if ('0' <= c && c <= '9') {
+ // 1. s[i] 本身可以作为一个字母
+ dp[i] += dp[i - 1];
+ }
+ if (d == '1' || d == '2' && c <= '5') {
+ // 2. s[i] 和 s[i - 1] 结合起来表示一个字母
+ dp[i] += dp[i - 2];
+ }
+ }
+ return dp[n];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func translateNum(num int) int {
+ s := strconv.Itoa(num)
+ n := len(s)
+ if n < 1 {
+ return 0
+ }
+ // 定义:dp[i] 表示 s[0..i-1] 的解码方式数量
+ dp := make([]int, n+1)
+ // base case: s 为空或者 s 只有一个字符的情况
+ dp[0] = 1
+ dp[1] = 1
+
+ // 注意 dp 数组和 s 之间的索引偏移一位
+ for i := 2; i <= n; i++ {
+ c, d := s[i-1], s[i-2]
+ if '0' <= c && c <= '9' {
+ // 1. s[i] 本身可以作为一个字母
+ dp[i] += dp[i-1]
+ }
+ if (d == '1' || (d == '2' && c <= '5')) {
+ // 2. s[i] 和 s[i - 1] 结合起来表示一个字母
+ dp[i] += dp[i-2]
+ }
+ }
+ return dp[n]
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int translateNum(int num) {
+ String s = num + "";
+ int n = s.length();
+ if (n < 1) {
+ return 0;
+ }
+ // 定义:dp[i] 表示 s[0..i-1] 的解码方式数量
+ int[] dp = new int[n + 1];
+ // base case: s 为空或者 s 只有一个字符的情况
+ dp[0] = 1;
+ dp[1] = 1;
+
+ // 注意 dp 数组和 s 之间的索引偏移一位
+ for (int i = 2; i <= n; i++) {
+ char c = s.charAt(i - 1), d = s.charAt(i - 2);
+ if ('0' <= c && c <= '9') {
+ // 1. s[i] 本身可以作为一个字母
+ dp[i] += dp[i - 1];
+ }
+ if (d == '1' || d == '2' && c <= '5') {
+ // 2. s[i] 和 s[i - 1] 结合起来表示一个字母
+ dp[i] += dp[i - 2];
+ }
+ }
+ return dp[n];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var translateNum = function(num) {
+ var s = num.toString();
+ var n = s.length;
+ if (n < 1) {
+ return 0;
+ }
+ // 定义:dp[i] 表示 s[0..i-1] 的解码方式数量
+ var dp = new Array(n + 1).fill(0);
+ // base case: s 为空或者 s 只有一个字符的情况
+ dp[0] = 1;
+ dp[1] = 1;
+
+ // 注意 dp 数组和 s 之间的索引偏移一位
+ for (var i = 2; i <= n; i++) {
+ var c = s.charAt(i - 1), d = s.charAt(i - 2);
+ if ('0' <= c && c <= '9') {
+ // 1. s[i] 本身可以作为一个字母
+ dp[i] += dp[i - 1];
+ }
+ if (d == '1' || d == '2' && c <= '5') {
+ // 2. s[i] 和 s[i - 1] 结合起来表示一个字母
+ dp[i] += dp[i - 2];
+ }
+ }
+ return dp[n];
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def translateNum(self, num: int) -> int:
+ s = str(num)
+ n = len(s)
+ if n < 1:
+ return 0
+ # 定义:dp[i] 表示 s[0..i-1] 的解码方式数量
+ dp = [0] * (n + 1)
+ # base case: s 为空或者 s 只有一个字符的情况
+ dp[0] = 1
+ dp[1] = 1
+
+ # 注意 dp 数组和 s 之间的索引偏移一位
+ for i in range(2, n + 1):
+ c = s[i - 1]
+ d = s[i - 2]
+ if '0' <= c <= '9':
+ # 1. s[i] 本身可以作为一个字母
+ dp[i] += dp[i - 1]
+ if d == '1' or (d == '2' and c <= '5'):
+ # 2. s[i] 和 s[i - 1] 结合起来表示一个字母
+ dp[i] += dp[i - 2]
+ return dp[n]
+```
+
+https://leetcode.cn/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof 的多语言解法👆
+
+https://leetcode.cn/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ string minNumber(vector& nums) {
+ int n = nums.size();
+ vector strs(n);
+ for (int i = 0; i < n; i++) {
+ strs[i] = to_string(nums[i]);
+ }
+ sort(strs.begin(), strs.end(), [](const string& s1, const string& s2) {
+ // 看看那种拼接方式得到的数字更小,排前面
+ // 不用转成 int 类型,因为字符串的比较算法和正整数的比较算法是一样的
+ // 而且拼接字符串比较长,会导致 int 类型溢出
+ return (s1 + s2) < (s2 + s1);
+ });
+
+ return accumulate(strs.begin(), strs.end(), string(""));
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func minNumber(nums []int) string {
+ n := len(nums)
+ strs := make([]string, n)
+ for i := 0; i < n; i++ {
+ strs[i] = strconv.Itoa(nums[i])
+ }
+ sort.Slice(strs, func(i, j int) bool {
+ // 看看那种拼接方式得到的数字更小,排前面
+ // 不用转成 int 类型,因为字符串的比较算法和正整数的比较算法是一样的
+ // 而且拼接字符串比较长,会导致 int 类型溢出
+ return strs[i]+strs[j] < strs[j]+strs[i]
+ })
+
+ return strings.Join(strs, "")
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public String minNumber(int[] nums) {
+ int n = nums.length;
+ String[] strs = new String[n];
+ for (int i = 0; i < n; i++) {
+ strs[i] = Integer.toString(nums[i]);
+ }
+ Arrays.sort(strs, (s1, s2) -> {
+ // 看看那种拼接方式得到的数字更小,排前面
+ // 不用转成 int 类型,因为字符串的比较算法和正整数的比较算法是一样的
+ // 而且拼接字符串比较长,会导致 int 类型溢出
+ return (s1 + s2).compareTo(s2 + s1);
+ });
+
+ return String.join("", strs);
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var minNumber = function(nums) {
+ const n = nums.length;
+ const strs = new Array(n);
+ for (let i = 0; i < n; i++) {
+ strs[i] = nums[i].toString();
+ }
+ strs.sort((s1, s2) => {
+ // 看看那种拼接方式得到的数字更小,排前面
+ // 不用转成 int 类型,因为字符串的比较算法和正整数的比较算法是一样的
+ // 而且拼接字符串比较长,会导致 int 类型溢出
+ return (s1 + s2).localeCompare(s2 + s1);
+ });
+
+ return strs.join("");
+}
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def minNumber(self, nums: List[int]) -> str:
+ n = len(nums)
+ strs = [str(num) for num in nums]
+
+ def compare(s1: str, s2: str) -> int:
+ # 看看那种拼接方式得到的数字更小,排前面
+ # 不用转成 int 类型,因为字符串的比较算法和正整数的比较算法是一样的
+ # 而且拼接字符串比较长,会导致 int 类型溢出
+ return -1 if s1 + s2 < s2 + s1 else 1
+
+ strs.sort(key=functools.cmp_to_key(compare))
+
+ return ''.join(strs)
+```
+
+https://leetcode.cn/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof 的多语言解法👆
+
+https://leetcode.cn/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int myAtoi(string str) {
+ int n = str.length();
+ int i = 0;
+ // 记录正负号
+ int sign = 1;
+ // 用 long 避免 int 溢出
+ long res = 0;
+ // 跳过前导空格
+ while (i < n && str[i] == ' ') {
+ i++;
+ }
+ if (i == n) {
+ return 0;
+ }
+
+ // 记录符号位
+ if (str[i] == '-') {
+ sign = -1;
+ i++;
+ } else if (str[i] == '+') {
+ i++;
+ }
+ if (i == n) {
+ return 0;
+ }
+
+ // 统计数字位
+ while (i < n && '0' <= str[i] && str[i] <= '9') {
+ res = res * 10 + str[i] - '0';
+ if (res > INT_MAX) {
+ break;
+ }
+ i++;
+ }
+ // 如果溢出,强转成 int 就会和真实值不同
+ if ((int) res != res) {
+ return sign == 1 ? INT_MAX : INT_MIN;
+ }
+ return (int) res * sign;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func myAtoi(str string) int {
+ n := len(str)
+ i := 0
+ // 记录正负号
+ sign := 1
+ // 用 long 避免 int 溢出
+ var res int64 = 0
+ // 跳过前导空格
+ for i < n && str[i] == ' ' {
+ i++
+ }
+ if i == n {
+ return 0
+ }
+
+ // 记录符号位
+ if str[i] == '-' {
+ sign = -1
+ i++
+ } else if str[i] == '+' {
+ i++
+ }
+ if i == n {
+ return 0
+ }
+
+ // 统计数字位
+ for i < n && '0' <= str[i] && str[i] <= '9' {
+ res = res * 10 + int64(str[i]-'0')
+ if res > math.MaxInt32 {
+ break
+ }
+ i++
+ }
+ // 如果溢出,强转成 int 就会和真实值不同
+ if int(res) != res {
+ if sign == 1 {
+ return math.MaxInt32
+ } else {
+ return math.MinInt32
+ }
+ }
+ return int(res) * sign
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int myAtoi(String str) {
+ int n = str.length();
+ int i = 0;
+ // 记录正负号
+ int sign = 1;
+ // 用 long 避免 int 溢出
+ long res = 0;
+ // 跳过前导空格
+ while (i < n && str.charAt(i) == ' ') {
+ i++;
+ }
+ if (i == n) {
+ return 0;
+ }
+
+ // 记录符号位
+ if (str.charAt(i) == '-') {
+ sign = -1;
+ i++;
+ } else if (str.charAt(i) == '+') {
+ i++;
+ }
+ if (i == n) {
+ return 0;
+ }
+
+ // 统计数字位
+ while (i < n && '0' <= str.charAt(i) && str.charAt(i) <= '9') {
+ res = res * 10 + str.charAt(i) - '0';
+ if (res > Integer.MAX_VALUE) {
+ break;
+ }
+ i++;
+ }
+ // 如果溢出,强转成 int 就会和真实值不同
+ if ((int) res != res) {
+ return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
+ }
+ return (int) res * sign;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var myAtoi = function(str) {
+ let n = str.length;
+ let i = 0;
+ // 记录正负号
+ let sign = 1;
+ // 用 BigInt 避免 int 溢出
+ let res = BigInt(0);
+ // 跳过前导空格
+ while (i < n && str[i] === ' ') {
+ i++;
+ }
+ if (i === n) {
+ return 0;
+ }
+
+ // 记录符号位
+ if (str[i] === '-') {
+ sign = -1;
+ i++;
+ } else if (str[i] === '+') {
+ i++;
+ }
+ if (i === n) {
+ return 0;
+ }
+
+ // 统计数字位
+ while (i < n && '0' <= str[i] && str[i] <= '9') {
+ res = res * BigInt(10) + BigInt(str[i].charCodeAt() - '0'.charCodeAt());
+ if (res > BigInt(Number.MAX_VALUE)) {
+ break;
+ }
+ i++;
+ }
+ // 如果溢出,强转成 int 就会和真实值不同
+ if (res > BigInt(Number.MAX_VALUE)) {
+ return sign === 1 ? Number.MAX_VALUE : Number.MIN_VALUE;
+ }
+ return Number(res) * sign;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def myAtoi(self, s: str) -> int:
+ n = len(s)
+ i = 0
+ # 记录正负号
+ sign = 1
+ # 用 long 避免 int 溢出
+ res = 0
+ # 跳过前导空格
+ while i < n and s[i] == ' ':
+ i += 1
+ if i == n:
+ return 0
+
+ # 记录符号位
+ if s[i] == '-':
+ sign = -1
+ i += 1
+ elif s[i] == '+':
+ i += 1
+ if i == n:
+ return 0
+
+ # 统计数字位
+ while i < n and '0' <= s[i] <= '9':
+ res = res * 10 + ord(s[i]) - ord('0')
+ if res > pow(2, 31) - 1:
+ break
+ i += 1
+ # 如果溢出,强转成 int 就会和真实值不同
+ if res != int(res):
+ return sign == 1 and pow(2, 31) - 1 or -pow(2, 31)
+ return int(res) * sign
+```
+
+https://leetcode.cn/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof 的多语言解法👆
+
+https://leetcode.cn/problems/bao-han-minhan-shu-de-zhan-lcof 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+// 原始思路
+class MinStack1 {
+ // 记录栈中的所有元素
+ stack stk;
+ // 阶段性记录栈中的最小元素
+ stack minStk;
+
+public:
+ void push(int val) {
+ stk.push(val);
+ // 维护 minStk 栈顶为全栈最小元素
+ if (minStk.empty() || val <= minStk.top()) {
+ // 新插入的这个元素就是全栈最小的
+ minStk.push(val);
+ }
+ else {
+ // 插入的这个元素比较大
+ minStk.push(minStk.top());
+ }
+ }
+
+ void pop() {
+ stk.pop();
+ minStk.pop();
+ }
+
+ int top() {
+ return stk.top();
+ }
+
+ int getMin() {
+ // minStk 栈顶为全栈最小元素
+ return minStk.top();
+ }
+};
+// 优化版
+class MinStack {
+ // 记录栈中的所有元素
+ stack stk;
+ // 阶段性记录栈中的最小元素
+ stack minStk;
+
+public:
+ void push(int val) {
+ stk.push(val);
+ // 维护 minStk 栈顶为全栈最小元素
+ if (minStk.empty() || val <= minStk.top()) {
+ // 新插入的这个元素就是全栈最小的
+ minStk.push(val);
+ }
+ }
+
+ void pop() {
+ // 注意 Java 的语言特性,比较 Integer 相等要用 equals 方法
+ if (stk.top() == minStk.top()) {
+ // 弹出的元素是全栈最小的
+ minStk.pop();
+ }
+ stk.pop();
+ }
+
+ int top() {
+ return stk.top();
+ }
+
+ int getMin() {
+ // minStk 栈顶为全栈最小元素
+ return minStk.top();
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+type MinStack1 struct {
+ stk []int
+ minStk []int
+}
+
+func (this *MinStack1) Push(val int) {
+ this.stk = append(this.stk, val)
+ // 维护 minStk 栈顶为全栈最小元素
+ if len(this.minStk) == 0 || val <= this.minStk[len(this.minStk)-1] {
+ // 新插入的这个元素就是全栈最小的
+ this.minStk = append(this.minStk, val)
+ } else {
+ // 插入的这个元素比较大
+ this.minStk = append(this.minStk, this.minStk[len(this.minStk)-1])
+ }
+}
+
+func (this *MinStack1) Pop() {
+ this.stk = this.stk[:len(this.stk)-1]
+ this.minStk = this.minStk[:len(this.minStk)-1]
+}
+
+func (this *MinStack1) Top() int {
+ return this.stk[len(this.stk)-1]
+}
+
+func (this *MinStack1) GetMin() int {
+ // minStk 栈顶为全栈最小元素
+ return this.minStk[len(this.minStk)-1]
+}
+
+type MinStack struct {
+ stk []int
+ minStk []int
+}
+
+func (this *MinStack) Push(val int) {
+ this.stk = append(this.stk, val)
+ // 维护 minStk 栈顶为全栈最小元素
+ if len(this.minStk) == 0 || val <= this.minStk[len(this.minStk)-1] {
+ // 新插入的这个元素就是全栈最小的
+ this.minStk = append(this.minStk, val)
+ }
+}
+
+func (this *MinStack) Pop() {
+ // 注意 go 的语言特性,比较 int 相等可以直接使用 ==
+ if this.stk[len(this.stk)-1] == this.minStk[len(this.minStk)-1] {
+ // 弹出的元素是全栈最小的
+ this.minStk = this.minStk[:len(this.minStk)-1]
+ }
+ this.stk = this.stk[:len(this.stk)-1]
+}
+
+func (this *MinStack) Top() int {
+ return this.stk[len(this.stk)-1]
+}
+
+func (this *MinStack) GetMin() int {
+ // minStk 栈顶为全栈最小元素
+ return this.minStk[len(this.minStk)-1]
+}
+```
+
+```java
+// by labuladong (java)
+// 原始思路
+class MinStack1 {
+ // 记录栈中的所有元素
+ Stack stk = new Stack<>();
+ // 阶段性记录栈中的最小元素
+ Stack minStk = new Stack<>();
+
+ public void push(int val) {
+ stk.push(val);
+ // 维护 minStk 栈顶为全栈最小元素
+ if (minStk.isEmpty() || val <= minStk.peek()) {
+ // 新插入的这个元素就是全栈最小的
+ minStk.push(val);
+ } else {
+ // 插入的这个元素比较大
+ minStk.push(minStk.peek());
+ }
+ }
+
+ public void pop() {
+ stk.pop();
+ minStk.pop();
+ }
+
+ public int top() {
+ return stk.peek();
+ }
+
+ public int getMin() {
+ // minStk 栈顶为全栈最小元素
+ return minStk.peek();
+ }
+}
+// 优化版
+class MinStack {
+ // 记录栈中的所有元素
+ Stack stk = new Stack<>();
+ // 阶段性记录栈中的最小元素
+ Stack minStk = new Stack<>();
+
+ public void push(int val) {
+ stk.push(val);
+ // 维护 minStk 栈顶为全栈最小元素
+ if (minStk.isEmpty() || val <= minStk.peek()) {
+ // 新插入的这个元素就是全栈最小的
+ minStk.push(val);
+ }
+ }
+
+ public void pop() {
+ // 注意 Java 的语言特性,比较 Integer 相等要用 equals 方法
+ if (stk.peek().equals(minStk.peek())) {
+ // 弹出的元素是全栈最小的
+ minStk.pop();
+ }
+ stk.pop();
+ }
+
+ public int top() {
+ return stk.peek();
+ }
+
+ public int getMin() {
+ // minStk 栈顶为全栈最小元素
+ return minStk.peek();
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+/**
+ * @constructor
+ */
+var MinStack1 = function() {
+ // 记录栈中的所有元素
+ this.stk = [];
+ // 阶段性记录栈中的最小元素
+ this.minStk = [];
+};
+
+/**
+ * @param {number} val
+ * @return {void}
+ */
+MinStack1.prototype.push = function(val) {
+ this.stk.push(val);
+ // 维护 minStk 栈顶为全栈最小元素
+ if (this.minStk.length === 0 || val <= this.minStk[this.minStk.length - 1]) {
+ // 新插入的这个元素就是全栈最小的
+ this.minStk.push(val);
+ } else {
+ // 插入的这个元素比较大
+ this.minStk.push(this.minStk[this.minStk.length - 1]);
+ }
+};
+
+/**
+ * @return {void}
+ */
+MinStack1.prototype.pop = function() {
+ this.stk.pop();
+ this.minStk.pop();
+};
+
+/**
+ * @return {number}
+ */
+MinStack1.prototype.top = function() {
+ return this.stk[this.stk.length - 1];
+};
+
+/**
+ * @return {number}
+ */
+MinStack1.prototype.getMin = function() {
+ // minStk 栈顶为全栈最小元素
+ return this.minStk[this.minStk.length - 1];
+};
+
+/**
+ * @constructor
+ */
+var MinStack = function() {
+ // 记录栈中的所有元素
+ this.stk = [];
+ // 阶段性记录栈中的最小元素
+ this.minStk = [];
+};
+
+/**
+ * @param {number} val
+ * @return {void}
+ */
+MinStack.prototype.push = function(val) {
+ this.stk.push(val);
+ // 维护 minStk 栈顶为全栈最小元素
+ if (this.minStk.length === 0 || val <= this.minStk[this.minStk.length - 1]) {
+ // 新插入的这个元素就是全栈最小的
+ this.minStk.push(val);
+ }
+};
+
+/**
+ * @return {void}
+ */
+MinStack.prototype.pop = function() {
+ // 注意 JavaScript 的语言特性,比较 Number 可以直接使用 ===
+ if (this.stk[this.stk.length - 1] === this.minStk[this.minStk.length - 1]) {
+ // 弹出的元素是全栈最小的
+ this.minStk.pop();
+ }
+ this.stk.pop();
+};
+
+/**
+ * @return {number}
+ */
+MinStack.prototype.top = function() {
+ return this.stk[this.stk.length - 1];
+};
+
+/**
+ * @return {number}
+ */
+MinStack.prototype.getMin = function() {
+ // minStk 栈顶为全栈最小元素
+ return this.minStk[this.minStk.length - 1];
+};
+```
+
+```python
+# by chatGPT (python)
+# 原始思路
+class MinStack1:
+ def __init__(self):
+ # 记录栈中的所有元素
+ self.stk = []
+ # 阶段性记录栈中的最小元素
+ self.minStk = []
+
+ def push(self, val: int) -> None:
+ self.stk.append(val)
+ # 维护 minStk 栈顶为全栈最小元素
+ if not self.minStk or val <= self.minStk[-1]:
+ # 新插入的这个元素就是全栈最小的
+ self.minStk.append(val)
+ else:
+ # 插入的这个元素比较大
+ self.minStk.append(self.minStk[-1])
+
+ def pop(self) -> None:
+ self.stk.pop()
+ self.minStk.pop()
+
+ def top(self) -> int:
+ return self.stk[-1]
+
+ def getMin(self) -> int:
+ # minStk 栈顶为全栈最小元素
+ return self.minStk[-1]
+
+
+# 优化版
+class MinStack:
+ def __init__(self):
+ # 记录栈中的所有元素
+ self.stk = []
+ # 阶段性记录栈中的最小元素
+ self.minStk = []
+
+ def push(self, val: int) -> None:
+ self.stk.append(val)
+ # 维护 minStk 栈顶为全栈最小元素
+ if not self.minStk or val <= self.minStk[-1]:
+ # 新插入的这个元素就是全栈最小的
+ self.minStk.append(val)
+
+ def pop(self) -> None:
+ # 注意 Python 的语言特性,比较 Integer 相等不需要调用 equals 方法
+ if self.stk[-1] == self.minStk[-1]:
+ # 弹出的元素是全栈最小的
+ self.minStk.pop()
+ self.stk.pop()
+
+ def top(self) -> int:
+ return self.stk[-1]
+
+ def getMin(self) -> int:
+ # minStk 栈顶为全栈最小元素
+ return self.minStk[-1]
+```
+
+https://leetcode.cn/problems/bao-han-minhan-shu-de-zhan-lcof 的多语言解法👆
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int maxProfit(vector& prices) {
+ int n = prices.size();
+ vector> dp(n, vector(2));
+ for (int i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = max(dp[i - 1][1], -prices[i]);
+ }
+ return dp[n - 1][0];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func maxProfit(prices []int) int {
+ n := len(prices)
+ dp := make([][]int, n)
+ for i := 0; i < n; i++ {
+ dp[i] = make([]int, 2)
+ if i - 1 == -1 {
+ // base case
+ dp[i][0] = 0
+ dp[i][1] = -prices[i]
+ continue
+ }
+ dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
+ dp[i][1] = max(dp[i-1][1], -prices[i])
+ }
+ return dp[n-1][0]
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int maxProfit(int[] prices) {
+ int n = prices.length;
+ int[][] dp = new int[n][2];
+ for (int i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);
+ }
+ return dp[n - 1][0];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+/**
+ * @param {number[]} prices
+ * @return {number}
+ */
+var maxProfit = function(prices) {
+ const n = prices.length;
+ const dp = new Array(n).map(() => new Array(2));
+ for (let i = 0; i < n; i++) {
+ if (i - 1 === -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);
+ }
+ return dp[n - 1][0];
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def maxProfit(self, prices: List[int]) -> int:
+ n = len(prices)
+ dp = [[0] * 2 for _ in range(n)]
+ for i in range(n):
+ if i - 1 == -1:
+ # base case
+ dp[i][0] = 0
+ dp[i][1] = -prices[i]
+ continue
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])
+ dp[i][1] = max(dp[i - 1][1], -prices[i])
+ return dp[n - 1][0]
+```
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock 的多语言解法👆
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int maxProfit(vector& prices) {
+ int n = prices.size();
+ vector> dp(n, vector(2));
+ for (int i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
+ }
+ return dp[n - 1][0];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func maxProfit(prices []int) int {
+ n := len(prices)
+ dp := make([][]int, n)
+ for i := 0; i < n; i++ {
+ dp[i] = make([]int, 2)
+ if i-1 == -1 {
+ // base case
+ dp[i][0] = 0
+ dp[i][1] = -prices[i]
+ continue
+ }
+ dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
+ dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i])
+ }
+ return dp[n-1][0]
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int maxProfit(int[] prices) {
+ int n = prices.length;
+ int[][] dp = new int[n][2];
+ for (int i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
+ }
+ return dp[n - 1][0];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var maxProfit = function(prices) {
+ const n = prices.length;
+ const dp = new Array(n).fill(0).map(() => new Array(2).fill(0));
+ for (let i = 0; i < n; i++) {
+ if (i - 1 === -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
+ }
+ return dp[n - 1][0];
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def maxProfit(self, prices: List[int]) -> int:
+ n = len(prices)
+ dp = [[0] * 2 for _ in range(n)]
+ for i in range(n):
+ if i - 1 == -1:
+ dp[i][0] = 0
+ dp[i][1] = -prices[i]
+ continue
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])
+ dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])
+ return dp[n - 1][0]
+```
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii 的多语言解法👆
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int maxProfit(vector& prices) {
+ int max_k = 2, n = prices.size();
+ int dp[n][max_k + 1][2];
+ for (int i = 0; i < n; i++) {
+ for (int k = max_k; k >= 1; k--) {
+ if (i - 1 == -1) {
+ // 处理 base case
+ dp[i][k][0] = 0;
+ dp[i][k][1] = -prices[i];
+ continue;
+ }
+ dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]);
+ dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]);
+ }
+ }
+ // 穷举了 n × max_k × 2 个状态,正确。
+ return dp[n - 1][max_k][0];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func maxProfit(prices []int) int {
+ max_k, n := 2, len(prices)
+ dp := make([][][]int, n)
+ for i := range dp {
+ dp[i] = make([][]int, max_k+1)
+ for j := range dp[i] {
+ dp[i][j] = make([]int, 2)
+ }
+ }
+ for i := 0; i < n; i++ {
+ for k := max_k; k >= 1; k-- {
+ if i-1 == -1 {
+ // 处理 base case
+ dp[i][k][0] = 0
+ dp[i][k][1] = -prices[i]
+ continue
+ }
+ dp[i][k][0] = func() int {
+ if dp[i-1][k][0] > dp[i-1][k][1]+prices[i] {
+ return dp[i-1][k][0]
+ }
+ return dp[i-1][k][1] + prices[i]
+ }()
+ dp[i][k][1] = func() int {
+ if dp[i-1][k][1] > dp[i-1][k-1][0]-prices[i] {
+ return dp[i-1][k][1]
+ }
+ return dp[i-1][k-1][0] - prices[i]
+ }()
+ }
+ }
+ // 穷举了 n × max_k × 2 个状态,正确。
+ return dp[n-1][max_k][0]
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int maxProfit(int[] prices) {
+ int max_k = 2, n = prices.length;
+ int[][][] dp = new int[n][max_k + 1][2];
+ for (int i = 0; i < n; i++) {
+ for (int k = max_k; k >= 1; k--) {
+ if (i - 1 == -1) {
+ // 处理 base case
+ dp[i][k][0] = 0;
+ dp[i][k][1] = -prices[i];
+ continue;
+ }
+ dp[i][k][0] = Math.max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]);
+ dp[i][k][1] = Math.max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]);
+ }
+ }
+ // 穷举了 n × max_k × 2 个状态,正确。
+ return dp[n - 1][max_k][0];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var maxProfit = function(prices) {
+ let max_k = 2, n = prices.length;
+ let dp = Array(n).fill().map(() => Array(max_k + 1).fill().map(() => Array(2).fill(0)));
+ for (let i = 0; i < n; i++) {
+ for (let k = max_k; k >= 1; k--) {
+ if (i - 1 == -1) {
+ // 处理 base case
+ dp[i][k][0] = 0;
+ dp[i][k][1] = -prices[i];
+ continue;
+ }
+ dp[i][k][0] = Math.max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]);
+ dp[i][k][1] = Math.max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]);
+ }
+ }
+ // 穷举了 n × max_k × 2 个状态,正确。
+ return dp[n - 1][max_k][0];
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def maxProfit(self, prices: List[int]) -> int:
+ max_k = 2
+ n = len(prices)
+ dp = [[[0 for _ in range(2)] for _ in range(max_k + 1)] for _ in range(n)]
+ for i in range(n):
+ for k in range(max_k, 0, -1):
+ if i - 1 == -1:
+ # 处理 base case
+ dp[i][k][0] = 0
+ dp[i][k][1] = -prices[i]
+ continue
+ dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])
+ dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])
+ # 穷举了 n × max_k × 2 个状态,正确。
+ return dp[n - 1][max_k][0]
+```
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii 的多语言解法👆
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iv 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int maxProfit(int max_k, vector& prices) {
+ int n = prices.size();
+ if (n <= 0) {
+ return 0;
+ }
+ if (max_k > n / 2) {
+ // 交易次数 k 没有限制的情况
+ return maxProfit_k_inf(prices);
+ }
+
+ // base case:
+ // dp[-1][...][0] = dp[...][0][0] = 0
+ // dp[-1][...][1] = dp[...][0][1] = -infinity
+ vector>> dp(n, vector>(max_k + 1, vector(2)));
+ // k = 0 时的 base case
+ for (int i = 0; i < n; i++) {
+ dp[i][0][1] = INT_MIN;
+ dp[i][0][0] = 0;
+ }
+
+ for (int i = 0; i < n; i++) {
+ for (int k = max_k; k >= 1; k--) {
+ if (i - 1 == -1) {
+ // 处理 i = -1 时的 base case
+ dp[i][k][0] = 0;
+ dp[i][k][1] = -prices[i];
+ continue;
+ }
+ // 状态转移方程
+ dp[i][k][0] = max(dp[i - 1][k][0], dp[i - 1][k][1] + prices[i]);
+ dp[i][k][1] = max(dp[i - 1][k][1], dp[i - 1][k - 1][0] - prices[i]);
+ }
+ }
+ return dp[n - 1][max_k][0];
+ }
+
+private:
+ // 第 122 题,k 无限的解法
+ int maxProfit_k_inf(vector& prices) {
+ int n = prices.size();
+ vector> dp(n, vector(2));
+ for (int i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
+ }
+ return dp[n - 1][0];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func maxProfit(max_k int, prices []int) int {
+ n := len(prices)
+ if n <= 0 {
+ return 0
+ }
+ if max_k > n/2 {
+ // 交易次数 k 没有限制的情况
+ return maxProfitKInf(prices)
+ }
+
+ // base case:
+ // dp[-1][...][0] = dp[...][0][0] = 0
+ // dp[-1][...][1] = dp[...][0][1] = -infinity
+ dp := make([][][]int, n)
+ for i := 0; i < n; i++ {
+ dp[i] = make([][]int, max_k+1)
+ for k := 0; k <= max_k; k++ {
+ dp[i][k] = make([]int, 2)
+ }
+ }
+
+ // k = 0 时的 base case
+ for i := 0; i < n; i++ {
+ dp[i][0][1] = -1 << 31
+ dp[i][0][0] = 0
+ }
+
+ for i := 0; i < n; i++ {
+ for k := max_k; k >= 1; k-- {
+ if i-1 == -1 {
+ // 处理 i = -1 时的 base case
+ dp[i][k][0] = 0
+ dp[i][k][1] = -prices[i]
+ continue
+ }
+ // 状态转移方程
+ dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1]+prices[i])
+ dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0]-prices[i])
+ }
+ }
+ return dp[n-1][max_k][0]
+}
+
+// 第 122 题,k 无限的解法
+func maxProfitKInf(prices []int) int {
+ n := len(prices)
+ dp := make([][]int, n)
+ for i := 0; i < n; i++ {
+ dp[i] = make([]int, 2)
+ }
+
+ for i := 0; i < n; i++ {
+ if i-1 == -1 {
+ // base case
+ dp[i][0] = 0
+ dp[i][1] = -prices[i]
+ continue
+ }
+ dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
+ dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i])
+ }
+ return dp[n-1][0]
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int maxProfit(int max_k, int[] prices) {
+ int n = prices.length;
+ if (n <= 0) {
+ return 0;
+ }
+ if (max_k > n / 2) {
+ // 交易次数 k 没有限制的情况
+ return maxProfit_k_inf(prices);
+ }
+
+ // base case:
+ // dp[-1][...][0] = dp[...][0][0] = 0
+ // dp[-1][...][1] = dp[...][0][1] = -infinity
+ int[][][] dp = new int[n][max_k + 1][2];
+ // k = 0 时的 base case
+ for (int i = 0; i < n; i++) {
+ dp[i][0][1] = Integer.MIN_VALUE;
+ dp[i][0][0] = 0;
+ }
+
+ for (int i = 0; i < n; i++)
+ for (int k = max_k; k >= 1; k--) {
+ if (i - 1 == -1) {
+ // 处理 i = -1 时的 base case
+ dp[i][k][0] = 0;
+ dp[i][k][1] = -prices[i];
+ continue;
+ }
+ // 状态转移方程
+ dp[i][k][0] = Math.max(dp[i - 1][k][0], dp[i - 1][k][1] + prices[i]);
+ dp[i][k][1] = Math.max(dp[i - 1][k][1], dp[i - 1][k - 1][0] - prices[i]);
+ }
+ return dp[n - 1][max_k][0];
+ }
+
+ // 第 122 题,k 无限的解法
+ private int maxProfit_k_inf(int[] prices) {
+ int n = prices.length;
+ int[][] dp = new int[n][2];
+ for (int i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
+ }
+ return dp[n - 1][0];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var maxProfit = function(max_k, prices) {
+ var n = prices.length;
+ if (n <= 0) {
+ return 0;
+ }
+ if (max_k > Math.floor(n / 2)) {
+ // 交易次数 k 没有限制的情况
+ return maxProfit_k_inf(prices);
+ }
+
+ // base case:
+ // dp[-1][...][0] = dp[...][0][0] = 0
+ // dp[-1][...][1] = dp[...][0][1] = -infinity
+ var dp = new Array(n).fill(0).map(()=>new Array(max_k + 1).fill(0).map(()=>new Array(2).fill(0)));
+ // k = 0 时的 base case
+ for (var i = 0; i < n; i++) {
+ dp[i][0][1] = Number.NEGATIVE_INFINITY;
+ dp[i][0][0] = 0;
+ }
+
+ for (var i = 0; i < n; i++)
+ for (var k = max_k; k >= 1; k--) {
+ if (i - 1 == -1) {
+ // 处理 i = -1 时的 base case
+ dp[i][k][0] = 0;
+ dp[i][k][1] = -prices[i];
+ continue;
+ }
+ // 状态转移方程
+ dp[i][k][0] = Math.max(dp[i - 1][k][0], dp[i - 1][k][1] + prices[i]);
+ dp[i][k][1] = Math.max(dp[i - 1][k][1], dp[i - 1][k - 1][0] - prices[i]);
+ }
+ return dp[n - 1][max_k][0];
+}
+
+// 第 122 题,k 无限的解法
+var maxProfit_k_inf = function(prices) {
+ var n = prices.length;
+ var dp = new Array(n).fill(0).map(()=>new Array(2).fill(0));
+ for (var i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
+ }
+ return dp[n - 1][0];
+}
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def maxProfit(self, max_k: int, prices: List[int]) -> int:
+ n = len(prices)
+ if n <= 0:
+ return 0
+ if max_k > n // 2:
+ # 交易次数 k 没有限制的情况
+ return self.maxProfit_k_inf(prices)
+
+ # base case:
+ # dp[-1][...][0] = dp[...][0][0] = 0
+ # dp[-1][...][1] = dp[...][0][1] = -infinity
+ dp = [[[0] * 2 for _ in range(max_k + 1)] for _ in range(n)]
+ # k = 0 时的 base case
+ for i in range(n):
+ dp[i][0][1] = float('-inf')
+ dp[i][0][0] = 0
+
+ for i in range(n):
+ for k in range(max_k, 0, -1):
+ if i - 1 == -1:
+ # 处理 i = -1 时的 base case
+ dp[i][k][0] = 0
+ dp[i][k][1] = -prices[i]
+ continue
+ # 状态转移方程
+ dp[i][k][0] = max(dp[i - 1][k][0], dp[i - 1][k][1] + prices[i])
+ dp[i][k][1] = max(dp[i - 1][k][1], dp[i - 1][k - 1][0] - prices[i])
+ return dp[n - 1][max_k][0]
+
+ # 第 122 题,k 无限的解法
+ def maxProfit_k_inf(self, prices: List[int]) -> int:
+ n = len(prices)
+ dp = [[0] * 2 for _ in range(n)]
+ for i in range(n):
+ if i - 1 == -1:
+ # base case
+ dp[i][0] = 0
+ dp[i][1] = -prices[i]
+ continue
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])
+ dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])
+ return dp[n - 1][0]
+```
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iv 的多语言解法👆
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int maxProfit(vector& prices) {
+ int n = prices.size();
+ vector> dp(n, vector(2));
+ for (int i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case 1
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ if (i - 2 == -1) {
+ // base case 2
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ // i - 2 小于 0 时根据状态转移方程推出对应 base case
+ dp[i][1] = max(dp[i - 1][1], -prices[i]);
+ // dp[i][1]
+ // = max(dp[i-1][1], dp[-1][0] - prices[i])
+ // = max(dp[i-1][1], 0 - prices[i])
+ // = max(dp[i-1][1], -prices[i])
+ continue;
+ }
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = max(dp[i - 1][1], dp[i - 2][0] - prices[i]);
+ }
+ return dp[n - 1][0];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func maxProfit(prices []int) int {
+ n := len(prices)
+ dp := make([][2]int, n)
+ for i := 0; i < n; i++ {
+ if i-1 == -1 {
+ // base case 1
+ dp[i][0] = 0
+ dp[i][1] = -prices[i]
+ continue
+ }
+ if i-2 == -1 {
+ // base case 2
+ dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
+ // i - 2 小于 0 时根据状态转移方程推出对应 base case
+ dp[i][1] = max(dp[i-1][1], -prices[i])
+ // dp[i][1]
+ // = max(dp[i-1][1], dp[-1][0] - prices[i])
+ // = max(dp[i-1][1], 0 - prices[i])
+ // = max(dp[i-1][1], -prices[i])
+ continue
+ }
+ dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
+ dp[i][1] = max(dp[i-1][1], dp[i-2][0]-prices[i])
+ }
+ return dp[n-1][0]
+}
+
+func max(x, y int) int {
+ if x > y {
+ return x
+ }
+ return y
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int maxProfit(int[] prices) {
+ int n = prices.length;
+ int[][] dp = new int[n][2];
+ for (int i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case 1
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ if (i - 2 == -1) {
+ // base case 2
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ // i - 2 小于 0 时根据状态转移方程推出对应 base case
+ dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);
+ // dp[i][1]
+ // = max(dp[i-1][1], dp[-1][0] - prices[i])
+ // = max(dp[i-1][1], 0 - prices[i])
+ // = max(dp[i-1][1], -prices[i])
+ continue;
+ }
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 2][0] - prices[i]);
+ }
+ return dp[n - 1][0];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+/**
+ * @param {number[]} prices
+ * @return {number}
+ */
+var maxProfit = function(prices) {
+ let n = prices.length;
+ let dp = Array.from(Array(n), () => new Array(2).fill(0));
+ for (let i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case 1
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i];
+ continue;
+ }
+ if (i - 2 == -1) {
+ // base case 2
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ // i - 2 小于 0 时根据状态转移方程推出对应 base case
+ dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);
+ // dp[i][1]
+ // = max(dp[i-1][1], dp[-1][0] - prices[i])
+ // = max(dp[i-1][1], 0 - prices[i])
+ // = max(dp[i-1][1], -prices[i])
+ continue;
+ }
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 2][0] - prices[i]);
+ }
+ return dp[n - 1][0];
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def maxProfit(self, prices: List[int]) -> int:
+ n = len(prices)
+ dp = [[0]*2 for _ in range(n)]
+ for i in range(n):
+ if i - 1 == -1:
+ # base case 1
+ dp[i][0] = 0
+ dp[i][1] = -prices[i]
+ continue
+ if i - 2 == -1:
+ # base case 2
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])
+ # i - 2 小于 0 时根据状态转移方程推出对应 base case
+ dp[i][1] = max(dp[i - 1][1], -prices[i])
+ # dp[i][1]
+ # = max(dp[i-1][1], dp[-1][0] - prices[i])
+ # = max(dp[i-1][1], 0 - prices[i])
+ # = max(dp[i-1][1], -prices[i])
+ continue
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])
+ dp[i][1] = max(dp[i - 1][1], dp[i - 2][0] - prices[i])
+ return dp[n - 1][0]
+```
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown 的多语言解法👆
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-transaction-fee 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int maxProfit(vector& prices, int fee) {
+ int n = prices.size();
+ vector> dp(n, vector(2));
+ for (int i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i] - fee;
+ // dp[i][1]
+ // = max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee)
+ // = max(dp[-1][1], dp[-1][0] - prices[i] - fee)
+ // = max(-inf, 0 - prices[i] - fee)
+ // = -prices[i] - fee
+ continue;
+ }
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee);
+ }
+ return dp[n - 1][0];
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func maxProfit(prices []int, fee int) int {
+ n := len(prices)
+ dp := make([][2]int, n)
+ for i := 0; i < n; i++ {
+ if i-1 == -1 {
+ // base case
+ dp[i][0] = 0
+ dp[i][1] = -prices[i] - fee
+ // dp[i][1]
+ // = max(dp[i-1][1], dp[i-1][0]-prices[i]-fee)
+ // = max(dp[-1][1], dp[-1][0]-prices[i]-fee)
+ // = max(-inf, 0-prices[i]-fee)
+ // = -prices[i]-fee
+ continue
+ }
+ dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
+ dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]-fee)
+ }
+ return dp[n-1][0]
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int maxProfit(int[] prices, int fee) {
+ int n = prices.length;
+ int[][] dp = new int[n][2];
+ for (int i = 0; i < n; i++) {
+ if (i - 1 == -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i] - fee;
+ // dp[i][1]
+ // = max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee)
+ // = max(dp[-1][1], dp[-1][0] - prices[i] - fee)
+ // = max(-inf, 0 - prices[i] - fee)
+ // = -prices[i] - fee
+ continue;
+ }
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee);
+ }
+ return dp[n - 1][0];
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var maxProfit = function(prices, fee) {
+ const n = prices.length;
+ const dp = new Array(n).map(() => new Array(2).fill(0));
+ for (let i = 0; i < n; i++) {
+ if (i - 1 === -1) {
+ // base case
+ dp[i][0] = 0;
+ dp[i][1] = -prices[i] - fee;
+ // dp[i][1]
+ // = max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee)
+ // = max(dp[-1][1], dp[-1][0] - prices[i] - fee)
+ // = max(-inf, 0 - prices[i] - fee)
+ // = -prices[i] - fee
+ continue;
+ }
+ dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
+ dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee);
+ }
+ return dp[n - 1][0];
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def maxProfit(self, prices: List[int], fee: int) -> int:
+ n = len(prices)
+ dp = [[0]*2 for _ in range(n)]
+ for i in range(n):
+ if i - 1 == -1:
+ # base case
+ dp[i][0] = 0
+ dp[i][1] = -prices[i] - fee
+ # dp[i][1]
+ # = max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee)
+ # = max(dp[-1][1], dp[-1][0] - prices[i] - fee)
+ # = max(-inf, 0 - prices[i] - fee)
+ # = -prices[i] - fee
+ continue
+ dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])
+ dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee)
+ return dp[n - 1][0]
+```
+
+https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-transaction-fee 的多语言解法👆
+
+https://leetcode.cn/problems/binary-search 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ int search(vector& nums, int target) {
+ int left = 0;
+ int right = nums.size() - 1; // 注意
+
+ while (left <= right) {
+ int mid = left + (right - left) / 2;
+ if (nums[mid] == target)
+ return mid;
+ else if (nums[mid] < target)
+ left = mid + 1; // 注意
+ else if (nums[mid] > target)
+ right = mid - 1; // 注意
+ }
+ return -1;
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+func search(nums []int, target int) int {
+ left := 0
+ right := len(nums) - 1 // 注意
+
+ for left <= right {
+ mid := left + (right - left) / 2
+ if nums[mid] == target {
+ return mid
+ } else if nums[mid] < target {
+ left = mid + 1 // 注意
+ } else if nums[mid] > target {
+ right = mid - 1 // 注意
+ }
+ }
+ return -1
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public int search(int[] nums, int target) {
+ int left = 0;
+ int right = nums.length - 1; // 注意
+
+ while(left <= right) {
+ int mid = left + (right - left) / 2;
+ if(nums[mid] == target)
+ return mid;
+ else if (nums[mid] < target)
+ left = mid + 1; // 注意
+ else if (nums[mid] > target)
+ right = mid - 1; // 注意
+ }
+ return -1;
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+var search = function(nums, target) {
+ var left = 0;
+ var right = nums.length - 1; // 注意
+
+ while (left <= right) {
+ var mid = left + Math.floor((right - left) / 2);
+ if (nums[mid] == target)
+ return mid;
+ else if (nums[mid] < target)
+ left = mid + 1; // 注意
+ else if (nums[mid] > target)
+ right = mid - 1; // 注意
+ }
+ return -1;
+};
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def search(self, nums: List[int], target: int) -> int:
+ left = 0
+ right = len(nums) - 1 # 注意
+
+ while left <= right:
+ mid = left + (right - left) // 2
+ if nums[mid] == target:
+ return mid
+ elif nums[mid] < target:
+ left = mid + 1 # 注意
+ elif nums[mid] > target:
+ right = mid - 1 # 注意
+
+ return -1
+```
+
+https://leetcode.cn/problems/binary-search 的多语言解法👆
+
+https://leetcode.cn/problems/binary-search-tree-to-greater-sum-tree 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ TreeNode* bstToGst(TreeNode* root) {
+ traverse(root);
+ return root;
+ }
+
+ // 记录累加和
+ int sum = 0;
+ void traverse(TreeNode* root) {
+ if (root == nullptr) {
+ return;
+ }
+ traverse(root->right);
+ // 维护累加和
+ sum += root->val;
+ // 将 BST 转化成累加树
+ root->val = sum;
+ traverse(root->left);
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ * Val int
+ * Left *TreeNode
+ * Right *TreeNode
+ * }
+ */
+func bstToGst(root *TreeNode) *TreeNode {
+ var sum int
+ // 定义中序遍历函数,内部维护sum变量
+ var traverse func(node *TreeNode)
+ traverse = func(node *TreeNode) {
+ if node == nil {
+ return
+ }
+ traverse(node.Right)
+ // 维护累加和
+ sum += node.Val
+ // 将BST转化为累加树
+ node.Val = sum
+ traverse(node.Left)
+ }
+ traverse(root)
+ return root
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ public TreeNode bstToGst(TreeNode root) {
+ traverse(root);
+ return root;
+ }
+
+ // 记录累加和
+ int sum = 0;
+ void traverse(TreeNode root) {
+ if (root == null) {
+ return;
+ }
+ traverse(root.right);
+ // 维护累加和
+ sum += root.val;
+ // 将 BST 转化成累加树
+ root.val = sum;
+ traverse(root.left);
+ }
+}
+```
+
+```javascript
+// by chatGPT (javascript)
+/**
+ * @param {TreeNode} root
+ * @return {TreeNode}
+ */
+var bstToGst = function(root) {
+ traverse(root);
+ return root;
+}
+
+// 记录累加和
+let sum = 0;
+let traverse = function(root) {
+ if (root === null) {
+ return;
+ }
+ traverse(root.right);
+ // 维护累加和
+ sum += root.val;
+ // 将 BST 转化成累加树
+ root.val = sum;
+ traverse(root.left);
+}
+```
+
+```python
+# by chatGPT (python)
+class Solution:
+ def bstToGst(self, root: TreeNode) -> TreeNode:
+ # 记录累加和
+ sum = 0
+
+ # 中序遍历BST,递归地对BST节点的值进行累加和操作
+ def traverse(root: TreeNode) -> None:
+ nonlocal sum
+ if not root:
+ return
+ traverse(root.right)
+ # 维护累加和
+ sum += root.val
+ # 将 BST 转化成累加树
+ root.val = sum
+ traverse(root.left)
+
+ traverse(root)
+ return root
+```
+
+https://leetcode.cn/problems/binary-search-tree-to-greater-sum-tree 的多语言解法👆
+
+https://leetcode.cn/problems/binary-tree-inorder-traversal 的多语言解法👇
+
+```cpp
+// by chatGPT (cpp)
+class Solution {
+public:
+ /* 动态规划思路 */
+ // 定义:输入一个节点,返回以该节点为根的二叉树的中序遍历结果
+ vector inorderTraversal(TreeNode* root) {
+ vector res;
+ if (root == NULL) {
+ return res;
+ }
+ vector left = inorderTraversal(root->left);
+ res.insert(res.end(), left.begin(), left.end());
+ res.push_back(root->val);
+ vector right = inorderTraversal(root->right);
+ res.insert(res.end(), right.begin(), right.end());
+ return res;
+ }
+
+ /* 回溯算法思路 */
+ vector res;
+
+ // 返回前序遍历结果
+ vector inorderTraversal2(TreeNode* root) {
+ traverse(root);
+ return res;
+ }
+
+ // 二叉树遍历函数
+ void traverse(TreeNode* root) {
+ if (root == NULL) {
+ return;
+ }
+ traverse(root->left);
+ // 中序遍历位置
+ res.push_back(root->val);
+ traverse(root->right);
+ }
+};
+```
+
+```go
+// by chatGPT (go)
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ * Val int
+ * Left *TreeNode
+ * Right *TreeNode
+ * }
+ */
+
+// 动态规划思路
+// 定义:输入一个节点,返回以该节点为根的二叉树的中序遍历结果
+func inorderTraversal(root *TreeNode) []int {
+ res := []int{}
+ if root == nil {
+ return res
+ }
+ res = append(res, inorderTraversal(root.Left)...)
+ res = append(res, root.Val)
+ res = append(res, inorderTraversal(root.Right)...)
+ return res
+}
+
+// 回溯算法思路
+func inorderTraversal2(root *TreeNode) []int {
+ res := []int{}
+ // 二叉树遍历函数
+ var traverse func(node *TreeNode)
+ traverse = func(node *TreeNode) {
+ if node == nil {
+ return
+ }
+ traverse(node.Left)
+ // 中序遍历位置
+ res = append(res, node.Val)
+ traverse(node.Right)
+ }
+
+ traverse(root)
+ return res
+}
+```
+
+```java
+// by labuladong (java)
+class Solution {
+ /* 动态规划思路 */
+ // 定义:输入一个节点,返回以该节点为根的二叉树的中序遍历结果
+ public List inorderTraversal(TreeNode root) {
+ LinkedList res = new LinkedList<>();
+ if (root == null) {
+ return res;
+ }
+ res.addAll(inorderTraversal(root.left));
+ res.add(root.val);
+ res.addAll(inorderTraversal(root.right));
+ return res;
+ }
+
+ /* 回溯算法思路 */
+ LinkedList res = new LinkedList<>();
+
+ // 返回前序遍历结果
+ public List