Skip to content

Commit

Permalink
Merge branch 'youngyangyang04:master' into remote
Browse files Browse the repository at this point in the history
  • Loading branch information
KingArthur0205 committed Jan 16, 2022
2 parents 0c184a5 + 48128fd commit e6fccc5
Show file tree
Hide file tree
Showing 16 changed files with 223 additions and 51 deletions.
18 changes: 8 additions & 10 deletions problems/0001.两数之和.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,18 +207,16 @@ function twoSum(array $nums, int $target): array
Swift:
```swift
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
var res = [Int]()
var dict = [Int : Int]()
for i in 0 ..< nums.count {
let other = target - nums[i]
if dict.keys.contains(other) {
res.append(i)
res.append(dict[other]!)
return res
// 值: 下标
var map = [Int: Int]()
for (i, e) in nums.enumerated() {
if let v = map[target - e] {
return [v, i]
} else {
map[e] = i
}
dict[nums[i]] = i
}
return res
return []
}
```

Expand Down
2 changes: 1 addition & 1 deletion problems/0031.下一个排列.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public:
}
}
}
// 到这里了说明整个数组都是倒叙了,反转一下便可
// 到这里了说明整个数组都是倒序了,反转一下便可
reverse(nums.begin(), nums.end());
}
};
Expand Down
101 changes: 99 additions & 2 deletions problems/0106.从中序与后序遍历序列构造二叉树.md
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ class Solution:
root.right = self.buildTree(preorder_right, inorder_right)

return root
```
```

106.从中序与后序遍历序列构造二叉树

Expand Down Expand Up @@ -716,7 +716,7 @@ class Solution:
root.right = self.buildTree(inorder_right, postorder_right)

return root
```
```

## Go

