Skip to content

Commit

Permalink
Merge branch 'master' into patch06
Browse files Browse the repository at this point in the history
  • Loading branch information
youngyangyang04 committed Jun 2, 2022
2 parents 9f72047 + 60193de commit 89b3d4e
Show file tree
Hide file tree
Showing 85 changed files with 2,777 additions and 280 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@
33. [二叉树:构造一棵搜索树](./problems/0108.将有序数组转换为二叉搜索树.md)
34. [二叉树:搜索树转成累加树](./problems/0538.把二叉搜索树转换为累加树.md)
35. [二叉树:总结篇!(需要掌握的二叉树技能都在这里了)](./problems/二叉树总结篇.md)

## 回溯算法

题目分类大纲如下:
Expand Down
18 changes: 18 additions & 0 deletions problems/0001.两数之和.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,24 @@ class Solution {
}
}
```
C#:
```csharp
public class Solution {
public int[] TwoSum(int[] nums, int target) {
Dictionary<int ,int> dic= new Dictionary<int,int>();
for(int i=0;i<nums.Length;i++){
int imp= target-nums[i];
if(dic.ContainsKey(imp)&&dic[imp]!=i){
return new int[]{i, dic[imp]};
}
if(!dic.ContainsKey(nums[i])){
dic.Add(nums[i],i);
}
}
return new int[]{0, 0};
}
}
```

-----------------------
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
70 changes: 26 additions & 44 deletions problems/0015.三数之和.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,54 +313,36 @@ func threeSum(nums []int)[][]int{
javaScript:

```js
/**
* @param {number[]} nums
* @return {number[][]}
*/

// 循环内不考虑去重
var threeSum = function(nums) {
const len = nums.length;
if(len < 3) return [];
nums.sort((a, b) => a - b);
const resSet = new Set();
for(let i = 0; i < len - 2; i++) {
if(nums[i] > 0) break;
let l = i + 1, r = len - 1;
while(l < r) {
const sum = nums[i] + nums[l] + nums[r];
if(sum < 0) { l++; continue };
if(sum > 0) { r--; continue };
resSet.add(`${nums[i]},${nums[l]},${nums[r]}`);
l++;
r--;
}
}
return Array.from(resSet).map(i => i.split(","));
};

