mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 16:54:50 +08:00
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
@ -207,18 +207,16 @@ function twoSum(array $nums, int $target): array
|
|||||||
Swift:
|
Swift:
|
||||||
```swift
|
```swift
|
||||||
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
|
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
|
||||||
var res = [Int]()
|
// 值: 下标
|
||||||
var dict = [Int : Int]()
|
var map = [Int: Int]()
|
||||||
for i in 0 ..< nums.count {
|
for (i, e) in nums.enumerated() {
|
||||||
let other = target - nums[i]
|
if let v = map[target - e] {
|
||||||
if dict.keys.contains(other) {
|
return [v, i]
|
||||||
res.append(i)
|
} else {
|
||||||
res.append(dict[other]!)
|
map[e] = i
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
dict[nums[i]] = i
|
|
||||||
}
|
}
|
||||||
return res
|
return []
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -197,7 +197,23 @@ var removeElement = (nums, val) => {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function removeElement(nums: number[], val: number): number {
|
||||||
|
let slowIndex: number = 0, fastIndex: number = 0;
|
||||||
|
while (fastIndex < nums.length) {
|
||||||
|
if (nums[fastIndex] !== val) {
|
||||||
|
nums[slowIndex++] = nums[fastIndex];
|
||||||
|
}
|
||||||
|
fastIndex++;
|
||||||
|
}
|
||||||
|
return slowIndex;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Ruby:
|
Ruby:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
def remove_element(nums, val)
|
def remove_element(nums, val)
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -649,6 +649,41 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
//前缀表(不减一)Java实现
|
||||||
|
public int strStr(String haystack, String needle) {
|
||||||
|
if (needle.length() == 0) return 0;
|
||||||
|
int[] next = new int[needle.length()];
|
||||||
|
getNext(next, needle);
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < haystack.length(); i++) {
|
||||||
|
while (j > 0 && needle.charAt(j) != haystack.charAt(i))
|
||||||
|
j = next[j - 1];
|
||||||
|
if (needle.charAt(j) == haystack.charAt(i))
|
||||||
|
j++;
|
||||||
|
if (j == needle.length())
|
||||||
|
return i - needle.length() + 1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getNext(int[] next, String s) {
|
||||||
|
int j = 0;
|
||||||
|
next[0] = 0;
|
||||||
|
for (int i = 1; i < s.length(); i++) {
|
||||||
|
while (j > 0 && s.charAt(j) != s.charAt(i))
|
||||||
|
j = next[j - 1];
|
||||||
|
if (s.charAt(j) == s.charAt(i))
|
||||||
|
j++;
|
||||||
|
next[i] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python3:
|
Python3:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@ -86,7 +86,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 到这里了说明整个数组都是倒叙了,反转一下便可
|
// 到这里了说明整个数组都是倒序了,反转一下便可
|
||||||
reverse(nums.begin(), nums.end());
|
reverse(nums.begin(), nums.end());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -255,6 +255,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
## Java
|
## Java
|
||||||
|
**使用标记数组**
|
||||||
```Java
|
```Java
|
||||||
class Solution {
|
class Solution {
|
||||||
List<List<Integer>> lists = new ArrayList<>();
|
List<List<Integer>> lists = new ArrayList<>();
|
||||||
@ -292,6 +293,44 @@ class Solution {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
**不使用标记数组**
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
List<List<Integer>> res = new ArrayList<>();
|
||||||
|
LinkedList<Integer> path = new LinkedList<>();
|
||||||
|
int sum = 0;
|
||||||
|
|
||||||
|
public List<List<Integer>> combinationSum2( int[] candidates, int target ) {
|
||||||
|
//为了将重复的数字都放到一起,所以先进行排序
|
||||||
|
Arrays.sort( candidates );
|
||||||
|
backTracking( candidates, target, 0 );
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void backTracking( int[] candidates, int target, int start ) {
|
||||||
|
if ( sum == target ) {
|
||||||
|
res.add( new ArrayList<>( path ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for ( int i = start; i < candidates.length && sum + candidates[i] <= target; i++ ) {
|
||||||
|
//正确剔除重复解的办法
|
||||||
|
//跳过同一树层使用过的元素
|
||||||
|
if ( i > start && candidates[i] == candidates[i - 1] ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sum += candidates[i];
|
||||||
|
path.add( candidates[i] );
|
||||||
|
// i+1 代表当前组内元素只选取一次
|
||||||
|
backTracking( candidates, target, i + 1 );
|
||||||
|
|
||||||
|
int temp = path.getLast();
|
||||||
|
sum -= temp;
|
||||||
|
path.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
**回溯+巧妙去重(省去使用used**
|
**回溯+巧妙去重(省去使用used**
|
||||||
@ -384,6 +423,7 @@ class Solution:
|
|||||||
## Go
|
## Go
|
||||||
主要在于如何在回溯中去重
|
主要在于如何在回溯中去重
|
||||||
|
|
||||||
|
**使用used数组**
|
||||||
```go
|
```go
|
||||||
func combinationSum2(candidates []int, target int) [][]int {
|
func combinationSum2(candidates []int, target int) [][]int {
|
||||||
var trcak []int
|
var trcak []int
|
||||||
@ -423,7 +463,41 @@ func backtracking(startIndex,sum,target int,candidates,trcak []int,res *[][]int,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
**不使用used数组**
|
||||||
|
```go
|
||||||
|
func combinationSum2(candidates []int, target int) [][]int {
|
||||||
|
var trcak []int
|
||||||
|
var res [][]int
|
||||||
|
sort.Ints(candidates)
|
||||||
|
backtracking(0,0,target,candidates,trcak,&res)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
func backtracking(startIndex,sum,target int,candidates,trcak []int,res *[][]int){
|
||||||
|
//终止条件
|
||||||
|
if sum==target{
|
||||||
|
tmp:=make([]int,len(trcak))
|
||||||
|
//拷贝
|
||||||
|
copy(tmp,trcak)
|
||||||
|
//放入结果集
|
||||||
|
*res=append(*res,tmp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//回溯
|
||||||
|
for i:=startIndex;i<len(candidates) && sum+candidates[i]<=target;i++{
|
||||||
|
// 若当前树层有使用过相同的元素,则跳过
|
||||||
|
if i>startIndex&&candidates[i]==candidates[i-1]{
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
//更新路径集合和sum
|
||||||
|
trcak=append(trcak,candidates[i])
|
||||||
|
sum+=candidates[i]
|
||||||
|
backtracking(i+1,sum,target,candidates,trcak,res)
|
||||||
|
//回溯
|
||||||
|
trcak=trcak[:len(trcak)-1]
|
||||||
|
sum-=candidates[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
## javaScript
|
## javaScript
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -323,5 +323,76 @@ func permuteUnique(_ nums: [Int]) -> [[Int]] {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### C
|
||||||
|
```c
|
||||||
|
//临时数组
|
||||||
|
int *path;
|
||||||
|
//返回数组
|
||||||
|
int **ans;
|
||||||
|
int *used;
|
||||||
|
int pathTop, ansTop;
|
||||||
|
|
||||||
|
//拷贝path到ans中
|
||||||
|
void copyPath() {
|
||||||
|
int *tempPath = (int*)malloc(sizeof(int) * pathTop);
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < pathTop; ++i) {
|
||||||
|
tempPath[i] = path[i];
|
||||||
|
}
|
||||||
|
ans[ansTop++] = tempPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void backTracking(int* used, int *nums, int numsSize) {
|
||||||
|
//若path中元素个数等于numsSize,将path拷贝入ans数组中
|
||||||
|
if(pathTop == numsSize)
|
||||||
|
copyPath();
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < numsSize; i++) {
|
||||||
|
//若当前元素已被使用
|
||||||
|
//或前一位元素与当前元素值相同但并未被使用
|
||||||
|
//则跳过此分支
|
||||||
|
if(used[i] || (i != 0 && nums[i] == nums[i-1] && used[i-1] == 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//将当前元素的使用情况设为True
|
||||||
|
used[i] = 1;
|
||||||
|
path[pathTop++] = nums[i];
|
||||||
|
backTracking(used, nums, numsSize);
|
||||||
|
used[i] = 0;
|
||||||
|
--pathTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmp(void* elem1, void* elem2) {
|
||||||
|
return *((int*)elem1) - *((int*)elem2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int** permuteUnique(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
|
||||||
|
//排序数组
|
||||||
|
qsort(nums, numsSize, sizeof(int), cmp);
|
||||||
|
//初始化辅助变量
|
||||||
|
pathTop = ansTop = 0;
|
||||||
|
path = (int*)malloc(sizeof(int) * numsSize);
|
||||||
|
ans = (int**)malloc(sizeof(int*) * 1000);
|
||||||
|
//初始化used辅助数组
|
||||||
|
used = (int*)malloc(sizeof(int) * numsSize);
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < numsSize; i++) {
|
||||||
|
used[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
backTracking(used, nums, numsSize);
|
||||||
|
|
||||||
|
//设置返回的数组的长度
|
||||||
|
*returnSize = ansTop;
|
||||||
|
*returnColumnSizes = (int*)malloc(sizeof(int) * ansTop);
|
||||||
|
int z;
|
||||||
|
for(z = 0; z < ansTop; z++) {
|
||||||
|
(*returnColumnSizes)[z] = numsSize;
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<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>
|
||||||
|
@ -166,7 +166,7 @@ if (i > startIndex && nums[i] == nums[i - 1] ) {
|
|||||||
|
|
||||||
|
|
||||||
### Java
|
### Java
|
||||||
|
使用used数组
|
||||||
```java
|
```java
|
||||||
class Solution {
|
class Solution {
|
||||||
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
|
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
|
||||||
@ -202,6 +202,37 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
不使用used数组
|
||||||
|
```java
|
||||||
|
class Solution {
|
||||||
|
|
||||||
|
List<List<Integer>> res = new ArrayList<>();
|
||||||
|
LinkedList<Integer> path = new LinkedList<>();
|
||||||
|
|
||||||
|
public List<List<Integer>> subsetsWithDup( int[] nums ) {
|
||||||
|
Arrays.sort( nums );
|
||||||
|
subsetsWithDupHelper( nums, 0 );
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void subsetsWithDupHelper( int[] nums, int start ) {
|
||||||
|
res.add( new ArrayList<>( path ) );
|
||||||
|
|
||||||
|
for ( int i = start; i < nums.length; i++ ) {
|
||||||
|
// 跳过当前树层使用过的、相同的元素
|
||||||
|
if ( i > start && nums[i - 1] == nums[i] ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
path.add( nums[i] );
|
||||||
|
subsetsWithDupHelper( nums, i + 1 );
|
||||||
|
path.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Python
|
### Python
|
||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
|
@ -574,7 +574,87 @@ var isSymmetric = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Swift:
|
||||||
|
|
||||||
|
> 递归
|
||||||
|
```swift
|
||||||
|
func isSymmetric(_ root: TreeNode?) -> Bool {
|
||||||
|
return _isSymmetric(root?.left, right: root?.right)
|
||||||
|
}
|
||||||
|
func _isSymmetric(_ left: TreeNode?, right: TreeNode?) -> Bool {
|
||||||
|
// 首先排除空节点情况
|
||||||
|
if left == nil && right == nil {
|
||||||
|
return true
|
||||||
|
} else if left == nil && right != nil {
|
||||||
|
return false
|
||||||
|
} else if left != nil && right == nil {
|
||||||
|
return false
|
||||||
|
} else if left!.val != right!.val {
|
||||||
|
// 进而排除数值不相等的情况
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// left 和 right 都不为空, 且数值也相等就递归
|
||||||
|
let inSide = _isSymmetric(left!.right, right: right!.left)
|
||||||
|
let outSide = _isSymmetric(left!.left, right: right!.right)
|
||||||
|
return inSide && outSide
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 迭代 - 使用队列
|
||||||
|
```swift
|
||||||
|
func isSymmetric2(_ root: TreeNode?) -> Bool {
|
||||||
|
guard let root = root else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
var queue = [TreeNode?]()
|
||||||
|
queue.append(root.left)
|
||||||
|
queue.append(root.right)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let left = queue.removeFirst()
|
||||||
|
let right = queue.removeFirst()
|
||||||
|
if left == nil && right == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if left == nil || right == nil || left?.val != right?.val {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
queue.append(left!.left)
|
||||||
|
queue.append(right!.right)
|
||||||
|
queue.append(left!.right)
|
||||||
|
queue.append(right!.left)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 迭代 - 使用栈
|
||||||
|
```swift
|
||||||
|
func isSymmetric3(_ root: TreeNode?) -> Bool {
|
||||||
|
guard let root = root else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
var stack = [TreeNode?]()
|
||||||
|
stack.append(root.left)
|
||||||
|
stack.append(root.right)
|
||||||
|
while !stack.isEmpty {
|
||||||
|
let left = stack.removeLast()
|
||||||
|
let right = stack.removeLast()
|
||||||
|
|
||||||
|
if left == nil && right == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if left == nil || right == nil || left?.val != right?.val {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
stack.append(left!.left)
|
||||||
|
stack.append(right!.right)
|
||||||
|
stack.append(left!.right)
|
||||||
|
stack.append(right!.left)
|
||||||
|
}
|
||||||
|
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>
|
||||||
|
@ -246,6 +246,34 @@ var levelOrder = function(root) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
```swift
|
||||||
|
func levelOrder(_ root: TreeNode?) -> [[Int]] {
|
||||||
|
var res = [[Int]]()
|
||||||
|
guard let root = root else {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
var queue = [TreeNode]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let size = queue.count
|
||||||
|
var sub = [Int]()
|
||||||
|
for _ in 0 ..< size {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
sub.append(node.val)
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.append(sub)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**此时我们就掌握了二叉树的层序遍历了,那么如下九道力扣上的题目,只需要修改模板的两三行代码(不能再多了),便可打倒!**
|
**此时我们就掌握了二叉树的层序遍历了,那么如下九道力扣上的题目,只需要修改模板的两三行代码(不能再多了),便可打倒!**
|
||||||
|
|
||||||
|
|
||||||
@ -426,6 +454,31 @@ var levelOrderBottom = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
```swift
|
||||||
|
func levelOrderBottom(_ root: TreeNode?) -> [[Int]] {
|
||||||
|
var res = [[Int]]()
|
||||||
|
guard let root = root else {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
var queue: [TreeNode] = [root]
|
||||||
|
while !queue.isEmpty {
|
||||||
|
var sub = [Int]()
|
||||||
|
for _ in 0 ..< queue.count {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
sub.append(node.val)
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.insert(sub, at: 0)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# 199.二叉树的右视图
|
# 199.二叉树的右视图
|
||||||
|
|
||||||
@ -604,6 +657,36 @@ var rightSideView = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
```swift
|
||||||
|
func rightSideView(_ root: TreeNode?) -> [Int] {
|
||||||
|
var res = [Int]()
|
||||||
|
guard let root = root else {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
var queue = [TreeNode]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let size = queue.count
|
||||||
|
for i in 0 ..< size {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
if i == size - 1 {
|
||||||
|
// 保存 每层最后一个元素
|
||||||
|
res.append(node.val)
|
||||||
|
}
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
# 637.二叉树的层平均值
|
# 637.二叉树的层平均值
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/)
|
[力扣题目链接](https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/)
|
||||||
@ -785,6 +868,34 @@ var averageOfLevels = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
```swift
|
||||||
|
func averageOfLevels(_ root: TreeNode?) -> [Double] {
|
||||||
|
var res = [Double]()
|
||||||
|
guard let root = root else {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
var queue = [TreeNode]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let size = queue.count
|
||||||
|
var sum = 0
|
||||||
|
for _ in 0 ..< size {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
sum += node.val
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.append(Double(sum) / Double(size))
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# 429.N叉树的层序遍历
|
# 429.N叉树的层序遍历
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/)
|
[力扣题目链接](https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/)
|
||||||
@ -981,6 +1092,31 @@ var levelOrder = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
```swift
|
||||||
|
func levelOrder(_ root: Node?) -> [[Int]] {
|
||||||
|
var res = [[Int]]()
|
||||||
|
guard let root = root else {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
var queue = [Node]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let size = queue.count
|
||||||
|
var sub = [Int]()
|
||||||
|
for _ in 0 ..< size {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
sub.append(node.val)
|
||||||
|
for childNode in node.children {
|
||||||
|
queue.append(childNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.append(sub)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# 515.在每个树行中找最大值
|
# 515.在每个树行中找最大值
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/)
|
[力扣题目链接](https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/)
|
||||||
@ -1136,6 +1272,36 @@ var largestValues = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
```swift
|
||||||
|
func largestValues(_ root: TreeNode?) -> [Int] {
|
||||||
|
var res = [Int]()
|
||||||
|
guard let root = root else {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
var queue = [TreeNode]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let size = queue.count
|
||||||
|
var max: Int = Int.min
|
||||||
|
for _ in 0 ..< size {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
if node.val > max {
|
||||||
|
max = node.val
|
||||||
|
}
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.append(max)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# 116.填充每个节点的下一个右侧节点指针
|
# 116.填充每个节点的下一个右侧节点指针
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/)
|
[力扣题目链接](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/)
|
||||||
@ -1338,6 +1504,37 @@ func connect(root *Node) *Node {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
```swift
|
||||||
|
func connect(_ root: Node?) -> Node? {
|
||||||
|
guard let root = root else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var queue = [Node]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let size = queue.count
|
||||||
|
var preNode: Node?
|
||||||
|
for i in 0 ..< size {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
if i == 0 {
|
||||||
|
preNode = node
|
||||||
|
} else {
|
||||||
|
preNode?.next = node
|
||||||
|
preNode = node
|
||||||
|
}
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# 117.填充每个节点的下一个右侧节点指针II
|
# 117.填充每个节点的下一个右侧节点指针II
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/)
|
[力扣题目链接](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/)
|
||||||
@ -1532,6 +1729,38 @@ func connect(root *Node) *Node {
|
|||||||
return root
|
return root
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
```swift
|
||||||
|
func connect(_ root: Node?) -> Node? {
|
||||||
|
guard let root = root else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var queue = [Node]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let size = queue.count
|
||||||
|
var preNode: Node?
|
||||||
|
for i in 0 ..< size {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
if i == 0 {
|
||||||
|
preNode = node
|
||||||
|
} else {
|
||||||
|
preNode?.next = node
|
||||||
|
preNode = node
|
||||||
|
}
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# 104.二叉树的最大深度
|
# 104.二叉树的最大深度
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/)
|
[力扣题目链接](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/)
|
||||||
@ -1704,6 +1933,31 @@ var maxDepth = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
```swift
|
||||||
|
func maxDepth(_ root: TreeNode?) -> Int {
|
||||||
|
guard let root = root else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var queue = [TreeNode]()
|
||||||
|
queue.append(root)
|
||||||
|
var res: Int = 0
|
||||||
|
while !queue.isEmpty {
|
||||||
|
for _ in 0 ..< queue.count {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res += 1
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# 111.二叉树的最小深度
|
# 111.二叉树的最小深度
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/)
|
[力扣题目链接](https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/)
|
||||||
@ -1876,7 +2130,33 @@ var minDepth = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
```swift
|
||||||
|
func minDepth(_ root: TreeNode?) -> Int {
|
||||||
|
guard let root = root else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var res = 0
|
||||||
|
var queue = [TreeNode]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
res += 1
|
||||||
|
for _ in 0 ..< queue.count {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
if node.left == nil && node.right == nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
# 总结
|
# 总结
|
||||||
|
@ -653,5 +653,82 @@ int maxDepth(struct TreeNode* root){
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Swift
|
||||||
|
|
||||||
|
>二叉树最大深度
|
||||||
|
```swift
|
||||||
|
// 递归 - 后序
|
||||||
|
func maxDepth1(_ root: TreeNode?) -> Int {
|
||||||
|
return _maxDepth1(root)
|
||||||
|
}
|
||||||
|
func _maxDepth1(_ root: TreeNode?) -> Int {
|
||||||
|
if root == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
let leftDepth = _maxDepth1(root!.left)
|
||||||
|
let rightDepth = _maxDepth1(root!.right)
|
||||||
|
return 1 + max(leftDepth, rightDepth)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 层序
|
||||||
|
func maxDepth(_ root: TreeNode?) -> Int {
|
||||||
|
guard let root = root else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var queue = [TreeNode]()
|
||||||
|
queue.append(root)
|
||||||
|
var res: Int = 0
|
||||||
|
while !queue.isEmpty {
|
||||||
|
res += 1
|
||||||
|
for _ in 0 ..< queue.count {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
>N叉树最大深度
|
||||||
|
```swift
|
||||||
|
// 递归
|
||||||
|
func maxDepth(_ root: Node?) -> Int {
|
||||||
|
guard let root = root else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var depth = 0
|
||||||
|
for node in root.children {
|
||||||
|
depth = max(depth, maxDepth(node))
|
||||||
|
}
|
||||||
|
return depth + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 迭代-层序遍历
|
||||||
|
func maxDepth1(_ root: Node?) -> Int {
|
||||||
|
guard let root = root else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var depth = 0
|
||||||
|
var queue = [Node]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let size = queue.count
|
||||||
|
depth += 1
|
||||||
|
for _ in 0 ..< size {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
for child in node.children {
|
||||||
|
queue.append(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return depth
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<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>
|
||||||
|
@ -816,6 +816,7 @@ var buildTree = function(preorder, inorder) {
|
|||||||
|
|
||||||
## C
|
## C
|
||||||
106 从中序与后序遍历序列构造二叉树
|
106 从中序与后序遍历序列构造二叉树
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int linearSearch(int* arr, int arrSize, int key) {
|
int linearSearch(int* arr, int arrSize, int key) {
|
||||||
int i;
|
int i;
|
||||||
@ -847,6 +848,7 @@ struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int po
|
|||||||
```
|
```
|
||||||
|
|
||||||
105 从前序与中序遍历序列构造二叉树
|
105 从前序与中序遍历序列构造二叉树
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
|
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
|
||||||
// 递归结束条件:传入的数组大小为0
|
// 递归结束条件:传入的数组大小为0
|
||||||
@ -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>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -404,8 +404,51 @@ var minDepth = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Swift
|
||||||
|
|
||||||
|
> 递归
|
||||||
|
```Swift
|
||||||
|
func minDepth(_ root: TreeNode?) -> Int {
|
||||||
|
guard let root = root else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if root.left == nil && root.right != nil {
|
||||||
|
return 1 + minDepth(root.right)
|
||||||
|
}
|
||||||
|
if root.left != nil && root.right == nil {
|
||||||
|
return 1 + minDepth(root.left)
|
||||||
|
}
|
||||||
|
return 1 + min(minDepth(root.left), minDepth(root.right))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 迭代
|
||||||
|
```Swift
|
||||||
|
func minDepth(_ root: TreeNode?) -> Int {
|
||||||
|
guard let root = root else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var res = 0
|
||||||
|
var queue = [TreeNode]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
res += 1
|
||||||
|
for _ in 0 ..< queue.count {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
if node.left == nil && node.right == nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<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>
|
||||||
|
@ -587,5 +587,57 @@ func partition(_ s: String) -> [[String]] {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Rust
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl Solution {
|
||||||
|
pub fn partition(s: String) -> Vec<Vec<String>> {
|
||||||
|
let mut ret = vec![];
|
||||||
|
let mut path = vec![];
|
||||||
|
let sub_str: Vec<char> = s.chars().collect();
|
||||||
|
|
||||||
|
Self::backtracing(&sub_str, 0, &mut ret, &mut path);
|
||||||
|
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn backtracing(sub_str: &Vec<char>, start: usize, ret: &mut Vec<Vec<String>>, path: &mut Vec<String>) {
|
||||||
|
//如果起始位置大于s的大小,说明找到了一组分割方案
|
||||||
|
if start >= sub_str.len() {
|
||||||
|
ret.push(path.clone());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in start..sub_str.len() {
|
||||||
|
if !Self::is_palindrome(sub_str, start, i) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//如果是回文子串,则记录
|
||||||
|
let s: String = sub_str[start..i+1].into_iter().collect();
|
||||||
|
path.push(s);
|
||||||
|
|
||||||
|
//起始位置后移,保证不重复
|
||||||
|
Self::backtracing(sub_str, i+1, ret, path);
|
||||||
|
path.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_palindrome(s: &Vec<char>, start: usize, end: usize) -> bool {
|
||||||
|
let (mut start, mut end) = (start, end);
|
||||||
|
|
||||||
|
while start < end {
|
||||||
|
if s[start] != s[end] {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
start += 1;
|
||||||
|
end -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
|
@ -133,39 +133,26 @@ public:
|
|||||||
java:
|
java:
|
||||||
|
|
||||||
```Java
|
```Java
|
||||||
public class EvalRPN {
|
class Solution {
|
||||||
|
|
||||||
public int evalRPN(String[] tokens) {
|
public int evalRPN(String[] tokens) {
|
||||||
Deque<Integer> stack = new LinkedList();
|
Deque<Integer> stack = new LinkedList();
|
||||||
for (String token : tokens) {
|
for (int i = 0; i < tokens.length; ++i) {
|
||||||
char c = token.charAt(0);
|
if ("+".equals(tokens[i])) { // leetcode 内置jdk的问题,不能使用==判断字符串是否相等
|
||||||
if (!isOpe(token)) {
|
stack.push(stack.pop() + stack.pop()); // 注意 - 和/ 需要特殊处理
|
||||||
stack.addFirst(stoi(token));
|
} else if ("-".equals(tokens[i])) {
|
||||||
} else if (c == '+') {
|
|
||||||
stack.push(stack.pop() + stack.pop());
|
|
||||||
} else if (c == '-') {
|
|
||||||
stack.push(-stack.pop() + stack.pop());
|
stack.push(-stack.pop() + stack.pop());
|
||||||
} else if (c == '*') {
|
} else if ("*".equals(tokens[i])) {
|
||||||
stack.push(stack.pop() * stack.pop());
|
stack.push(stack.pop() * stack.pop());
|
||||||
|
} else if ("/".equals(tokens[i])) {
|
||||||
|
int temp1 = stack.pop();
|
||||||
|
int temp2 = stack.pop();
|
||||||
|
stack.push(temp2 / temp1);
|
||||||
} else {
|
} else {
|
||||||
int num1 = stack.pop();
|
stack.push(Integer.valueOf(tokens[i]));
|
||||||
int num2 = stack.pop();
|
|
||||||
stack.push( num2/num1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stack.pop();
|
return stack.pop();
|
||||||
}
|
}
|
||||||
private boolean isOpe(String s) {
|
|
||||||
return s.length() == 1 && s.charAt(0) <'0' || s.charAt(0) >'9';
|
|
||||||
}
|
|
||||||
private int stoi(String s) {
|
|
||||||
return Integer.valueOf(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
new EvalRPN().evalRPN(new String[] {"10","6","9","3","+","-11","*","/","*","17","+","5","+"});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
不能使用辅助空间之后,那么只能在原字符串上下功夫了。
|
不能使用辅助空间之后,那么只能在原字符串上下功夫了。
|
||||||
|
|
||||||
想一下,我们将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒叙了,那么再把单词反转一下,单词不就正过来了。
|
想一下,我们将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,单词不就正过来了。
|
||||||
|
|
||||||
所以解题思路如下:
|
所以解题思路如下:
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
/**
|
/**
|
||||||
* Definition for singly-linked list.
|
* Definition for singly-linked list.
|
||||||
|
@ -314,6 +314,54 @@ var reverseList = function(head) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 双指针法
|
||||||
|
function reverseList(head: ListNode | null): ListNode | null {
|
||||||
|
let preNode: ListNode | null = null,
|
||||||
|
curNode: ListNode | null = head,
|
||||||
|
tempNode: ListNode | null;
|
||||||
|
while (curNode) {
|
||||||
|
tempNode = curNode.next;
|
||||||
|
curNode.next = preNode;
|
||||||
|
preNode = curNode;
|
||||||
|
curNode = tempNode;
|
||||||
|
}
|
||||||
|
return preNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 递归(从前往后翻转)
|
||||||
|
function reverseList(head: ListNode | null): ListNode | null {
|
||||||
|
function recur(preNode: ListNode | null, curNode: ListNode | null): ListNode | null {
|
||||||
|
if (curNode === null) return preNode;
|
||||||
|
let tempNode: ListNode | null = curNode.next;
|
||||||
|
curNode.next = preNode;
|
||||||
|
preNode = curNode;
|
||||||
|
curNode = tempNode;
|
||||||
|
return recur(preNode, curNode);
|
||||||
|
}
|
||||||
|
return recur(null, head);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 递归(从后往前翻转)
|
||||||
|
function reverseList(head: ListNode | null): ListNode | null {
|
||||||
|
if (head === null) return null;
|
||||||
|
let newHead: ListNode | null;
|
||||||
|
function recur(node: ListNode | null, preNode: ListNode | null): void {
|
||||||
|
if (node.next === null) {
|
||||||
|
newHead = node;
|
||||||
|
newHead.next = preNode;
|
||||||
|
} else {
|
||||||
|
recur(node.next, node);
|
||||||
|
node.next = preNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recur(head, null);
|
||||||
|
return newHead;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Ruby:
|
Ruby:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
|
@ -121,7 +121,6 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
|
|
||||||
@ -214,6 +213,28 @@ var minSubArrayLen = function(target, nums) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Typescript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function minSubArrayLen(target: number, nums: number[]): number {
|
||||||
|
let left: number = 0, right: number = 0;
|
||||||
|
let res: number = nums.length + 1;
|
||||||
|
let sum: number = 0;
|
||||||
|
while (right < nums.length) {
|
||||||
|
sum += nums[right];
|
||||||
|
if (sum >= target) {
|
||||||
|
// 不断移动左指针,直到不能再缩小为止
|
||||||
|
while (sum - nums[left] >= target) {
|
||||||
|
sum -= nums[left++];
|
||||||
|
}
|
||||||
|
res = Math.min(res, right - left + 1);
|
||||||
|
}
|
||||||
|
right++;
|
||||||
|
}
|
||||||
|
return res === nums.length + 1 ? 0 : res;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
@ -291,5 +312,23 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Ruby:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
def min_sub_array_len(target, nums)
|
||||||
|
res = Float::INFINITY # 无穷大
|
||||||
|
i, sum = 0, 0
|
||||||
|
nums.length.times do |j|
|
||||||
|
sum += nums[j]
|
||||||
|
while sum >= target
|
||||||
|
res = [res, j - i + 1].min
|
||||||
|
sum -= nums[i]
|
||||||
|
i += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
res == Float::INFINITY ? 0 : res
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<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>
|
||||||
|
@ -323,7 +323,6 @@ class Solution:
|
|||||||
self.backtracking(k, n, i + 1)
|
self.backtracking(k, n, i + 1)
|
||||||
self.path.pop()
|
self.path.pop()
|
||||||
self.sum_now -= i
|
self.sum_now -= i
|
||||||
return
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Go
|
## Go
|
||||||
|
@ -80,7 +80,7 @@ return treeNum;
|
|||||||
class Solution {
|
class Solution {
|
||||||
private:
|
private:
|
||||||
int getNodesNum(TreeNode* cur) {
|
int getNodesNum(TreeNode* cur) {
|
||||||
if (cur == 0) return 0;
|
if (cur == NULL) return 0;
|
||||||
int leftNum = getNodesNum(cur->left); // 左
|
int leftNum = getNodesNum(cur->left); // 左
|
||||||
int rightNum = getNodesNum(cur->right); // 右
|
int rightNum = getNodesNum(cur->right); // 右
|
||||||
int treeNum = leftNum + rightNum + 1; // 中
|
int treeNum = leftNum + rightNum + 1; // 中
|
||||||
@ -522,5 +522,73 @@ int countNodes(struct TreeNode* root){
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Swift:
|
||||||
|
|
||||||
|
> 递归
|
||||||
|
```swift
|
||||||
|
func countNodes(_ root: TreeNode?) -> Int {
|
||||||
|
return _countNodes(root)
|
||||||
|
}
|
||||||
|
func _countNodes(_ root: TreeNode?) -> Int {
|
||||||
|
guard let root = root else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
let leftCount = _countNodes(root.left)
|
||||||
|
let rightCount = _countNodes(root.right)
|
||||||
|
return 1 + leftCount + rightCount
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 层序遍历
|
||||||
|
```Swift
|
||||||
|
func countNodes(_ root: TreeNode?) -> Int {
|
||||||
|
guard let root = root else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var res = 0
|
||||||
|
var queue = [TreeNode]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let size = queue.count
|
||||||
|
for _ in 0 ..< size {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
res += 1
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 利用完全二叉树性质
|
||||||
|
```Swift
|
||||||
|
func countNodes(_ root: TreeNode?) -> Int {
|
||||||
|
guard let root = root else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var leftNode = root.left
|
||||||
|
var rightNode = root.right
|
||||||
|
var leftDepth = 0
|
||||||
|
var rightDepth = 0
|
||||||
|
while leftNode != nil {
|
||||||
|
leftNode = leftNode!.left
|
||||||
|
leftDepth += 1
|
||||||
|
}
|
||||||
|
while rightNode != nil {
|
||||||
|
rightNode = rightNode!.right
|
||||||
|
rightDepth += 1
|
||||||
|
}
|
||||||
|
if leftDepth == rightDepth {
|
||||||
|
return (2 << leftDepth) - 1
|
||||||
|
}
|
||||||
|
return countNodes(root.left) + countNodes(root.right) + 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<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>
|
||||||
|
@ -609,5 +609,43 @@ struct TreeNode* invertTree(struct TreeNode* root){
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Swift:
|
||||||
|
```swift
|
||||||
|
// 前序遍历-递归
|
||||||
|
func invertTree(_ root: TreeNode?) -> TreeNode? {
|
||||||
|
guard let root = root else {
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
let tmp = root.left
|
||||||
|
root.left = root.right
|
||||||
|
root.right = tmp
|
||||||
|
let _ = invertTree(root.left)
|
||||||
|
let _ = invertTree(root.right)
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|
||||||
|
// 层序遍历-迭代
|
||||||
|
func invertTree1(_ root: TreeNode?) -> TreeNode? {
|
||||||
|
guard let root = root else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var queue = [TreeNode]()
|
||||||
|
queue.append(root)
|
||||||
|
while !queue.isEmpty {
|
||||||
|
let node = queue.removeFirst()
|
||||||
|
let tmp = node.left
|
||||||
|
node.left = node.right
|
||||||
|
node.right = tmp
|
||||||
|
if let left = node.left {
|
||||||
|
queue.append(left)
|
||||||
|
}
|
||||||
|
if let right = node.right {
|
||||||
|
queue.append(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<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>
|
||||||
|
@ -93,7 +93,7 @@ dp[i][3] = dp[i - 1][2];
|
|||||||
综上分析,递推代码如下:
|
综上分析,递推代码如下:
|
||||||
|
|
||||||
```CPP
|
```CPP
|
||||||
dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3], dp[i - 1][1]) - prices[i];
|
dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3], dp[i - 1][1]) - prices[i]);
|
||||||
dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);
|
dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);
|
||||||
dp[i][2] = dp[i - 1][0] + prices[i];
|
dp[i][2] = dp[i - 1][0] + prices[i];
|
||||||
dp[i][3] = dp[i - 1][2];
|
dp[i][3] = dp[i - 1][2];
|
||||||
|
@ -101,7 +101,6 @@ s[j] = tmp;
|
|||||||
s[i] ^= s[j];
|
s[i] ^= s[j];
|
||||||
s[j] ^= s[i];
|
s[j] ^= s[i];
|
||||||
s[i] ^= s[j];
|
s[i] ^= s[j];
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
这道题目还是比较简单的,但是我正好可以通过这道题目说一说在刷题的时候,使用库函数的原则。
|
这道题目还是比较简单的,但是我正好可以通过这道题目说一说在刷题的时候,使用库函数的原则。
|
||||||
|
@ -107,7 +107,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒叙来输出到数组
|
// 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组
|
||||||
vector<int> result(k);
|
vector<int> result(k);
|
||||||
for (int i = k - 1; i >= 0; i--) {
|
for (int i = k - 1; i >= 0; i--) {
|
||||||
result[i] = pri_que.top().first;
|
result[i] = pri_que.top().first;
|
||||||
@ -142,7 +142,7 @@ class Solution {
|
|||||||
|
|
||||||
Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
|
Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
|
||||||
// 根据map的value值正序排,相当于一个小顶堆
|
// 根据map的value值正序排,相当于一个小顶堆
|
||||||
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) {
|
if (queue.size() > k) {
|
||||||
@ -180,7 +180,7 @@ class Solution:
|
|||||||
if len(pri_que) > k: #如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
|
if len(pri_que) > k: #如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
|
||||||
heapq.heappop(pri_que)
|
heapq.heappop(pri_que)
|
||||||
|
|
||||||
#找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒叙来输出到数组
|
#找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组
|
||||||
result = [0] * k
|
result = [0] * k
|
||||||
for i in range(k-1, -1, -1):
|
for i in range(k-1, -1, -1):
|
||||||
result[i] = heapq.heappop(pri_que)[1]
|
result[i] = heapq.heappop(pri_que)[1]
|
||||||
|
@ -112,7 +112,7 @@ vector<int> dp(10001, 0);
|
|||||||
|
|
||||||
4. 确定遍历顺序
|
4. 确定遍历顺序
|
||||||
|
|
||||||
在[动态规划:关于01背包问题,你该了解这些!(滚动数组)](https://programmercarl.com/背包理论基础01背包-2.html)中就已经说明:如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒叙遍历!
|
在[动态规划:关于01背包问题,你该了解这些!(滚动数组)](https://programmercarl.com/背包理论基础01背包-2.html)中就已经说明:如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历!
|
||||||
|
|
||||||
代码如下:
|
代码如下:
|
||||||
|
|
||||||
|
@ -229,28 +229,24 @@ class Solution {
|
|||||||
Swift:
|
Swift:
|
||||||
```swift
|
```swift
|
||||||
func fourSumCount(_ nums1: [Int], _ nums2: [Int], _ nums3: [Int], _ nums4: [Int]) -> Int {
|
func fourSumCount(_ nums1: [Int], _ nums2: [Int], _ nums3: [Int], _ nums4: [Int]) -> Int {
|
||||||
// key:a+b的数值,value:a+b数值出现的次数
|
// ab和: ab和出现次数
|
||||||
var map = [Int: Int]()
|
var countDic = [Int: Int]()
|
||||||
// 遍历nums1和nums2数组,统计两个数组元素之和,和出现的次数,放到map中
|
for a in nums1 {
|
||||||
for i in 0 ..< nums1.count {
|
for b in nums2 {
|
||||||
for j in 0 ..< nums2.count {
|
let key = a + b
|
||||||
let sum1 = nums1[i] + nums2[j]
|
countDic[key] = countDic[key, default: 0] + 1
|
||||||
map[sum1] = (map[sum1] ?? 0) + 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 统计a+b+c+d = 0 出现的次数
|
|
||||||
var res = 0
|
// 通过-(c + d)作为key,去累加ab和出现的次数
|
||||||
// 在遍历大num3和num4数组,找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来。
|
var result = 0
|
||||||
for i in 0 ..< nums3.count {
|
for c in nums3 {
|
||||||
for j in 0 ..< nums4.count {
|
for d in nums4 {
|
||||||
let sum2 = nums3[i] + nums4[j]
|
let key = -(c + d)
|
||||||
let other = 0 - sum2
|
result += countDic[key, default: 0]
|
||||||
if map.keys.contains(other) {
|
|
||||||
res += map[other]!
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return result
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
这里就要说一说next数组了,next 数组记录的就是最长相同前后缀( [字符串:KMP算法精讲](https://programmercarl.com/0028.实现strStr.html) 这里介绍了什么是前缀,什么是后缀,什么又是最长相同前后缀), 如果 next[len - 1] != -1,则说明字符串有最长相同的前后缀(就是字符串里的前缀子串和后缀子串相同的最长长度)。
|
这里就要说一说next数组了,next 数组记录的就是最长相同前后缀( [字符串:KMP算法精讲](https://programmercarl.com/0028.实现strStr.html) 这里介绍了什么是前缀,什么是后缀,什么又是最长相同前后缀), 如果 next[len - 1] != -1,则说明字符串有最长相同的前后缀(就是字符串里的前缀子串和后缀子串相同的最长长度)。
|
||||||
|
|
||||||
最长相等前后缀的长度为:next[len - 1] + 1。
|
最长相等前后缀的长度为:next[len - 1] + 1。(这里的next数组是以统一减一的方式计算的,因此需要+1)
|
||||||
|
|
||||||
数组长度为:len。
|
数组长度为:len。
|
||||||
|
|
||||||
|
@ -154,6 +154,8 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
|
||||||
|
> 动态规划:
|
||||||
```java
|
```java
|
||||||
/**
|
/**
|
||||||
* 1.dp[i] 代表当前下标最大连续值
|
* 1.dp[i] 代表当前下标最大连续值
|
||||||
@ -180,6 +182,25 @@ Java:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> 贪心法:
|
||||||
|
|
||||||
|
```Java
|
||||||
|
public static int findLengthOfLCIS(int[] nums) {
|
||||||
|
if (nums.length == 0) return 0;
|
||||||
|
int res = 1; // 连续子序列最少也是1
|
||||||
|
int count = 1;
|
||||||
|
for (int i = 0; i < nums.length - 1; i++) {
|
||||||
|
if (nums[i + 1] > nums[i]) { // 连续记录
|
||||||
|
count++;
|
||||||
|
} else { // 不连续,count从头开始
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
if (count > res) res = count;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
> 动态规划:
|
> 动态规划:
|
||||||
|
@ -68,7 +68,7 @@ for (int i = 0; i < n; i++) {
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
vector<int> vec; // 记录入度为2的边(如果有的话就两条边)
|
vector<int> vec; // 记录入度为2的边(如果有的话就两条边)
|
||||||
// 找入度为2的节点所对应的边,注意要倒叙,因为优先返回最后出现在二维数组中的答案
|
// 找入度为2的节点所对应的边,注意要倒序,因为优先返回最后出现在二维数组中的答案
|
||||||
for (int i = n - 1; i >= 0; i--) {
|
for (int i = n - 1; i >= 0; i--) {
|
||||||
if (inDegree[edges[i][1]] == 2) {
|
if (inDegree[edges[i][1]] == 2) {
|
||||||
vec.push_back(i);
|
vec.push_back(i);
|
||||||
@ -577,7 +577,7 @@ var findRedundantDirectedConnection = function(edges) {
|
|||||||
inDegree[edges[i][1]]++; // 统计入度
|
inDegree[edges[i][1]]++; // 统计入度
|
||||||
}
|
}
|
||||||
let vec = [];// 记录入度为2的边(如果有的话就两条边)
|
let vec = [];// 记录入度为2的边(如果有的话就两条边)
|
||||||
// 找入度为2的节点所对应的边,注意要倒叙,因为优先返回最后出现在二维数组中的答案
|
// 找入度为2的节点所对应的边,注意要倒序,因为优先返回最后出现在二维数组中的答案
|
||||||
for (let i = n - 1; i >= 0; i--) {
|
for (let i = n - 1; i >= 0; i--) {
|
||||||
if (inDegree[edges[i][1]] == 2) {
|
if (inDegree[edges[i][1]] == 2) {
|
||||||
vec.push(i);
|
vec.push(i);
|
||||||
|
@ -284,7 +284,6 @@ func search(nums []int, target int) int {
|
|||||||
* @param {number} target
|
* @param {number} target
|
||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
var search = function(nums, target) {
|
var search = function(nums, target) {
|
||||||
let left = 0, right = nums.length - 1;
|
let left = 0, right = nums.length - 1;
|
||||||
// 使用左闭右闭区间
|
// 使用左闭右闭区间
|
||||||
@ -326,6 +325,46 @@ var search = function(nums, target) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**TypeScript**
|
||||||
|
|
||||||
|
(版本一)左闭右闭区间
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function search(nums: number[], target: number): number {
|
||||||
|
let left: number = 0, right: number = nums.length - 1;
|
||||||
|
while (left <= right) {
|
||||||
|
let mid: number = left + Math.floor((right - left) / 2);
|
||||||
|
if (nums[mid] > target) {
|
||||||
|
right = mid - 1;
|
||||||
|
} else if (nums[mid] < target) {
|
||||||
|
left = mid + 1;
|
||||||
|
} else {
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
(版本二)左闭右开区间
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function search(nums: number[], target: number): number {
|
||||||
|
let left: number = 0, right: number = nums.length;
|
||||||
|
while (left < right) {
|
||||||
|
let mid: number = left + Math.floor((right - left) / 2);
|
||||||
|
if (nums[mid] > target) {
|
||||||
|
right = mid;
|
||||||
|
} else if (nums[mid] < target) {
|
||||||
|
left = mid + 1;
|
||||||
|
} else {
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
**Ruby:**
|
**Ruby:**
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
|
@ -119,7 +119,7 @@ C++代码如下:
|
|||||||
class Solution {
|
class Solution {
|
||||||
public:
|
public:
|
||||||
vector<int> dailyTemperatures(vector<int>& T) {
|
vector<int> dailyTemperatures(vector<int>& T) {
|
||||||
// 递减栈
|
// 递增栈
|
||||||
stack<int> st;
|
stack<int> st;
|
||||||
vector<int> result(T.size(), 0);
|
vector<int> result(T.size(), 0);
|
||||||
st.push(0);
|
st.push(0);
|
||||||
@ -150,7 +150,7 @@ public:
|
|||||||
class Solution {
|
class Solution {
|
||||||
public:
|
public:
|
||||||
vector<int> dailyTemperatures(vector<int>& T) {
|
vector<int> dailyTemperatures(vector<int>& T) {
|
||||||
stack<int> st; // 递减栈
|
stack<int> st; // 递增栈
|
||||||
vector<int> result(T.size(), 0);
|
vector<int> result(T.size(), 0);
|
||||||
for (int i = 0; i < T.size(); i++) {
|
for (int i = 0; i < T.size(); i++) {
|
||||||
while (!st.empty() && T[i] > T[st.top()]) { // 注意栈不能为空
|
while (!st.empty() && T[i] > T[st.top()]) { // 注意栈不能为空
|
||||||
@ -178,7 +178,7 @@ public:
|
|||||||
Java:
|
Java:
|
||||||
```java
|
```java
|
||||||
/**
|
/**
|
||||||
* 单调栈,栈内顺序要么从大到小 要么从小到大,本题从大到笑
|
* 单调栈,栈内顺序要么从大到小 要么从小到大,本题从大到小
|
||||||
* <p>
|
* <p>
|
||||||
* 入站元素要和当前栈内栈首元素进行比较
|
* 入站元素要和当前栈内栈首元素进行比较
|
||||||
* 若大于栈首则 则与元素下标做差
|
* 若大于栈首则 则与元素下标做差
|
||||||
|
@ -82,7 +82,7 @@ dp[1] = cost[1];
|
|||||||
|
|
||||||
**但是稍稍有点难度的动态规划,其遍历顺序并不容易确定下来**。
|
**但是稍稍有点难度的动态规划,其遍历顺序并不容易确定下来**。
|
||||||
|
|
||||||
例如:01背包,都知道两个for循环,一个for遍历物品嵌套一个for遍历背包容量,那么为什么不是一个for遍历背包容量嵌套一个for遍历物品呢? 以及在使用一维dp数组的时候遍历背包容量为什么要倒叙呢?
|
例如:01背包,都知道两个for循环,一个for遍历物品嵌套一个for遍历背包容量,那么为什么不是一个for遍历背包容量嵌套一个for遍历物品呢? 以及在使用一维dp数组的时候遍历背包容量为什么要倒序呢?
|
||||||
|
|
||||||
**这些都是遍历顺序息息相关。当然背包问题后续「代码随想录」都会重点讲解的!**
|
**这些都是遍历顺序息息相关。当然背包问题后续「代码随想录」都会重点讲解的!**
|
||||||
|
|
||||||
|
@ -221,6 +221,35 @@ var sortedSquares = function(nums) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Typescript:
|
||||||
|
|
||||||
|
双指针法:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function sortedSquares(nums: number[]): number[] {
|
||||||
|
let left: number = 0, right: number = nums.length - 1;
|
||||||
|
let resArr: number[] = new Array(nums.length);
|
||||||
|
let resArrIndex: number = resArr.length - 1;
|
||||||
|
while (left <= right) {
|
||||||
|
if (Math.abs(nums[left]) < Math.abs(nums[right])) {
|
||||||
|
resArr[resArrIndex] = nums[right--] ** 2;
|
||||||
|
} else {
|
||||||
|
resArr[resArrIndex] = nums[left++] ** 2;
|
||||||
|
}
|
||||||
|
resArrIndex--;
|
||||||
|
}
|
||||||
|
return resArr;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
骚操作法(暴力思路):
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function sortedSquares(nums: number[]): number[] {
|
||||||
|
return nums.map(i => i * i).sort((a, b) => a - b);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
|
@ -58,7 +58,7 @@ words[i] 由小写英文字母组成
|
|||||||
|
|
||||||
先统计第一个字符串所有字符出现的次数,代码如下:
|
先统计第一个字符串所有字符出现的次数,代码如下:
|
||||||
|
|
||||||
```
|
```cpp
|
||||||
int hash[26] = {0}; // 用来统计所有字符串里字符出现的最小频率
|
int hash[26] = {0}; // 用来统计所有字符串里字符出现的最小频率
|
||||||
for (int i = 0; i < A[0].size(); i++) { // 用第一个字符串给hash初始化
|
for (int i = 0; i < A[0].size(); i++) { // 用第一个字符串给hash初始化
|
||||||
hash[A[0][i] - 'a']++;
|
hash[A[0][i] - 'a']++;
|
||||||
@ -71,7 +71,7 @@ for (int i = 0; i < A[0].size(); i++) { // 用第一个字符串给hash初始化
|
|||||||
|
|
||||||
代码如下:
|
代码如下:
|
||||||
|
|
||||||
```
|
```cpp
|
||||||
int hashOtherStr[26] = {0}; // 统计除第一个字符串外字符的出现频率
|
int hashOtherStr[26] = {0}; // 统计除第一个字符串外字符的出现频率
|
||||||
for (int i = 1; i < A.size(); i++) {
|
for (int i = 1; i < A.size(); i++) {
|
||||||
memset(hashOtherStr, 0, 26 * sizeof(int));
|
memset(hashOtherStr, 0, 26 * sizeof(int));
|
||||||
@ -84,11 +84,11 @@ for (int i = 1; i < A.size(); i++) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
此时hash里统计着字符在所有字符串里出现的最小次数,那么把hash转正题目要求的输出格式就可以了。
|
此时hash里统计着字符在所有字符串里出现的最小次数,那么把hash转成题目要求的输出格式就可以了。
|
||||||
|
|
||||||
代码如下:
|
代码如下:
|
||||||
|
|
||||||
```
|
```cpp
|
||||||
// 将hash统计的字符次数,转成输出形式
|
// 将hash统计的字符次数,转成输出形式
|
||||||
for (int i = 0; i < 26; i++) {
|
for (int i = 0; i < 26; i++) {
|
||||||
while (hash[i] != 0) { // 注意这里是while,多个重复的字符
|
while (hash[i] != 0) { // 注意这里是while,多个重复的字符
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
从栈中弹出剩余元素,此时是字符串ac,因为从栈里弹出的元素是倒叙的,所以在对字符串进行反转一下,就得到了最终的结果。
|
从栈中弹出剩余元素,此时是字符串ac,因为从栈里弹出的元素是倒序的,所以在对字符串进行反转一下,就得到了最终的结果。
|
||||||
|
|
||||||
C++代码 :
|
C++代码 :
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ vector<int> dp(15001, 0);
|
|||||||
4. 确定遍历顺序
|
4. 确定遍历顺序
|
||||||
|
|
||||||
|
|
||||||
在[动态规划:关于01背包问题,你该了解这些!(滚动数组)](https://programmercarl.com/背包理论基础01背包-2.html)中就已经说明:如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒叙遍历!
|
在[动态规划:关于01背包问题,你该了解这些!(滚动数组)](https://programmercarl.com/背包理论基础01背包-2.html)中就已经说明:如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历!
|
||||||
|
|
||||||
代码如下:
|
代码如下:
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ for(int i = 0; i < weight.size(); i++) { // 遍历物品
|
|||||||
|
|
||||||
为什么呢?
|
为什么呢?
|
||||||
|
|
||||||
**倒叙遍历是为了保证物品i只被放入一次!**。但如果一旦正序遍历了,那么物品0就会被重复加入多次!
|
**倒序遍历是为了保证物品i只被放入一次!**。但如果一旦正序遍历了,那么物品0就会被重复加入多次!
|
||||||
|
|
||||||
举一个例子:物品0的重量weight[0] = 1,价值value[0] = 15
|
举一个例子:物品0的重量weight[0] = 1,价值value[0] = 15
|
||||||
|
|
||||||
@ -115,9 +115,9 @@ dp[2] = dp[2 - weight[0]] + value[0] = 30
|
|||||||
|
|
||||||
此时dp[2]就已经是30了,意味着物品0,被放入了两次,所以不能正序遍历。
|
此时dp[2]就已经是30了,意味着物品0,被放入了两次,所以不能正序遍历。
|
||||||
|
|
||||||
为什么倒叙遍历,就可以保证物品只放入一次呢?
|
为什么倒序遍历,就可以保证物品只放入一次呢?
|
||||||
|
|
||||||
倒叙就是先算dp[2]
|
倒序就是先算dp[2]
|
||||||
|
|
||||||
dp[2] = dp[2 - weight[0]] + value[0] = 15 (dp数组已经都初始化为0)
|
dp[2] = dp[2 - weight[0]] + value[0] = 15 (dp数组已经都初始化为0)
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ dp[1] = dp[1 - weight[0]] + value[0] = 15
|
|||||||
|
|
||||||
所以从后往前循环,每次取得状态不会和之前取得状态重合,这样每种物品就只取一次了。
|
所以从后往前循环,每次取得状态不会和之前取得状态重合,这样每种物品就只取一次了。
|
||||||
|
|
||||||
**那么问题又来了,为什么二维dp数组历的时候不用倒叙呢?**
|
**那么问题又来了,为什么二维dp数组历的时候不用倒序呢?**
|
||||||
|
|
||||||
因为对于二维dp,dp[i][j]都是通过上一层即dp[i - 1][j]计算而来,本层的dp[i][j]并不会被覆盖!
|
因为对于二维dp,dp[i][j]都是通过上一层即dp[i - 1][j]计算而来,本层的dp[i][j]并不会被覆盖!
|
||||||
|
|
||||||
|
@ -168,6 +168,32 @@ public class ListNode {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
JavaScript:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
class ListNode {
|
||||||
|
val;
|
||||||
|
next = null;
|
||||||
|
constructor(value) {
|
||||||
|
this.val = value;
|
||||||
|
this.next = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class ListNode {
|
||||||
|
public val: number;
|
||||||
|
public next: ListNode = null;
|
||||||
|
constructor(value: number) {
|
||||||
|
this.val = value;
|
||||||
|
this.next = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user