Expand Down Expand Up @@ -816,6 +816,7 @@ var buildTree = function(preorder, inorder) {

## C
106 从中序与后序遍历序列构造二叉树

```c
int linearSearch(int* arr, int arrSize, int key) {
int i;
Expand Down Expand Up @@ -847,6 +848,7 @@ struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int po
```
105 从前序与中序遍历序列构造二叉树
```c
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
// 递归结束条件:传入的数组大小为0
Expand Down Expand Up @@ -889,5 +891,100 @@ struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int in
}
```

## Swift

105 从前序与中序遍历序列构造二叉树

```swift
class Solution {
func buildTree(_ preorder: [Int], _ inorder: [Int]) -> TreeNode? {
return helper(preorder: preorder,
preorderBegin: 0,
preorderEnd: preorder.count,
inorder: inorder,
inorderBegin: 0,
inorderEnd: inorder.count)
}

func helper(preorder: [Int], preorderBegin: Int, preorderEnd: Int, inorder: [Int], inorderBegin: Int, inorderEnd: Int) -> TreeNode? {
if preorderBegin == preorderEnd {
return nil
}

// 前序遍历数组的第一个元素作为分割点
let rootValue = preorder[preorderBegin]
let root = TreeNode(rootValue)


if preorderEnd - preorderBegin == 1 {
return root
}

var index = 0 // 从中序遍历数组中找到根节点的下标
if let ind = inorder.firstIndex(of: rootValue) {
index = ind
}

// 递归
root.left = helper(preorder: preorder,
preorderBegin: preorderBegin + 1,
preorderEnd: preorderBegin + 1 + index - inorderBegin,
inorder: inorder,
inorderBegin: inorderBegin,
inorderEnd: index)
root.right = helper(preorder: preorder,
preorderBegin: preorderBegin + 1 + index - inorderBegin,
preorderEnd: preorderEnd,
inorder: inorder,
inorderBegin: index + 1,
inorderEnd: inorderEnd)
return root
}
}
```

106 从中序与后序遍历序列构造二叉树

```swift
class Solution_0106 {
func buildTree(inorder: [Int], inorderBegin: Int, inorderEnd: Int, postorder: [Int], postorderBegin: Int, postorderEnd: Int) -> TreeNode? {
if postorderEnd - postorderBegin < 1 {
return nil
}

// 后序遍历数组的最后一个元素作为分割点
let rootValue = postorder[postorderEnd - 1]
let root = TreeNode(rootValue)

if postorderEnd - postorderBegin == 1 {
return root
}

// 从中序遍历数组中找到根节点的下标
var delimiterIndex = 0
if let index = inorder.firstIndex(of: rootValue) {
delimiterIndex = index
}

root.left = buildTree(inorder: inorder,
inorderBegin: inorderBegin,
inorderEnd: delimiterIndex,
postorder: postorder,
postorderBegin: postorderBegin,
postorderEnd: postorderBegin + (delimiterIndex - inorderBegin))

root.right = buildTree(inorder: inorder,
inorderBegin: delimiterIndex + 1,
inorderEnd: inorderEnd,
postorder: postorder,
postorderBegin: postorderBegin + (delimiterIndex - inorderBegin),
postorderEnd: postorderEnd - 1)
return root
}
}
```



-----------------------
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
2 changes: 1 addition & 1 deletion problems/0151.翻转字符串里的单词.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

不能使用辅助空间之后,那么只能在原字符串上下功夫了。

想一下,我们将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒叙了,那么再把单词反转一下,单词不就正过来了。
想一下,我们将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,单词不就正过来了。

所以解题思路如下:

Expand Down
56 changes: 56 additions & 0 deletions problems/0203.移除链表元素.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,63 @@ var removeElements = function(head, val) {
};
```

TypeScript:

版本一(在原链表上直接删除):

```typescript
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function removeElements(head: ListNode | null, val: number): ListNode | null {
// 删除头部节点
while (head !== null && head.val === val) {
head = head.next;
}
if (head === null) return head;
let pre: ListNode = head, cur: ListNode = head.next;
// 删除非头部节点
while (cur) {
if (cur.val === val) {
pre.next = cur.next;
} else {
pre = pre.next;
}
cur = cur.next;
}
return head;
};
```

版本二(虚拟头节点):

```typescript
function removeElements(head: ListNode | null, val: number): ListNode | null {
head = new ListNode(0, head);
let pre: ListNode = head, cur: ListNode = head.next;
// 删除非头部节点
while (cur) {
if (cur.val === val) {
pre.next = cur.next;
} else {
pre = pre.next;
}
cur = cur.next;
}
return head.next;
};
```

Swift:

```swift
/**
* Definition for singly-linked list.
Expand Down
1 change: 0 additions & 1 deletion problems/0344.反转字符串.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ s[j] = tmp;
s[i] ^= s[j];
s[j] ^= s[i];
s[i] ^= s[j];

```

这道题目还是比较简单的,但是我正好可以通过这道题目说一说在刷题的时候,使用库函数的原则。
Expand Down
4 changes: 2 additions & 2 deletions problems/0347.前K个高频元素.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public:
}
}

// 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒叙来输出到数组
// 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组
vector<int> result(k);
for (int i = k - 1; i >= 0; i--) {
result[i] = pri_que.top().first;
Expand Down Expand Up @@ -180,7 +180,7 @@ class Solution:
if len(pri_que) > k: #如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
heapq.heappop(pri_que)

#找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒叙来输出到数组
#找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组
result = [0] * k
for i in range(k-1, -1, -1):
result[i] = heapq.heappop(pri_que)[1]
Expand Down
2 changes: 1 addition & 1 deletion problems/0416.分割等和子集.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ vector<int> dp(10001, 0);
4. 确定遍历顺序
在[动态规划:关于01背包问题,你该了解这些!(滚动数组)](https://programmercarl.com/背包理论基础01背包-2.html)中就已经说明:如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒叙遍历
在[动态规划:关于01背包问题,你该了解这些!(滚动数组)](https://programmercarl.com/背包理论基础01背包-2.html)中就已经说明:如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历
代码如下:
Expand Down
36 changes: 16 additions & 20 deletions problems/0454.四数相加II.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ D = [ 0, 2]

1. 首先定义 一个unordered_map,key放a和b两数之和,value 放a和b两数之和出现的次数。
2. 遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中。
3. 定义int变量count,用来统计a+b+c+d = 0 出现的次数。
3. 定义int变量count,用来统计 a+b+c+d = 0 出现的次数。
4. 在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。
5. 最后返回统计值 count 就可以了

Expand Down Expand Up @@ -139,7 +139,7 @@ class Solution(object):
return count


```
```

Go:
```go
Expand Down Expand Up @@ -229,28 +229,24 @@ class Solution {
Swift:
```swift
func fourSumCount(_ nums1: [Int], _ nums2: [Int], _ nums3: [Int], _ nums4: [Int]) -> Int {
// key:a+b的数值,value:a+b数值出现的次数
var map = [Int: Int]()
// 遍历nums1和nums2数组,统计两个数组元素之和,和出现的次数,放到map中
for i in 0 ..< nums1.count {
for j in 0 ..< nums2.count {
let sum1 = nums1[i] + nums2[j]
map[sum1] = (map[sum1] ?? 0) + 1
// ab和: ab和出现次数
var countDic = [Int: Int]()
for a in nums1 {
for b in nums2 {
let key = a + b
countDic[key] = countDic[key, default: 0] + 1
}
}
// 统计a+b+c+d = 0 出现的次数
var res = 0
// 在遍历大num3和num4数组,找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来。
for i in 0 ..< nums3.count {
for j in 0 ..< nums4.count {
let sum2 = nums3[i] + nums4[j]
let other = 0 - sum2
if map.keys.contains(other) {
res += map[other]!
}

// 通过-(c + d)作为key,去累加ab和出现的次数
var result = 0
for c in nums3 {
for d in nums4 {
let key = -(c + d)
result += countDic[key, default: 0]
}
}
return res
return result
}
```

Expand Down
4 changes: 2 additions & 2 deletions problems/0685.冗余连接II.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ for (int i = 0; i < n; i++) {

```cpp
vector<int> vec; // 记录入度为2的边(如果有的话就两条边)
// 找入度为2的节点所对应的边,注意要倒叙,因为优先返回最后出现在二维数组中的答案
// 找入度为2的节点所对应的边,注意要倒序,因为优先返回最后出现在二维数组中的答案
for (int i = n - 1; i >= 0; i--) {
if (inDegree[edges[i][1]] == 2) {
vec.push_back(i);
Expand Down Expand Up @@ -577,7 +577,7 @@ var findRedundantDirectedConnection = function(edges) {
inDegree[edges[i][1]]++; // 统计入度
}
let vec = [];// 记录入度为2的边(如果有的话就两条边)
// 找入度为2的节点所对应的边,注意要倒叙,因为优先返回最后出现在二维数组中的答案
// 找入度为2的节点所对应的边,注意要倒序,因为优先返回最后出现在二维数组中的答案
for (let i = n - 1; i >= 0; i--) {
if (inDegree[edges[i][1]] == 2) {
vec.push(i);
Expand Down
2 changes: 1 addition & 1 deletion problems/0746.使用最小花费爬楼梯.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ dp[1] = cost[1];

**但是稍稍有点难度的动态规划,其遍历顺序并不容易确定下来**

例如:01背包,都知道两个for循环,一个for遍历物品嵌套一个for遍历背包容量,那么为什么不是一个for遍历背包容量嵌套一个for遍历物品呢? 以及在使用一维dp数组的时候遍历背包容量为什么要倒叙呢
例如:01背包,都知道两个for循环,一个for遍历物品嵌套一个for遍历背包容量,那么为什么不是一个for遍历背包容量嵌套一个for遍历物品呢? 以及在使用一维dp数组的时候遍历背包容量为什么要倒序呢

**这些都是遍历顺序息息相关。当然背包问题后续「代码随想录」都会重点讲解的!**

Expand Down
8 changes: 4 additions & 4 deletions problems/1002.查找常用字符.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ words[i] 由小写英文字母组成

先统计第一个字符串所有字符出现的次数,代码如下:

```
```cpp
int hash[26] = {0}; // 用来统计所有字符串里字符出现的最小频率
for (int i = 0; i < A[0].size(); i++) { // 用第一个字符串给hash初始化
hash[A[0][i] - 'a']++;
Expand All @@ -71,7 +71,7 @@ for (int i = 0; i < A[0].size(); i++) { // 用第一个字符串给hash初始化

代码如下:

```
```cpp
int hashOtherStr[26] = {0}; // 统计除第一个字符串外字符的出现频率
for (int i = 1; i < A.size(); i++) {
memset(hashOtherStr, 0, 26 * sizeof(int));
Expand All @@ -84,11 +84,11 @@ for (int i = 1; i < A.size(); i++) {
}
}
```
此时hash里统计着字符在所有字符串里出现的最小次数,那么把hash转正题目要求的输出格式就可以了
此时hash里统计着字符在所有字符串里出现的最小次数,那么把hash转成题目要求的输出格式就可以了

代码如下:

```
```cpp
// 将hash统计的字符次数,转成输出形式
for (int i = 0; i < 26; i++) {
while (hash[i] != 0) { // 注意这里是while,多个重复的字符
Expand Down
Loading

0 comments on commit e6fccc5

Please sign in to comment.