Skip to content

Commit b98a630

Browse files
Merge branch 'master' into greedy02
2 parents ff233a8 + 2805c6d commit b98a630

File tree

176 files changed

+5172
-512
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

176 files changed

+5172
-512
lines changed

problems/0001.两数之和.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
## 1. 两数之和
99

10-
[力扣题目链接](https://leetcode-cn.com/problems/two-sum/)
10+
[力扣题目链接](https://leetcode.cn/problems/two-sum/)
1111

1212
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
1313

@@ -317,6 +317,20 @@ public class Solution {
317317
}
318318
```
319319

320+
Dart:
321+
```dart
322+
List<int> twoSum(List<int> nums, int target) {
323+
var tmp = [];
324+
for (var i = 0; i < nums.length; i++) {
325+
var rest = target - nums[i];
326+
if(tmp.contains(rest)){
327+
return [tmp.indexOf(rest), i];
328+
}
329+
tmp.add(nums[i]);
330+
}
331+
return [0 , 0];
332+
}
333+
```
320334

321335
-----------------------
322336
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>

problems/0005.最长回文子串.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
# 5.最长回文子串
1010

11-
[力扣题目链接](https://leetcode-cn.com/problems/longest-palindromic-substring/)
11+
[力扣题目链接](https://leetcode.cn/problems/longest-palindromic-substring/)
1212

1313
给你一个字符串 s,找到 s 中最长的回文子串。
1414

problems/0015.三数之和.md

+137-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
1111
# 第15题. 三数之和
1212

13-
[力扣题目链接](https://leetcode-cn.com/problems/3sum/)
13+
[力扣题目链接](https://leetcode.cn/problems/3sum/)
1414

1515
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
1616

@@ -95,7 +95,7 @@ public:
9595
9696
拿这个nums数组来举例,首先将数组排序,然后有一层for循环,i从下标0的地方开始,同时定一个下标left 定义在i+1的位置上,定义下标right 在数组结尾的位置上。
9797
98-
依然还是在数组中找到 abc 使得a + b +c =0,我们这里相当于 a = nums[i] b = nums[left] c = nums[right]。
98+
依然还是在数组中找到 abc 使得a + b +c =0,我们这里相当于 a = nums[i]b = nums[left]c = nums[right]。
9999
100100
接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下标就应该向左移动,这样才能让三数之和小一些。
101101
@@ -345,6 +345,76 @@ var threeSum = function(nums) {
345345
return res
346346
};
347347
```
348+
349+
解法二:nSum通用解法。递归
350+
351+
```js
352+
/**
353+
* nsum通用解法,支持2sum,3sum,4sum...等等
354+
* 时间复杂度分析:
355+
* 1. n = 2时,时间复杂度O(NlogN),排序所消耗的时间。、
356+
* 2. n > 2时,时间复杂度为O(N^n-1),即N的n-1次方,至少是2次方,此时可省略排序所消耗的时间。举例:3sum为O(n^2),4sum为O(n^3)
357+
* @param {number[]} nums
358+
* @return {number[][]}
359+
*/
360+
var threeSum = function (nums) {
361+
// nsum通用解法核心方法
362+
function nSumTarget(nums, n, start, target) {
363+
// 前提:nums要先排序好
364+
let res = [];
365+
if (n === 2) {
366+
res = towSumTarget(nums, start, target);
367+
} else {
368+
for (let i = start; i < nums.length; i++) {
369+
// 递归求(n - 1)sum
370+
let subRes = nSumTarget(
371+
nums,
372+
n - 1,
373+
i + 1,
374+
target - nums[i]
375+
);
376+
for (let j = 0; j < subRes.length; j++) {
377+
res.push([nums[i], ...subRes[j]]);
378+
}
379+
// 跳过相同元素
380+
while (nums[i] === nums[i + 1]) i++;
381+
}
382+
}
383+
return res;
384+
}
385+
386+
function towSumTarget(nums, start, target) {
387+
// 前提:nums要先排序好
388+
let res = [];
389+
let len = nums.length;
390+
let left = start;
391+
let right = len - 1;
392+
while (left < right) {
393+
let sum = nums[left] + nums[right];
394+
if (sum < target) {
395+
while (nums[left] === nums[left + 1]) left++;
396+
left++;
397+
} else if (sum > target) {
398+
while (nums[right] === nums[right - 1]) right--;
399+
right--;
400+
} else {
401+
// 相等
402+
res.push([nums[left], nums[right]]);
403+
// 跳过相同元素
404+
while (nums[left] === nums[left + 1]) left++;
405+
while (nums[right] === nums[right - 1]) right--;
406+
left++;
407+
right--;
408+
}
409+
}
410+
return res;
411+
}
412+
nums.sort((a, b) => a - b);
413+
// n = 3,此时求3sum之和
414+
return nSumTarget(nums, 3, 0, 0);
415+
};
416+
```
417+
348418
TypeScript:
349419

350420
```typescript
@@ -484,6 +554,71 @@ func threeSum(_ nums: [Int]) -> [[Int]] {
484554
}
485555
```
486556

557+
Rust:
558+
```Rust
559+
// 哈希解法
560+
use std::collections::HashSet;
561+
impl Solution {
562+
pub fn three_sum(nums: Vec<i32>) -> Vec<Vec<i32>> {
563+
let mut result: Vec<Vec<i32>> = Vec::new();
564+
let mut nums = nums;
565+
nums.sort();
566+
let len = nums.len();
567+
for i in 0..len {
568+
if nums[i] > 0 { break; }
569+
if i > 0 && nums[i] == nums[i - 1] { continue; }
570+
let mut set = HashSet::new();
571+
for j in (i + 1)..len {
572+
if j > i + 2 && nums[j] == nums[j - 1] && nums[j] == nums[j - 2] { continue; }
573+
let c = 0 - (nums[i] + nums[j]);
574+
if set.contains(&c) {
575+
result.push(vec![nums[i], nums[j], c]);
576+
set.remove(&c);
577+
} else { set.insert(nums[j]); }
578+
}
579+
}
580+
result
581+
}
582+
}
583+
```
584+
585+
```Rust
586+
// 双指针法
587+
use std::collections::HashSet;
588+
impl Solution {
589+
pub fn three_sum(nums: Vec<i32>) -> Vec<Vec<i32>> {
590+
let mut result: Vec<Vec<i32>> = Vec::new();
591+
let mut nums = nums;
592+
nums.sort();
593+
let len = nums.len();
594+
for i in 0..len {
595+
if nums[i] > 0 { return result; }
596+
if i > 0 && nums[i] == nums[i - 1] { continue; }
597+
let (mut left, mut right) = (i + 1, len - 1);
598+
while left < right {
599+
if nums[i] + nums[left] + nums[right] > 0 {
600+
right -= 1;
601+
// 去重
602+
while left < right && nums[right] == nums[right + 1] { right -= 1; }
603+
} else if nums[i] + nums[left] + nums[right] < 0 {
604+
left += 1;
605+
// 去重
606+
while left < right && nums[left] == nums[left - 1] { left += 1; }
607+
} else {
608+
result.push(vec![nums[i], nums[left], nums[right]]);
609+
// 去重
610+
right -= 1;
611+
left += 1;
612+
while left < right && nums[right] == nums[right + 1] { right -= 1; }
613+
while left < right && nums[left] == nums[left - 1] { left += 1; }
614+
}
615+
}
616+
}
617+
result
618+
}
619+
}
620+
```
621+
487622
C:
488623
```C
489624
//qsort辅助cmp函数

problems/0017.电话号码的字母组合.md

+75-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
# 17.电话号码的字母组合
99

10-
[力扣题目链接](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/)
10+
[力扣题目链接](https://leetcode.cn/problems/letter-combinations-of-a-phone-number/)
1111

1212
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
1313

@@ -454,6 +454,49 @@ function letterCombinations(digits: string): string[] {
454454
};
455455
```
456456

457+
## Rust
458+
459+
```Rust
460+
impl Solution {
461+
fn backtracking(result: &mut Vec<String>, s: &mut String, map: &[&str; 10], digits: &String, index: usize) {
462+
let len = digits.len();
463+
if len == index {
464+
result.push(s.to_string());
465+
return;
466+
}
467+
// 在保证不会越界的情况下使用unwrap()将Some()中的值提取出来
468+
let digit= digits.chars().nth(index).unwrap().to_digit(10).unwrap() as usize;
469+
let letters = map[digit];
470+
for i in letters.chars() {
471+
s.push(i);
472+
Self::backtracking(result, s, &map, &digits, index+1);
473+
s.pop();
474+
}
475+
}
476+
pub fn letter_combinations(digits: String) -> Vec<String> {
477+
if digits.len() == 0 {
478+
return vec![];
479+
}
480+
const MAP: [&str; 10] = [
481+
"",
482+
"",
483+
"abc",
484+
"def",
485+
"ghi",
486+
"jkl",
487+
"mno",
488+
"pqrs",
489+
"tuv",
490+
"wxyz"
491+
];
492+
let mut result: Vec<String> = Vec::new();
493+
let mut s: String = String::new();
494+
Self::backtracking(&mut result, &mut s, &MAP, &digits, 0);
495+
result
496+
}
497+
}
498+
```
499+
457500
## C
458501

459502
```c
@@ -557,6 +600,37 @@ func letterCombinations(_ digits: String) -> [String] {
557600
}
558601
```
559602

603+
## Scala:
604+
605+
```scala
606+
object Solution {
607+
import scala.collection.mutable
608+
def letterCombinations(digits: String): List[String] = {
609+
var result = mutable.ListBuffer[String]()
610+
if(digits == "") return result.toList // 如果参数为空,返回空结果集的List形式
611+
var path = mutable.ListBuffer[Char]()
612+
// 数字和字符的映射关系
613+
val map = Array[String]("", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz")
614+
615+
def backtracking(index: Int): Unit = {
616+
if (index == digits.size) {
617+
result.append(path.mkString) // mkString语法:将数组类型直接转换为字符串
618+
return
619+
}
620+
var digit = digits(index) - '0' // 这里使用toInt会报错!必须 -'0'
621+
for (i <- 0 until map(digit).size) {
622+
path.append(map(digit)(i))
623+
backtracking(index + 1)
624+
path = path.take(path.size - 1)
625+
}
626+
}
627+
628+
backtracking(0)
629+
result.toList
630+
}
631+
}
632+
```
633+
560634

561635
-----------------------
562636
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>

problems/0018.四数之和.md

+52-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
1111
# 第18题. 四数之和
1212

13-
[力扣题目链接](https://leetcode-cn.com/problems/4sum/)
13+
[力扣题目链接](https://leetcode.cn/problems/4sum/)
1414

1515
题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
1616

@@ -140,6 +140,11 @@ class Solution {
140140

141141
for (int i = 0; i < nums.length; i++) {
142142

143+
// nums[i] > target 直接返回, 剪枝操作
144+
if (nums[i] > 0 && nums[i] > target) {
145+
return result;
146+
}
147+
143148
if (i > 0 && nums[i - 1] == nums[i]) {
144149
continue;
145150
}
@@ -153,7 +158,7 @@ class Solution {
153158
int left = j + 1;
154159
int right = nums.length - 1;
155160
while (right > left) {
156-
int sum = nums[i] + nums[j] + nums[left] + nums[right];
161+
long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
157162
if (sum > target) {
158163
right--;
159164
} else if (sum < target) {
@@ -522,6 +527,51 @@ public class Solution
522527
}
523528
}
524529
```
530+
531+
Rust:
532+
```Rust
533+
impl Solution {
534+
pub fn four_sum(nums: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
535+
let mut result: Vec<Vec<i32>> = Vec::new();
536+
let mut nums = nums;
537+
nums.sort();
538+
let len = nums.len();
539+
for k in 0..len {
540+
// 剪枝
541+
if nums[k] > target && (nums[k] > 0 || target > 0) { break; }
542+
// 去重
543+
if k > 0 && nums[k] == nums[k - 1] { continue; }
544+
for i in (k + 1)..len {
545+
// 剪枝
546+
if nums[k] + nums[i] > target && (nums[k] + nums[i] >= 0 || target >= 0) { break; }
547+
// 去重
548+
if i > k + 1 && nums[i] == nums[i - 1] { continue; }
549+
let (mut left, mut right) = (i + 1, len - 1);
550+
while left < right {
551+
if nums[k] + nums[i] > target - (nums[left] + nums[right]) {
552+
right -= 1;
553+
// 去重
554+
while left < right && nums[right] == nums[right + 1] { right -= 1; }
555+
} else if nums[k] + nums[i] < target - (nums[left] + nums[right]) {
556+
left += 1;
557+
// 去重
558+
while left < right && nums[left] == nums[left - 1] { left += 1; }
559+
} else {
560+
result.push(vec![nums[k], nums[i], nums[left], nums[right]]);
561+
// 去重
562+
while left < right && nums[right] == nums[right - 1] { right -= 1; }
563+
while left < right && nums[left] == nums[left + 1] { left += 1; }
564+
left += 1;
565+
right -= 1;
566+
}
567+
}
568+
}
569+
}
570+
result
571+
}
572+
}
573+
```
574+
525575
Scala:
526576
```scala
527577
object Solution {

0 commit comments

Comments
 (0)