forked from azl397985856/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 修改错别字,并添加题解 (azl397985856#343)
- Loading branch information
Showing
10 changed files
with
445 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
## 题目地址 | ||
https://leetcode-cn.com/problems/two-sum | ||
|
||
## 题目描述 | ||
``` | ||
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 | ||
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 | ||
示例: | ||
给定 nums = [2, 7, 11, 15], target = 9 | ||
因为 nums[0] + nums[1] = 2 + 7 = 9 | ||
所以返回 [0, 1] | ||
``` | ||
## 思路 | ||
最容易想到的就是暴力枚举,我们可以利用两层 for 循环来遍历每个元素,并查找满足条件的目标元素。不过这样时间复杂度为 O(N^2),空间复杂度为 O(1),时间复杂度较高,我们要想办法进行优化。我们可以增加一个 Map 记录已经遍历过的数字及其对应的索引值。这样当遍历一个新数字的时候去 Map 里查询,target 与该数的差值是否已经在前面的数字中出现过。如果出现过,那么已经得出答案,就不必再往下执行了。 | ||
|
||
## 关键点 | ||
|
||
- 求和转换为求差 | ||
- 借助 Map 结构将数组中每个元素及其索引相互对应 | ||
- 以空间换时间,将查找时间从 O(N) 降低到 O(1) | ||
|
||
## 代码 | ||
* 语言支持:JS | ||
|
||
```js | ||
/** | ||
* @param {number[]} nums | ||
* @param {number} target | ||
* @return {number[]} | ||
*/ | ||
const twoSum = function (nums, target) { | ||
const map = new Map(); | ||
for (let i = 0; i < nums.length; i++) { | ||
const diff = target - nums[i]; | ||
if (map.has(diff)) { | ||
return [map.get(diff), i]; | ||
} | ||
map.set(nums[i], i); | ||
} | ||
} | ||
``` | ||
|
||
***复杂度分析*** | ||
|
||
- 时间复杂度:O(N) | ||
- 空间复杂度:O(N) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
## 题目地址 | ||
https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number | ||
|
||
## 题目描述 | ||
``` | ||
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 | ||
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 | ||
示例: | ||
输入:"23" | ||
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. | ||
说明: | ||
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。 | ||
``` | ||
|
||
## 思路 | ||
使用回溯法进行求解,回溯是一种通过穷举所有可能情况来找到所有解的算法。如果一个候选解最后被发现并不是可行解,回溯算法会舍弃它,并在前面的一些步骤做出一些修改,并重新尝试找到可行解。究其本质,其实就是枚举。 | ||
|
||
如果没有更多的数字需要被输入,说明当前的组合已经产生。 | ||
|
||
如果还有数字需要被输入: | ||
- 遍历下一个数字所对应的所有映射的字母 | ||
- 将当前的字母添加到组合最后,也就是 str + tmp[r] | ||
|
||
## 关键点 | ||
利用回溯思想解题,在for循环中调用递归。 | ||
|
||
## 代码 | ||
* 语言支持:JS | ||
|
||
```js | ||
/** | ||
* @param {string} digits | ||
* @return {string[]} | ||
*/ | ||
const letterCombinations = function (digits) { | ||
if (!digits) { | ||
return []; | ||
} | ||
const len = digits.length; | ||
const map = new Map(); | ||
map.set('2', 'abc'); | ||
map.set('3', 'def'); | ||
map.set('4', 'ghi'); | ||
map.set('5', 'jkl'); | ||
map.set('6', 'mno'); | ||
map.set('7', 'pqrs'); | ||
map.set('8', 'tuv'); | ||
map.set('9', 'wxyz'); | ||
const result = []; | ||
|
||
function generate(i, str) { | ||
if (i == len) { | ||
result.push(str); | ||
return; | ||
} | ||
const tmp = map.get(digits[i]); | ||
for (let r = 0; r < tmp.length; r++) { | ||
generate(i + 1, str + tmp[r]); | ||
} | ||
} | ||
generate(0, ''); | ||
return result; | ||
}; | ||
``` | ||
|
||
***复杂度分析*** | ||
|
||
N + M 是输入数字的总数 | ||
|
||
- 时间复杂度:O(3^N * 4^M) | ||
- 空间复杂度:O(3^N * 4^M) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
## 题目地址 | ||
https://leetcode-cn.com/problems/merge-two-sorted-lists | ||
|
||
## 题目描述 | ||
``` | ||
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 | ||
示例: | ||
输入:1->2->4, 1->3->4 | ||
输出:1->1->2->3->4->4 | ||
``` | ||
|
||
## 思路 | ||
使用递归来解题,将两个链表头部较小的一个与剩下的元素合并,并返回排好序的链表头,当两条链表中的一条为空时终止递归。 | ||
|
||
|
||
## 关键点 | ||
|
||
- 掌握链表数据结构 | ||
- 考虑边界情况 | ||
|
||
## 代码 | ||
* 语言支持:JS | ||
|
||
```js | ||
/** | ||
* Definition for singly-linked list. | ||
* function ListNode(val) { | ||
* this.val = val; | ||
* this.next = null; | ||
* } | ||
*/ | ||
/** | ||
* @param {ListNode} l1 | ||
* @param {ListNode} l2 | ||
* @return {ListNode} | ||
*/ | ||
const mergeTwoLists = function (l1, l2) { | ||
if (l1 === null) { | ||
return l2; | ||
} | ||
if (l2 === null) { | ||
return l1; | ||
} | ||
if (l1.val < l2.val) { | ||
l1.next = mergeTwoLists(l1.next, l2); | ||
return l1; | ||
} else { | ||
l2.next = mergeTwoLists(l1, l2.next); | ||
return l2; | ||
} | ||
}; | ||
``` | ||
|
||
***复杂度分析*** | ||
|
||
M、N 是两条链表 l1、l2 的长度 | ||
|
||
- 时间复杂度:O(M+N) | ||
- 空间复杂度:O(M+N) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
## 题目地址 | ||
https://leetcode-cn.com/problems/generate-parentheses | ||
|
||
## 题目描述 | ||
``` | ||
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 | ||
示例: | ||
输入:n = 3 | ||
输出:[ | ||
"((()))", | ||
"(()())", | ||
"(())()", | ||
"()(())", | ||
"()()()" | ||
] | ||
``` | ||
|
||
## 思路 | ||
|
||
深度优先搜索(回溯思想),从空字符串开始构造,做加法。 | ||
|
||
|
||
## 关键点 | ||
|
||
- 当 l < r 时记得剪枝 | ||
|
||
|
||
## 代码 | ||
* 语言支持:JS | ||
|
||
```js | ||
/** | ||
* @param {number} n | ||
* @return {string[]} | ||
* @param l 左括号已经用了几个 | ||
* @param r 右括号已经用了几个 | ||
* @param str 当前递归得到的拼接字符串结果 | ||
* @param res 结果集 | ||
*/ | ||
const generateParenthesis = function (n) { | ||
const res = []; | ||
|
||
function dfs(l, r, str) { | ||
if (l == n && r == n) { | ||
return res.push(str); | ||
} | ||
// l 小于 r 时不满足条件 剪枝 | ||
if (l < r) { | ||
return; | ||
} | ||
// l 小于 n 时可以插入左括号,最多可以插入 n 个 | ||
if (l < n) { | ||
dfs(l + 1, r, str + '('); | ||
} | ||
// r < l 时 可以插入右括号 | ||
if (r < l) { | ||
dfs(l, r + 1, str + ')'); | ||
} | ||
} | ||
dfs(0, 0, ''); | ||
return res; | ||
}; | ||
``` | ||
|
||
|
||
***复杂度分析*** | ||
|
||
- 时间复杂度:O(2^N) | ||
- 空间复杂度:O(2^N) |
Oops, something went wrong.