// 去重优化
var threeSum = function(nums) {
const len = nums.length;
if(len < 3) return [];
nums.sort((a, b) => a - b);
const res = [];
for(let i = 0; i < len - 2; i++) {
if(nums[i] > 0) break;
// a去重
if(i > 0 && nums[i] === nums[i - 1]) continue;
let l = i + 1, r = len - 1;
const res = [], len = nums.length
// 将数组排序
nums.sort((a, b) => a - b)
for (let i = 0; i < len; i++) {
let l = i + 1, r = len - 1, iNum = nums[i]
// 数组排过序,如果第一个数大于0直接返回res
if (iNum > 0) return res
// 去重
if (iNum == nums[i - 1]) continue
while(l < r) {
const sum = nums[i] + nums[l] + nums[r];
if(sum < 0) { l++; continue };
if(sum > 0) { r--; continue };
res.push([nums[i], nums[l], nums[r]])
// b c 去重
while(l < r && nums[l] === nums[++l]);
while(l < r && nums[r] === nums[--r]);
let lNum = nums[l], rNum = nums[r], threeSum = iNum + lNum + rNum
// 三数之和小于0,则左指针向右移动
if (threeSum < 0) l++
else if (threeSum > 0) r--
else {
res.push([iNum, lNum, rNum])
// 去重
while(l < r && nums[l] == nums[l + 1]){
l++
}
while(l < r && nums[r] == nums[r - 1]) {
r--
}
l++
r--
}
}
}
return res;
return res
};
```
TypeScript:
Expand Down
26 changes: 24 additions & 2 deletions problems/0019.删除链表的倒数第N个节点.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

分为如下几步:

* 首先这里我推荐大家使用虚拟头结点,这样方面处理删除实际头结点的逻辑,如果虚拟头结点不清楚,可以看这篇: [链表:听说用虚拟头节点会方便很多?](https://programmercarl.com/0203.移除链表元素.html)
* 首先这里我推荐大家使用虚拟头结点,这样方便处理删除实际头结点的逻辑,如果虚拟头结点不清楚,可以看这篇: [链表:听说用虚拟头节点会方便很多?](https://programmercarl.com/0203.移除链表元素.html)

* 定义fast指针和slow指针,初始值为虚拟头结点,如图:

Expand Down Expand Up @@ -289,6 +289,28 @@ func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
return dummyHead.next
}
```

Scala:
```scala
object Solution {
def removeNthFromEnd(head: ListNode, n: Int): ListNode = {
val dummy = new ListNode(-1, head) // 定义虚拟头节点
var fast = head // 快指针从头开始走
var slow = dummy // 慢指针从虚拟头开始头
// 因为参数 n 是不可变量,所以不能使用 while(n>0){n-=1}的方式
for (i <- 0 until n) {
fast = fast.next
}
// 快指针和满指针一起走,直到fast走到null
while (fast != null) {
slow = slow.next
fast = fast.next
}
// 删除slow的下一个节点
slow.next = slow.next.next
// 返回虚拟头节点的下一个
dummy.next
}
}
```
-----------------------
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
24 changes: 23 additions & 1 deletion problems/0024.两两交换链表中的节点.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,29 @@ func swapPairs(_ head: ListNode?) -> ListNode? {
return dummyHead.next
}
```

Scala:
```scala
// 虚拟头节点
object Solution {
def swapPairs(head: ListNode): ListNode = {
var dummy = new ListNode(0, head) // 虚拟头节点
var pre = dummy
var cur = head
// 当pre的下一个和下下个都不为空,才进行两两转换
while (pre.next != null && pre.next.next != null) {
var tmp: ListNode = cur.next.next // 缓存下一次要进行转换的第一个节点
pre.next = cur.next // 步骤一
cur.next.next = cur // 步骤二
cur.next = tmp // 步骤三
// 下面是准备下一轮的交换
pre = cur
cur = tmp
}
// 最终返回dummy虚拟头节点的下一个,return可以省略
dummy.next
}
}
```

-----------------------
<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/0027.移除元素.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public:

**双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组、链表、字符串等操作的面试题,都使用双指针法。**

后序都会一一介绍到,本题代码如下:
后续都会一一介绍到,本题代码如下:

```CPP
// 时间复杂度:O(n)
Expand Down
25 changes: 25 additions & 0 deletions problems/0035.搜索插入位置.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,31 @@ func searchInsert(_ nums: [Int], _ target: Int) -> Int {
```


### PHP

```php
// 二分法(1):[左闭右闭]
function searchInsert($nums, $target)
{
$n = count($nums);
$l = 0;
$r = $n - 1;
while ($l <= $r) {
$mid = floor(($l + $r) / 2);
if ($nums[$mid] > $target) {
// 下次搜索在左区间:[$l,$mid-1]
$r = $mid - 1;
} else if ($nums[$mid] < $target) {
// 下次搜索在右区间:[$mid+1,$r]
$l = $mid + 1;
} else {
// 命中返回
return $mid;
}
}
return $r + 1;
}
```


-----------------------
Expand Down
5 changes: 2 additions & 3 deletions problems/0039.组合总和.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,18 +370,17 @@ func backtracking(startIndex,sum,target int,candidates,trcak []int,res *[][]int)
```js
var combinationSum = function(candidates, target) {
const res = [], path = [];
candidates.sort(); // 排序
candidates.sort((a,b)=>a-b); // 排序
backtracking(0, 0);
return res;
function backtracking(j, sum) {
if (sum > target) return;
if (sum === target) {
res.push(Array.from(path));
return;
}
for(let i = j; i < candidates.length; i++ ) {
const n = candidates[i];
if(n > target - sum) continue;
if(n > target - sum) break;
path.push(n);
sum += n;
backtracking(i, sum);
Expand Down
15 changes: 10 additions & 5 deletions problems/0040.组合总和II.md
Original file line number Diff line number Diff line change
Expand Up @@ -508,22 +508,27 @@ func backtracking(startIndex,sum,target int,candidates,trcak []int,res *[][]int)
*/
var combinationSum2 = function(candidates, target) {
const res = []; path = [], len = candidates.length;
candidates.sort();
candidates.sort((a,b)=>a-b);
backtracking(0, 0);
return res;
function backtracking(sum, i) {
if (sum > target) return;
if (sum === target) {
res.push(Array.from(path));
return;
}
let f = -1;
for(let j = i; j < len; j++) {
const n = candidates[j];
if(n > target - sum || n === f) continue;
if(j > i && candidates[j] === candidates[j-1]){
//若当前元素和前一个元素相等
//则本次循环结束,防止出现重复组合
continue;
}
//如果当前元素值大于目标值-总和的值
//由于数组已排序,那么该元素之后的元素必定不满足条件
//直接终止当前层的递归
if(n > target - sum) break;
path.push(n);
sum += n;
f = n;
backtracking(sum, j + 1);
path.pop();
sum -= n;
Expand Down
32 changes: 20 additions & 12 deletions problems/0045.跳跃游戏II.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,18 +217,26 @@ class Solution:
### Go
```Go
func jump(nums []int) int {
dp:=make([]int ,len(nums))
dp[0]=0

for i:=1;i<len(nums);i++{
dp[i]=i
for j:=0;j<i;j++{
if nums[j]+j>i{
dp[i]=min(dp[j]+1,dp[i])
}
}
}
return dp[len(nums)-1]
dp := make([]int, len(nums))
dp[0] = 0//初始第一格跳跃数一定为0

for i := 1; i < len(nums); i++ {
dp[i] = i
for j := 0; j < i; j++ {
if nums[j] + j >= i {//nums[j]为起点,j为往右跳的覆盖范围,这行表示从j能跳到i
dp[i] = min(dp[j] + 1, dp[i])//更新最小能到i的跳跃次数
}
}
}
return dp[len(nums)-1]
}

func min(a, b int) int {
if a < b {
return a
} else {
return b
}
}
```

Expand Down
20 changes: 17 additions & 3 deletions problems/0053.最大子序和.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public:
## 其他语言版本
### Java
### Java
```java
class Solution {
public int maxSubArray(int[] nums) {
Expand Down Expand Up @@ -180,7 +180,7 @@ class Solution {
}
```

### Python
### Python
```python
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
Expand All @@ -195,7 +195,7 @@ class Solution:
return result
```

### Go
### Go

```go
func maxSubArray(nums []int) int {
Expand All @@ -212,6 +212,20 @@ func maxSubArray(nums []int) int {
}
```

### Rust
```rust
pub fn max_sub_array(nums: Vec<i32>) -> i32 {
let mut max_sum = i32::MIN;
let mut curr = 0;
for n in nums.iter() {
curr += n;
max_sum = max_sum.max(curr);
curr = curr.max(0);
}
max_sum
}
```

### Javascript:
```Javascript
var maxSubArray = function(nums) {
Expand Down
Loading

0 comments on commit 89b3d4e

Please sign in to comment.