mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-12 13:45:39 +08:00
Merge branch 'youngyangyang04:master' into master
This commit is contained in:
@ -317,6 +317,20 @@ public class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Dart:
|
||||||
|
```dart
|
||||||
|
List<int> twoSum(List<int> nums, int target) {
|
||||||
|
var tmp = [];
|
||||||
|
for (var i = 0; i < nums.length; i++) {
|
||||||
|
var rest = target - nums[i];
|
||||||
|
if(tmp.contains(rest)){
|
||||||
|
return [tmp.indexOf(rest), i];
|
||||||
|
}
|
||||||
|
tmp.add(nums[i]);
|
||||||
|
}
|
||||||
|
return [0 , 0];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -554,6 +554,71 @@ func threeSum(_ nums: [Int]) -> [[Int]] {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Rust:
|
||||||
|
```Rust
|
||||||
|
// 哈希解法
|
||||||
|
use std::collections::HashSet;
|
||||||
|
impl Solution {
|
||||||
|
pub fn three_sum(nums: Vec<i32>) -> Vec<Vec<i32>> {
|
||||||
|
let mut result: Vec<Vec<i32>> = Vec::new();
|
||||||
|
let mut nums = nums;
|
||||||
|
nums.sort();
|
||||||
|
let len = nums.len();
|
||||||
|
for i in 0..len {
|
||||||
|
if nums[i] > 0 { break; }
|
||||||
|
if i > 0 && nums[i] == nums[i - 1] { continue; }
|
||||||
|
let mut set = HashSet::new();
|
||||||
|
for j in (i + 1)..len {
|
||||||
|
if j > i + 2 && nums[j] == nums[j - 1] && nums[j] == nums[j - 2] { continue; }
|
||||||
|
let c = 0 - (nums[i] + nums[j]);
|
||||||
|
if set.contains(&c) {
|
||||||
|
result.push(vec![nums[i], nums[j], c]);
|
||||||
|
set.remove(&c);
|
||||||
|
} else { set.insert(nums[j]); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```Rust
|
||||||
|
// 双指针法
|
||||||
|
use std::collections::HashSet;
|
||||||
|
impl Solution {
|
||||||
|
pub fn three_sum(nums: Vec<i32>) -> Vec<Vec<i32>> {
|
||||||
|
let mut result: Vec<Vec<i32>> = Vec::new();
|
||||||
|
let mut nums = nums;
|
||||||
|
nums.sort();
|
||||||
|
let len = nums.len();
|
||||||
|
for i in 0..len {
|
||||||
|
if nums[i] > 0 { return result; }
|
||||||
|
if i > 0 && nums[i] == nums[i - 1] { continue; }
|
||||||
|
let (mut left, mut right) = (i + 1, len - 1);
|
||||||
|
while left < right {
|
||||||
|
if nums[i] + nums[left] + nums[right] > 0 {
|
||||||
|
right -= 1;
|
||||||
|
// 去重
|
||||||
|
while left < right && nums[right] == nums[right + 1] { right -= 1; }
|
||||||
|
} else if nums[i] + nums[left] + nums[right] < 0 {
|
||||||
|
left += 1;
|
||||||
|
// 去重
|
||||||
|
while left < right && nums[left] == nums[left - 1] { left += 1; }
|
||||||
|
} else {
|
||||||
|
result.push(vec![nums[i], nums[left], nums[right]]);
|
||||||
|
// 去重
|
||||||
|
right -= 1;
|
||||||
|
left += 1;
|
||||||
|
while left < right && nums[right] == nums[right + 1] { right -= 1; }
|
||||||
|
while left < right && nums[left] == nums[left - 1] { left += 1; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
C:
|
C:
|
||||||
```C
|
```C
|
||||||
//qsort辅助cmp函数
|
//qsort辅助cmp函数
|
||||||
|
@ -140,6 +140,11 @@ class Solution {
|
|||||||
|
|
||||||
for (int i = 0; i < nums.length; i++) {
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
|
||||||
|
// nums[i] > target 直接返回, 剪枝操作
|
||||||
|
if (nums[i] > 0 && nums[i] > target) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (i > 0 && nums[i - 1] == nums[i]) {
|
if (i > 0 && nums[i - 1] == nums[i]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -522,6 +527,51 @@ public class Solution
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Rust:
|
||||||
|
```Rust
|
||||||
|
impl Solution {
|
||||||
|
pub fn four_sum(nums: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
|
||||||
|
let mut result: Vec<Vec<i32>> = Vec::new();
|
||||||
|
let mut nums = nums;
|
||||||
|
nums.sort();
|
||||||
|
let len = nums.len();
|
||||||
|
for k in 0..len {
|
||||||
|
// 剪枝
|
||||||
|
if nums[k] > target && (nums[k] > 0 || target > 0) { break; }
|
||||||
|
// 去重
|
||||||
|
if k > 0 && nums[k] == nums[k - 1] { continue; }
|
||||||
|
for i in (k + 1)..len {
|
||||||
|
// 剪枝
|
||||||
|
if nums[k] + nums[i] > target && (nums[k] + nums[i] >= 0 || target >= 0) { break; }
|
||||||
|
// 去重
|
||||||
|
if i > k + 1 && nums[i] == nums[i - 1] { continue; }
|
||||||
|
let (mut left, mut right) = (i + 1, len - 1);
|
||||||
|
while left < right {
|
||||||
|
if nums[k] + nums[i] > target - (nums[left] + nums[right]) {
|
||||||
|
right -= 1;
|
||||||
|
// 去重
|
||||||
|
while left < right && nums[right] == nums[right + 1] { right -= 1; }
|
||||||
|
} else if nums[k] + nums[i] < target - (nums[left] + nums[right]) {
|
||||||
|
left += 1;
|
||||||
|
// 去重
|
||||||
|
while left < right && nums[left] == nums[left - 1] { left += 1; }
|
||||||
|
} else {
|
||||||
|
result.push(vec![nums[k], nums[i], nums[left], nums[right]]);
|
||||||
|
// 去重
|
||||||
|
while left < right && nums[right] == nums[right - 1] { right -= 1; }
|
||||||
|
while left < right && nums[left] == nums[left + 1] { left += 1; }
|
||||||
|
left += 1;
|
||||||
|
right -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Scala:
|
Scala:
|
||||||
```scala
|
```scala
|
||||||
object Solution {
|
object Solution {
|
||||||
|
@ -456,6 +456,36 @@ func permute(_ nums: [Int]) -> [[Int]] {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Scala
|
||||||
|
|
||||||
|
```scala
|
||||||
|
object Solution {
|
||||||
|
import scala.collection.mutable
|
||||||
|
def permute(nums: Array[Int]): List[List[Int]] = {
|
||||||
|
var result = mutable.ListBuffer[List[Int]]()
|
||||||
|
var path = mutable.ListBuffer[Int]()
|
||||||
|
|
||||||
|
def backtracking(used: Array[Boolean]): Unit = {
|
||||||
|
if (path.size == nums.size) {
|
||||||
|
// 如果path的长度和nums相等,那么可以添加到结果集
|
||||||
|
result.append(path.toList)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 添加循环守卫,只有当当前数字没有用过的情况下才进入回溯
|
||||||
|
for (i <- nums.indices if used(i) == false) {
|
||||||
|
used(i) = true
|
||||||
|
path.append(nums(i))
|
||||||
|
backtracking(used) // 回溯
|
||||||
|
path.remove(path.size - 1)
|
||||||
|
used(i) = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backtracking(new Array[Boolean](nums.size)) // 调用方法
|
||||||
|
result.toList // 最终返回结果集的List形式
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -422,5 +422,43 @@ int** permuteUnique(int* nums, int numsSize, int* returnSize, int** returnColumn
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Scala
|
||||||
|
|
||||||
|
```scala
|
||||||
|
object Solution {
|
||||||
|
import scala.collection.mutable
|
||||||
|
def permuteUnique(nums: Array[Int]): List[List[Int]] = {
|
||||||
|
var result = mutable.ListBuffer[List[Int]]()
|
||||||
|
var path = mutable.ListBuffer[Int]()
|
||||||
|
var num = nums.sorted // 首先对数据进行排序
|
||||||
|
|
||||||
|
def backtracking(used: Array[Boolean]): Unit = {
|
||||||
|
if (path.size == num.size) {
|
||||||
|
// 如果path的size等于num了,那么可以添加到结果集
|
||||||
|
result.append(path.toList)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 循环守卫,当前元素没被使用过就进入循环体
|
||||||
|
for (i <- num.indices if used(i) == false) {
|
||||||
|
// 当前索引为0,不存在和前一个数字相等可以进入回溯
|
||||||
|
// 当前索引值和上一个索引不相等,可以回溯
|
||||||
|
// 前一个索引对应的值没有被选,可以回溯
|
||||||
|
// 因为Scala没有continue,只能将逻辑反过来写
|
||||||
|
if (i == 0 || (i > 0 && num(i) != num(i - 1)) || used(i-1) == false) {
|
||||||
|
used(i) = true
|
||||||
|
path.append(num(i))
|
||||||
|
backtracking(used)
|
||||||
|
path.remove(path.size - 1)
|
||||||
|
used(i) = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backtracking(new Array[Boolean](nums.length))
|
||||||
|
result.toList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -455,7 +455,7 @@ var solveNQueens = function(n) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
## TypeScript
|
### TypeScript
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
function solveNQueens(n: number): string[][] {
|
function solveNQueens(n: number): string[][] {
|
||||||
@ -683,5 +683,77 @@ char *** solveNQueens(int n, int* returnSize, int** returnColumnSizes){
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Scala
|
||||||
|
|
||||||
|
```scala
|
||||||
|
object Solution {
|
||||||
|
import scala.collection.mutable
|
||||||
|
def solveNQueens(n: Int): List[List[String]] = {
|
||||||
|
var result = mutable.ListBuffer[List[String]]()
|
||||||
|
|
||||||
|
def judge(x: Int, y: Int, maze: Array[Array[Boolean]]): Boolean = {
|
||||||
|
// 正上方
|
||||||
|
var xx = x
|
||||||
|
while (xx >= 0) {
|
||||||
|
if (maze(xx)(y)) return false
|
||||||
|
xx -= 1
|
||||||
|
}
|
||||||
|
// 左边
|
||||||
|
var yy = y
|
||||||
|
while (yy >= 0) {
|
||||||
|
if (maze(x)(yy)) return false
|
||||||
|
yy -= 1
|
||||||
|
}
|
||||||
|
// 左上方
|
||||||
|
xx = x
|
||||||
|
yy = y
|
||||||
|
while (xx >= 0 && yy >= 0) {
|
||||||
|
if (maze(xx)(yy)) return false
|
||||||
|
xx -= 1
|
||||||
|
yy -= 1
|
||||||
|
}
|
||||||
|
xx = x
|
||||||
|
yy = y
|
||||||
|
// 右上方
|
||||||
|
while (xx >= 0 && yy < n) {
|
||||||
|
if (maze(xx)(yy)) return false
|
||||||
|
xx -= 1
|
||||||
|
yy += 1
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
def backtracking(row: Int, maze: Array[Array[Boolean]]): Unit = {
|
||||||
|
if (row == n) {
|
||||||
|
// 将结果转换为题目所需要的形式
|
||||||
|
var path = mutable.ListBuffer[String]()
|
||||||
|
for (x <- maze) {
|
||||||
|
var tmp = mutable.ListBuffer[String]()
|
||||||
|
for (y <- x) {
|
||||||
|
if (y == true) tmp.append("Q")
|
||||||
|
else tmp.append(".")
|
||||||
|
}
|
||||||
|
path.append(tmp.mkString)
|
||||||
|
}
|
||||||
|
result.append(path.toList)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j <- 0 until n) {
|
||||||
|
// 判断这个位置是否可以放置皇后
|
||||||
|
if (judge(row, j, maze)) {
|
||||||
|
maze(row)(j) = true
|
||||||
|
backtracking(row + 1, maze)
|
||||||
|
maze(row)(j) = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backtracking(0, Array.ofDim[Boolean](n, n))
|
||||||
|
result.toList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -136,24 +136,38 @@ public:
|
|||||||
|
|
||||||
### Java
|
### Java
|
||||||
```java
|
```java
|
||||||
|
|
||||||
|
/**
|
||||||
|
时间复杂度 : O(NlogN) 排序需要O(NlogN)
|
||||||
|
空间复杂度 : O(logN) java 的内置排序是快速排序 需要 O(logN)空间
|
||||||
|
|
||||||
|
*/
|
||||||
class Solution {
|
class Solution {
|
||||||
public int[][] merge(int[][] intervals) {
|
public int[][] merge(int[][] intervals) {
|
||||||
List<int[]> res = new LinkedList<>();
|
List<int[]> res = new LinkedList<>();
|
||||||
Arrays.sort(intervals, (o1, o2) -> Integer.compare(o1[0], o2[0]));
|
//按照左边界排序
|
||||||
|
Arrays.sort(intervals, (x, y) -> Integer.compare(x[0], y[0]));
|
||||||
|
//initial start 是最小左边界
|
||||||
int start = intervals[0][0];
|
int start = intervals[0][0];
|
||||||
|
int rightmostRightBound = intervals[0][1];
|
||||||
for (int i = 1; i < intervals.length; i++) {
|
for (int i = 1; i < intervals.length; i++) {
|
||||||
if (intervals[i][0] > intervals[i - 1][1]) {
|
//如果左边界大于最大右边界
|
||||||
res.add(new int[]{start, intervals[i - 1][1]});
|
if (intervals[i][0] > rightmostRightBound) {
|
||||||
|
//加入区间 并且更新start
|
||||||
|
res.add(new int[]{start, rightmostRightBound});
|
||||||
start = intervals[i][0];
|
start = intervals[i][0];
|
||||||
|
rightmostRightBound = intervals[i][1];
|
||||||
} else {
|
} else {
|
||||||
intervals[i][1] = Math.max(intervals[i][1], intervals[i - 1][1]);
|
//更新最大右边界
|
||||||
|
rightmostRightBound = Math.max(rightmostRightBound, intervals[i][1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.add(new int[]{start, intervals[intervals.length - 1][1]});
|
res.add(new int[]{start, rightmostRightBound});
|
||||||
return res.toArray(new int[res.size()][]);
|
return res.toArray(new int[res.size()][]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
```
|
```
|
||||||
```java
|
```java
|
||||||
// 版本2
|
// 版本2
|
||||||
|
@ -373,6 +373,60 @@ func subsets(_ nums: [Int]) -> [[Int]] {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Scala
|
||||||
|
|
||||||
|
思路一: 使用本题解思路
|
||||||
|
|
||||||
|
```scala
|
||||||
|
object Solution {
|
||||||
|
import scala.collection.mutable
|
||||||
|
def subsets(nums: Array[Int]): List[List[Int]] = {
|
||||||
|
var result = mutable.ListBuffer[List[Int]]()
|
||||||
|
var path = mutable.ListBuffer[Int]()
|
||||||
|
|
||||||
|
def backtracking(startIndex: Int): Unit = {
|
||||||
|
result.append(path.toList) // 存放结果
|
||||||
|
if (startIndex >= nums.size) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (i <- startIndex until nums.size) {
|
||||||
|
path.append(nums(i)) // 添加元素
|
||||||
|
backtracking(i + 1)
|
||||||
|
path.remove(path.size - 1) // 删除
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backtracking(0)
|
||||||
|
result.toList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
思路二: 将原问题转换为二叉树,针对每一个元素都有**选或不选**两种选择,直到遍历到最后,所有的叶子节点即为本题的答案:
|
||||||
|
|
||||||
|
```scala
|
||||||
|
object Solution {
|
||||||
|
import scala.collection.mutable
|
||||||
|
def subsets(nums: Array[Int]): List[List[Int]] = {
|
||||||
|
var result = mutable.ListBuffer[List[Int]]()
|
||||||
|
|
||||||
|
def backtracking(path: mutable.ListBuffer[Int], startIndex: Int): Unit = {
|
||||||
|
if (startIndex == nums.length) {
|
||||||
|
result.append(path.toList)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
path.append(nums(startIndex))
|
||||||
|
backtracking(path, startIndex + 1) // 选择元素
|
||||||
|
path.remove(path.size - 1)
|
||||||
|
backtracking(path, startIndex + 1) // 不选择元素
|
||||||
|
}
|
||||||
|
|
||||||
|
backtracking(mutable.ListBuffer[Int](), 0)
|
||||||
|
result.toList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -434,6 +434,63 @@ func subsetsWithDup(_ nums: [Int]) -> [[Int]] {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Scala
|
||||||
|
|
||||||
|
不使用userd数组:
|
||||||
|
|
||||||
|
```scala
|
||||||
|
object Solution {
|
||||||
|
import scala.collection.mutable
|
||||||
|
def subsetsWithDup(nums: Array[Int]): List[List[Int]] = {
|
||||||
|
var result = mutable.ListBuffer[List[Int]]()
|
||||||
|
var path = mutable.ListBuffer[Int]()
|
||||||
|
var num = nums.sorted // 排序
|
||||||
|
|
||||||
|
def backtracking(startIndex: Int): Unit = {
|
||||||
|
result.append(path.toList)
|
||||||
|
if (startIndex >= num.size){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (i <- startIndex until num.size) {
|
||||||
|
// 同一树层重复的元素不进入回溯
|
||||||
|
if (!(i > startIndex && num(i) == num(i - 1))) {
|
||||||
|
path.append(num(i))
|
||||||
|
backtracking(i + 1)
|
||||||
|
path.remove(path.size - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backtracking(0)
|
||||||
|
result.toList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
使用Set去重:
|
||||||
|
```scala
|
||||||
|
object Solution {
|
||||||
|
import scala.collection.mutable
|
||||||
|
def subsetsWithDup(nums: Array[Int]): List[List[Int]] = {
|
||||||
|
var result = mutable.Set[List[Int]]()
|
||||||
|
var num = nums.sorted
|
||||||
|
def backtracking(path: mutable.ListBuffer[Int], startIndex: Int): Unit = {
|
||||||
|
if (startIndex == num.length) {
|
||||||
|
result.add(path.toList)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
path.append(num(startIndex))
|
||||||
|
backtracking(path, startIndex + 1) // 选择
|
||||||
|
path.remove(path.size - 1)
|
||||||
|
backtracking(path, startIndex + 1) // 不选择
|
||||||
|
}
|
||||||
|
|
||||||
|
backtracking(mutable.ListBuffer[Int](), 0)
|
||||||
|
|
||||||
|
result.toList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -2629,21 +2629,21 @@ JavaScript:
|
|||||||
var minDepth = function(root) {
|
var minDepth = function(root) {
|
||||||
if (root === null) return 0;
|
if (root === null) return 0;
|
||||||
let queue = [root];
|
let queue = [root];
|
||||||
let deepth = 0;
|
let depth = 0;
|
||||||
while (queue.length) {
|
while (queue.length) {
|
||||||
let n = queue.length;
|
let n = queue.length;
|
||||||
deepth++;
|
depth++;
|
||||||
for (let i=0; i<n; i++) {
|
for (let i=0; i<n; i++) {
|
||||||
let node = queue.shift();
|
let node = queue.shift();
|
||||||
// 如果左右节点都是null,则该节点深度最小
|
// 如果左右节点都是null(在遇见的第一个leaf节点上),则该节点深度最小
|
||||||
if (node.left === null && node.right === null) {
|
if (node.left === null && node.right === null) {
|
||||||
return deepth;
|
return depth;
|
||||||
}
|
}
|
||||||
node.left && queue.push(node.left);;
|
node.left && queue.push(node.left);;
|
||||||
node.right && queue.push (node.right);
|
node.right && queue.push(node.right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return deepth;
|
return depth;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -294,14 +294,13 @@ class solution {
|
|||||||
/**
|
/**
|
||||||
* 递归法
|
* 递归法
|
||||||
*/
|
*/
|
||||||
public int maxdepth(treenode root) {
|
public int maxDepth(TreeNode root) {
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int leftdepth = maxdepth(root.left);
|
int leftDepth = maxDepth(root.left);
|
||||||
int rightdepth = maxdepth(root.right);
|
int rightDepth = maxDepth(root.right);
|
||||||
return math.max(leftdepth, rightdepth) + 1;
|
return Math.max(leftDepth, rightDepth) + 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -311,23 +310,23 @@ class solution {
|
|||||||
/**
|
/**
|
||||||
* 迭代法,使用层序遍历
|
* 迭代法,使用层序遍历
|
||||||
*/
|
*/
|
||||||
public int maxdepth(treenode root) {
|
public int maxDepth(TreeNode root) {
|
||||||
if(root == null) {
|
if(root == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
deque<treenode> deque = new linkedlist<>();
|
Deque<TreeNode> deque = new LinkedList<>();
|
||||||
deque.offer(root);
|
deque.offer(root);
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
while (!deque.isempty()) {
|
while (!deque.isEmpty()) {
|
||||||
int size = deque.size();
|
int size = deque.size();
|
||||||
depth++;
|
depth++;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
treenode poll = deque.poll();
|
TreeNode node = deque.poll();
|
||||||
if (poll.left != null) {
|
if (node.left != null) {
|
||||||
deque.offer(poll.left);
|
deque.offer(node.left);
|
||||||
}
|
}
|
||||||
if (poll.right != null) {
|
if (node.right != null) {
|
||||||
deque.offer(poll.right);
|
deque.offer(node.right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
<img src="https://code-thinking-1253855093.file.myqcloud.com/pics/20210924105952.png" width="1000"/>
|
<img src="https://code-thinking-1253855093.file.myqcloud.com/pics/20210924105952.png" width="1000"/>
|
||||||
</a>
|
</a>
|
||||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 129. 求根节点到叶节点数字之和
|
# 129. 求根节点到叶节点数字之和
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode.cn/problems/sum-root-to-leaf-numbers/)
|
[力扣题目链接](https://leetcode.cn/problems/sum-root-to-leaf-numbers/)
|
||||||
@ -245,6 +248,29 @@ class Solution:
|
|||||||
```
|
```
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func sumNumbers(root *TreeNode) int {
|
||||||
|
sum = 0
|
||||||
|
travel(root, root.Val)
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
func travel(root *TreeNode, tmpSum int) {
|
||||||
|
if root.Left == nil && root.Right == nil {
|
||||||
|
sum += tmpSum
|
||||||
|
} else {
|
||||||
|
if root.Left != nil {
|
||||||
|
travel(root.Left, tmpSum*10+root.Left.Val)
|
||||||
|
}
|
||||||
|
if root.Right != nil {
|
||||||
|
travel(root.Right, tmpSum*10+root.Right.Val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JavaScript:
|
JavaScript:
|
||||||
```javascript
|
```javascript
|
||||||
var sumNumbers = function(root) {
|
var sumNumbers = function(root) {
|
||||||
|
@ -206,6 +206,55 @@ public:
|
|||||||
## Java
|
## Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
class Solution {
|
||||||
|
|
||||||
|
public int minCut(String s) {
|
||||||
|
if(null == s || "".equals(s)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int len = s.length();
|
||||||
|
// 1.
|
||||||
|
// 记录子串[i..j]是否是回文串
|
||||||
|
boolean[][] isPalindromic = new boolean[len][len];
|
||||||
|
// 从下到上,从左到右
|
||||||
|
for(int i = len - 1; i >= 0; i--){
|
||||||
|
for(int j = i; j < len; j++){
|
||||||
|
if(s.charAt(i) == s.charAt(j)){
|
||||||
|
if(j - i <= 1){
|
||||||
|
isPalindromic[i][j] = true;
|
||||||
|
} else{
|
||||||
|
isPalindromic[i][j] = isPalindromic[i + 1][j - 1];
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
isPalindromic[i][j] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.
|
||||||
|
// dp[i] 表示[0..i]的最小分割次数
|
||||||
|
int[] dp = new int[len];
|
||||||
|
for(int i = 0; i < len; i++){
|
||||||
|
//初始考虑最坏的情况。 1个字符分割0次, len个字符分割 len - 1次
|
||||||
|
dp[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 1; i < len; i++){
|
||||||
|
if(isPalindromic[0][i]){
|
||||||
|
// s[0..i]是回文了,那 dp[i] = 0, 一次也不用分割
|
||||||
|
dp[i] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for(int j = 0; j < i; j++){
|
||||||
|
// 按文中的思路,不清楚就拿 "ababa" 为例,先写出 isPalindromic 数组,再进行求解
|
||||||
|
if(isPalindromic[j + 1][i]){
|
||||||
|
dp[i] = Math.min(dp[i], dp[j] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[len - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
@ -240,6 +289,7 @@ class Solution:
|
|||||||
## Go
|
## Go
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## JavaScript
|
## JavaScript
|
||||||
|
@ -315,6 +315,36 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Rust:
|
||||||
|
```Rust
|
||||||
|
use std::collections::HashSet;
|
||||||
|
impl Solution {
|
||||||
|
pub fn get_sum(mut n: i32) -> i32 {
|
||||||
|
let mut sum = 0;
|
||||||
|
while n > 0 {
|
||||||
|
sum += (n % 10) * (n % 10);
|
||||||
|
n /= 10;
|
||||||
|
}
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_happy(n: i32) -> bool {
|
||||||
|
let mut n = n;
|
||||||
|
let mut set = HashSet::new();
|
||||||
|
loop {
|
||||||
|
let sum = Self::get_sum(n);
|
||||||
|
if sum == 1 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if set.contains(&sum) {
|
||||||
|
return false;
|
||||||
|
} else { set.insert(sum); }
|
||||||
|
n = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
C:
|
C:
|
||||||
```C
|
```C
|
||||||
typedef struct HashNodeTag {
|
typedef struct HashNodeTag {
|
||||||
|
@ -156,6 +156,28 @@ var isIsomorphic = function(s, t) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TypeScript
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function isIsomorphic(s: string, t: string): boolean {
|
||||||
|
const helperMap1: Map<string, string> = new Map();
|
||||||
|
const helperMap2: Map<string, string> = new Map();
|
||||||
|
for (let i = 0, length = s.length; i < length; i++) {
|
||||||
|
let temp1: string | undefined = helperMap1.get(s[i]);
|
||||||
|
let temp2: string | undefined = helperMap2.get(t[i]);
|
||||||
|
if (temp1 === undefined && temp2 === undefined) {
|
||||||
|
helperMap1.set(s[i], t[i]);
|
||||||
|
helperMap2.set(t[i], s[i]);
|
||||||
|
} else if (temp1 !== t[i] || temp2 !== s[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -470,25 +470,14 @@ func invertTree(root *TreeNode) *TreeNode {
|
|||||||
使用递归版本的前序遍历
|
使用递归版本的前序遍历
|
||||||
```javascript
|
```javascript
|
||||||
var invertTree = function(root) {
|
var invertTree = function(root) {
|
||||||
//1. 首先使用递归版本的前序遍历实现二叉树翻转
|
// 终止条件
|
||||||
//交换节点函数
|
if (!root) {
|
||||||
const inverNode=function(left,right){
|
return null;
|
||||||
let temp=left;
|
|
||||||
left=right;
|
|
||||||
right=temp;
|
|
||||||
//需要重新给root赋值一下
|
|
||||||
root.left=left;
|
|
||||||
root.right=right;
|
|
||||||
}
|
}
|
||||||
//确定递归函数的参数和返回值inverTree=function(root)
|
// 交换左右节点
|
||||||
//确定终止条件
|
const rightNode = root.right;
|
||||||
if(root===null){
|
root.right = invertTree(root.left);
|
||||||
return root;
|
root.left = invertTree(rightNode);
|
||||||
}
|
|
||||||
//确定节点处理逻辑 交换
|
|
||||||
inverNode(root.left,root.right);
|
|
||||||
invertTree(root.left);
|
|
||||||
invertTree(root.right);
|
|
||||||
return root;
|
return root;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
@ -141,13 +141,10 @@ class Solution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
|
Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
|
||||||
// 根据map的value值正序排,相当于一个小顶堆
|
// 根据map的value值,构建于一个大顶堆(o1 - o2: 小顶堆, o2 - o1 : 大顶堆)
|
||||||
PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((o1, o2) -> o1.getValue() - o2.getValue());
|
PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((o1, o2) -> o2.getValue() - o1.getValue());
|
||||||
for (Map.Entry<Integer, Integer> entry : entries) {
|
for (Map.Entry<Integer, Integer> entry : entries) {
|
||||||
queue.offer(entry);
|
queue.offer(entry);
|
||||||
if (queue.size() > k) {
|
|
||||||
queue.poll();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int i = k - 1; i >= 0; i--) {
|
for (int i = k - 1; i >= 0; i--) {
|
||||||
result[i] = queue.poll().getKey();
|
result[i] = queue.poll().getKey();
|
||||||
|
@ -456,31 +456,42 @@ func deleteNode(root *TreeNode, key int) *TreeNode {
|
|||||||
* @param {number} key
|
* @param {number} key
|
||||||
* @return {TreeNode}
|
* @return {TreeNode}
|
||||||
*/
|
*/
|
||||||
var deleteNode = function (root, key) {
|
var deleteNode = function(root, key) {
|
||||||
if (root === null)
|
if (!root) return null;
|
||||||
return root;
|
if (key > root.val) {
|
||||||
if (root.val === key) {
|
|
||||||
if (!root.left)
|
|
||||||
return root.right;
|
|
||||||
else if (!root.right)
|
|
||||||
return root.left;
|
|
||||||
else {
|
|
||||||
let cur = root.right;
|
|
||||||
while (cur.left) {
|
|
||||||
cur = cur.left;
|
|
||||||
}
|
|
||||||
cur.left = root.left;
|
|
||||||
root = root.right;
|
|
||||||
delete root;
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (root.val > key)
|
|
||||||
root.left = deleteNode(root.left, key);
|
|
||||||
if (root.val < key)
|
|
||||||
root.right = deleteNode(root.right, key);
|
root.right = deleteNode(root.right, key);
|
||||||
return root;
|
return root;
|
||||||
|
} else if (key < root.val) {
|
||||||
|
root.left = deleteNode(root.left, key);
|
||||||
|
return root;
|
||||||
|
} else {
|
||||||
|
// 场景1: 该节点是叶节点
|
||||||
|
if (!root.left && !root.right) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
// 场景2: 有一个孩子节点不存在
|
||||||
|
if (root.left && !root.right) {
|
||||||
|
return root.left;
|
||||||
|
} else if (root.right && !root.left) {
|
||||||
|
return root.right;
|
||||||
|
}
|
||||||
|
// 场景3: 左右节点都存在
|
||||||
|
const rightNode = root.right;
|
||||||
|
// 获取最小值节点
|
||||||
|
const minNode = getMinNode(rightNode);
|
||||||
|
// 将待删除节点的值替换为最小值节点值
|
||||||
|
root.val = minNode.val;
|
||||||
|
// 删除最小值节点
|
||||||
|
root.right = deleteNode(root.right, minNode.val);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
function getMinNode(root) {
|
||||||
|
while (root.left) {
|
||||||
|
root = root.left;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
迭代
|
迭代
|
||||||
|
@ -136,17 +136,28 @@ public:
|
|||||||
|
|
||||||
### Java
|
### Java
|
||||||
```java
|
```java
|
||||||
|
/**
|
||||||
|
时间复杂度 : O(NlogN) 排序需要 O(NlogN) 的复杂度
|
||||||
|
|
||||||
|
空间复杂度 : O(logN) java所使用的内置函数用的是快速排序需要 logN 的空间
|
||||||
|
*/
|
||||||
class Solution {
|
class Solution {
|
||||||
public int findMinArrowShots(int[][] points) {
|
public int findMinArrowShots(int[][] points) {
|
||||||
if (points.length == 0) return 0;
|
if (points.length == 0) return 0;
|
||||||
Arrays.sort(points, (o1, o2) -> Integer.compare(o1[0], o2[0]));
|
//用x[0] - y[0] 会大于2147483647 造成整型溢出
|
||||||
|
Arrays.sort(points, (x, y) -> Integer.compare(x[0], y[0]));
|
||||||
|
//count = 1 因为最少需要一个箭来射击第一个气球
|
||||||
int count = 1;
|
int count = 1;
|
||||||
for (int i = 1; i < points.length; i++) {
|
//重叠气球的最小右边界
|
||||||
if (points[i][0] > points[i - 1][1]) {
|
int leftmostRightBound = points[0][1];
|
||||||
|
//如果下一个气球的左边界大于最小右边界
|
||||||
|
if (points[i][0] > leftmostRightBound ) {
|
||||||
|
//增加一次射击
|
||||||
count++;
|
count++;
|
||||||
|
leftmostRightBound = points[i][1];
|
||||||
|
//不然就更新最小右边界
|
||||||
} else {
|
} else {
|
||||||
points[i][1] = Math.min(points[i][1],points[i - 1][1]);
|
leftmostRightBound = Math.min(leftmostRightBound , points[i][1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
@ -522,5 +522,39 @@ func findSubsequences(_ nums: [Int]) -> [[Int]] {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Scala
|
||||||
|
|
||||||
|
```scala
|
||||||
|
object Solution {
|
||||||
|
import scala.collection.mutable
|
||||||
|
def findSubsequences(nums: Array[Int]): List[List[Int]] = {
|
||||||
|
var result = mutable.ListBuffer[List[Int]]()
|
||||||
|
var path = mutable.ListBuffer[Int]()
|
||||||
|
|
||||||
|
def backtracking(startIndex: Int): Unit = {
|
||||||
|
// 集合元素大于1,添加到结果集
|
||||||
|
if (path.size > 1) {
|
||||||
|
result.append(path.toList)
|
||||||
|
}
|
||||||
|
|
||||||
|
var used = new Array[Boolean](201)
|
||||||
|
// 使用循环守卫,当前层没有用过的元素才有资格进入回溯
|
||||||
|
for (i <- startIndex until nums.size if !used(nums(i) + 100)) {
|
||||||
|
// 如果path没元素或 当前循环的元素比path的最后一个元素大,则可以进入回溯
|
||||||
|
if (path.size == 0 || (!path.isEmpty && nums(i) >= path(path.size - 1))) {
|
||||||
|
used(nums(i) + 100) = true
|
||||||
|
path.append(nums(i))
|
||||||
|
backtracking(i + 1)
|
||||||
|
path.remove(path.size - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backtracking(0)
|
||||||
|
result.toList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -106,6 +106,7 @@ class Solution {
|
|||||||
int index = result.length - 1;
|
int index = result.length - 1;
|
||||||
while (left <= right) {
|
while (left <= right) {
|
||||||
if (nums[left] * nums[left] > nums[right] * nums[right]) {
|
if (nums[left] * nums[left] > nums[right] * nums[right]) {
|
||||||
|
// 正数的相对位置是不变的, 需要调整的是负数平方后的相对位置
|
||||||
result[index--] = nums[left] * nums[left];
|
result[index--] = nums[left] * nums[left];
|
||||||
++left;
|
++left;
|
||||||
} else {
|
} else {
|
||||||
|
@ -129,6 +129,9 @@ public:
|
|||||||
Java:
|
Java:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
/*
|
||||||
|
二维dp数组
|
||||||
|
*/
|
||||||
class Solution {
|
class Solution {
|
||||||
public int longestCommonSubsequence(String text1, String text2) {
|
public int longestCommonSubsequence(String text1, String text2) {
|
||||||
int[][] dp = new int[text1.length() + 1][text2.length() + 1]; // 先对dp数组做初始化操作
|
int[][] dp = new int[text1.length() + 1][text2.length() + 1]; // 先对dp数组做初始化操作
|
||||||
@ -146,6 +149,47 @@ class Solution {
|
|||||||
return dp[text1.length()][text2.length()];
|
return dp[text1.length()][text2.length()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
一维dp数组
|
||||||
|
*/
|
||||||
|
class Solution {
|
||||||
|
public int longestCommonSubsequence(String text1, String text2) {
|
||||||
|
int n1 = text1.length();
|
||||||
|
int n2 = text2.length();
|
||||||
|
|
||||||
|
// 多从二维dp数组过程分析
|
||||||
|
// 关键在于 如果记录 dp[i - 1][j - 1]
|
||||||
|
// 因为 dp[i - 1][j - 1] <!=> dp[j - 1] <=> dp[i][j - 1]
|
||||||
|
int [] dp = new int[n2 + 1];
|
||||||
|
|
||||||
|
for(int i = 1; i <= n1; i++){
|
||||||
|
|
||||||
|
// 这里pre相当于 dp[i - 1][j - 1]
|
||||||
|
int pre = dp[0];
|
||||||
|
for(int j = 1; j <= n2; j++){
|
||||||
|
|
||||||
|
//用于给pre赋值
|
||||||
|
int cur = dp[j];
|
||||||
|
if(text1.charAt(i - 1) == text2.charAt(j - 1)){
|
||||||
|
//这里pre相当于dp[i - 1][j - 1] 千万不能用dp[j - 1] !!
|
||||||
|
dp[j] = pre + 1;
|
||||||
|
} else{
|
||||||
|
// dp[j] 相当于 dp[i - 1][j]
|
||||||
|
// dp[j - 1] 相当于 dp[i][j - 1]
|
||||||
|
dp[j] = Math.max(dp[j], dp[j - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新dp[i - 1][j - 1], 为下次使用做准备
|
||||||
|
pre = cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[n2];
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
Reference in New Issue
Block a user