mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 16:54:50 +08:00
Merge branch 'master' of https://github.com/youngyangyang04/leetcode
This commit is contained in:
@ -232,6 +232,38 @@ class Solution:
|
|||||||
return dp[-1][-1]
|
return dp[-1][-1]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
"""
|
||||||
|
使用一维dp数组
|
||||||
|
"""
|
||||||
|
|
||||||
|
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
|
||||||
|
m, n = len(obstacleGrid), len(obstacleGrid[0])
|
||||||
|
|
||||||
|
# 初始化dp数组
|
||||||
|
# 该数组缓存当前行
|
||||||
|
curr = [0] * n
|
||||||
|
for j in range(n):
|
||||||
|
if obstacleGrid[0][j] == 1:
|
||||||
|
break
|
||||||
|
curr[j] = 1
|
||||||
|
|
||||||
|
for i in range(1, m): # 从第二行开始
|
||||||
|
for j in range(n): # 从第一列开始,因为第一列可能有障碍物
|
||||||
|
# 有障碍物处无法通行,状态就设成0
|
||||||
|
if obstacleGrid[i][j] == 1:
|
||||||
|
curr[j] = 0
|
||||||
|
elif j > 0:
|
||||||
|
# 等价于
|
||||||
|
# dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
|
||||||
|
curr[j] = curr[j] + curr[j - 1]
|
||||||
|
# 隐含的状态更新
|
||||||
|
# dp[i][0] = dp[i - 1][0]
|
||||||
|
|
||||||
|
return curr[n - 1]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -314,7 +314,62 @@ func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
JavaScript版本
|
||||||
|
> 递归
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* Definition for a binary tree node.
|
||||||
|
* function TreeNode(val) {
|
||||||
|
* this.val = val;
|
||||||
|
* this.left = this.right = null;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {TreeNode} root
|
||||||
|
* @param {TreeNode} p
|
||||||
|
* @param {TreeNode} q
|
||||||
|
* @return {TreeNode}
|
||||||
|
*/
|
||||||
|
var lowestCommonAncestor = function(root, p, q) {
|
||||||
|
if(root.val > p.val && root.val > q.val)
|
||||||
|
return lowestCommonAncestor(root.left, p , q);
|
||||||
|
else if(root.val < p.val && root.val < q.val)
|
||||||
|
return lowestCommonAncestor(root.right, p , q);
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> 迭代
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* Definition for a binary tree node.
|
||||||
|
* function TreeNode(val) {
|
||||||
|
* this.val = val;
|
||||||
|
* this.left = this.right = null;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {TreeNode} root
|
||||||
|
* @param {TreeNode} p
|
||||||
|
* @param {TreeNode} q
|
||||||
|
* @return {TreeNode}
|
||||||
|
*/
|
||||||
|
var lowestCommonAncestor = function(root, p, q) {
|
||||||
|
while(1) {
|
||||||
|
if(root.val > p.val && root.val > q.val)
|
||||||
|
root = root.left;
|
||||||
|
else if(root.val < p.val && root.val < q.val)
|
||||||
|
root = root.right;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -208,6 +208,7 @@ public:
|
|||||||
|
|
||||||
Java:
|
Java:
|
||||||
```Java
|
```Java
|
||||||
|
//解法一
|
||||||
//自定义数组
|
//自定义数组
|
||||||
class MyQueue {
|
class MyQueue {
|
||||||
Deque<Integer> deque = new LinkedList<>();
|
Deque<Integer> deque = new LinkedList<>();
|
||||||
@ -260,6 +261,40 @@ class Solution {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//解法二
|
||||||
|
//利用双端队列手动实现单调队列
|
||||||
|
/**
|
||||||
|
* 用一个单调队列来存储对应的下标,每当窗口滑动的时候,直接取队列的头部指针对应的值放入结果集即可
|
||||||
|
* 单调队列类似 (tail -->) 3 --> 2 --> 1 --> 0 (--> head) (右边为头结点,元素存的是下标)
|
||||||
|
*/
|
||||||
|
class Solution {
|
||||||
|
public int[] maxSlidingWindow(int[] nums, int k) {
|
||||||
|
ArrayDeque<Integer> deque = new ArrayDeque<>();
|
||||||
|
int n = nums.length;
|
||||||
|
int[] res = new int[n - k + 1];
|
||||||
|
int idx = 0;
|
||||||
|
for(int i = 0; i < n; i++) {
|
||||||
|
// 根据题意,i为nums下标,是要在[i - k + 1, k] 中选到最大值,只需要保证两点
|
||||||
|
// 1.队列头结点需要在[i - k + 1, k]范围内,不符合则要弹出
|
||||||
|
while(!deque.isEmpty() && deque.peek() < i - k + 1){
|
||||||
|
deque.poll();
|
||||||
|
}
|
||||||
|
// 2.既然是单调,就要保证每次放进去的数字要比末尾的都大,否则也弹出
|
||||||
|
while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
|
||||||
|
deque.pollLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
deque.offer(i);
|
||||||
|
|
||||||
|
// 因为单调,当i增长到符合第一个k范围的时候,每滑动一步都将队列头节点放入结果就行了
|
||||||
|
if(i >= k - 1){
|
||||||
|
res[idx++] = nums[deque.peek()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
@ -155,7 +155,7 @@ class Solution {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
```python3
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
def reverseString(self, s: List[str]) -> None:
|
def reverseString(self, s: List[str]) -> None:
|
||||||
"""
|
"""
|
||||||
@ -166,6 +166,17 @@ class Solution:
|
|||||||
s[left], s[right] = s[right], s[left]
|
s[left], s[right] = s[right], s[left]
|
||||||
left += 1
|
left += 1
|
||||||
right -= 1
|
right -= 1
|
||||||
|
|
||||||
|
# 下面的写法更加简洁,但是都是同样的算法
|
||||||
|
# class Solution:
|
||||||
|
# def reverseString(self, s: List[str]) -> None:
|
||||||
|
# """
|
||||||
|
# Do not return anything, modify s in-place instead.
|
||||||
|
# """
|
||||||
|
# 不需要判别是偶数个还是奇数个序列,因为奇数个的时候,中间那个不需要交换就可
|
||||||
|
# for i in range(len(s)//2):
|
||||||
|
# s[i], s[len(s)-1-i] = s[len(s)-1-i], s[i]
|
||||||
|
# return s
|
||||||
```
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
@ -214,12 +214,9 @@ Python:
|
|||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
|
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
|
||||||
people.sort(key=lambda x: (x[0], -x[1]), reverse=True)
|
people.sort(key=lambda x: (-x[0], x[1]))
|
||||||
que = []
|
que = []
|
||||||
for p in people:
|
for p in people:
|
||||||
if p[1] > len(que):
|
|
||||||
que.append(p)
|
|
||||||
else:
|
|
||||||
que.insert(p[1], p)
|
que.insert(p[1], p)
|
||||||
return que
|
return que
|
||||||
```
|
```
|
||||||
|
@ -358,6 +358,51 @@ func deleteNode1(root *TreeNode)*TreeNode{
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
JavaScript版本
|
||||||
|
|
||||||
|
> 递归
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* Definition for a binary tree node.
|
||||||
|
* function TreeNode(val, left, right) {
|
||||||
|
* this.val = (val===undefined ? 0 : val)
|
||||||
|
* this.left = (left===undefined ? null : left)
|
||||||
|
* this.right = (right===undefined ? null : right)
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param {TreeNode} root
|
||||||
|
* @param {number} key
|
||||||
|
* @return {TreeNode}
|
||||||
|
*/
|
||||||
|
var deleteNode = function (root, key) {
|
||||||
|
if (root === null)
|
||||||
|
return root;
|
||||||
|
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;
|
||||||
|
let temp = root;
|
||||||
|
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);
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -368,6 +368,20 @@ func mergeTrees(t1 *TreeNode, t2 *TreeNode) *TreeNode {
|
|||||||
Right: mergeTrees(t1.Right,t2.Right)}
|
Right: mergeTrees(t1.Right,t2.Right)}
|
||||||
return root
|
return root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 前序遍历简洁版
|
||||||
|
func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
|
||||||
|
if root1 == nil {
|
||||||
|
return root2
|
||||||
|
}
|
||||||
|
if root2 == nil {
|
||||||
|
return root1
|
||||||
|
}
|
||||||
|
root1.Val += root2.Val
|
||||||
|
root1.Left = mergeTrees(root1.Left, root2.Left)
|
||||||
|
root1.Right = mergeTrees(root1.Right, root2.Right)
|
||||||
|
return root1
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
JavaScript:
|
JavaScript:
|
||||||
|
@ -286,8 +286,118 @@ func insertIntoBST(root *TreeNode, val int) *TreeNode {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
JavaScript版本
|
||||||
|
|
||||||
|
> 有返回值的递归写法
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* Definition for a binary tree node.
|
||||||
|
* function TreeNode(val, left, right) {
|
||||||
|
* this.val = (val===undefined ? 0 : val)
|
||||||
|
* this.left = (left===undefined ? null : left)
|
||||||
|
* this.right = (right===undefined ? null : right)
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param {TreeNode} root
|
||||||
|
* @param {number} val
|
||||||
|
* @return {TreeNode}
|
||||||
|
*/
|
||||||
|
var insertIntoBST = function (root, val) {
|
||||||
|
const setInOrder = (root, val) => {
|
||||||
|
if (root === null) {
|
||||||
|
let node = new TreeNode(val);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
if (root.val > val)
|
||||||
|
root.left = setInOrder(root.left, val);
|
||||||
|
else if (root.val < val)
|
||||||
|
root.right = setInOrder(root.right, val);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
return setInOrder(root, val);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> 无返回值的递归
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* Definition for a binary tree node.
|
||||||
|
* function TreeNode(val, left, right) {
|
||||||
|
* this.val = (val===undefined ? 0 : val)
|
||||||
|
* this.left = (left===undefined ? null : left)
|
||||||
|
* this.right = (right===undefined ? null : right)
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param {TreeNode} root
|
||||||
|
* @param {number} val
|
||||||
|
* @return {TreeNode}
|
||||||
|
*/
|
||||||
|
var insertIntoBST = function (root, val) {
|
||||||
|
let parent = new TreeNode(0);
|
||||||
|
const preOrder = (cur, val) => {
|
||||||
|
if (cur === null) {
|
||||||
|
let node = new TreeNode(val);
|
||||||
|
if (parent.val > val)
|
||||||
|
parent.left = node;
|
||||||
|
else
|
||||||
|
parent.right = node;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parent = cur;
|
||||||
|
if (cur.val > val)
|
||||||
|
preOrder(cur.left, val);
|
||||||
|
if (cur.val < val)
|
||||||
|
preOrder(cur.right, val);
|
||||||
|
}
|
||||||
|
if (root === null)
|
||||||
|
root = new TreeNode(val);
|
||||||
|
preOrder(root, val);
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> 迭代
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* Definition for a binary tree node.
|
||||||
|
* function TreeNode(val, left, right) {
|
||||||
|
* this.val = (val===undefined ? 0 : val)
|
||||||
|
* this.left = (left===undefined ? null : left)
|
||||||
|
* this.right = (right===undefined ? null : right)
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param {TreeNode} root
|
||||||
|
* @param {number} val
|
||||||
|
* @return {TreeNode}
|
||||||
|
*/
|
||||||
|
var insertIntoBST = function (root, val) {
|
||||||
|
if (root === null) {
|
||||||
|
root = new TreeNode(val);
|
||||||
|
} else {
|
||||||
|
let parent = new TreeNode(0);
|
||||||
|
let cur = root;
|
||||||
|
while (cur) {
|
||||||
|
parent = cur;
|
||||||
|
if (cur.val > val)
|
||||||
|
cur = cur.left;
|
||||||
|
else
|
||||||
|
cur = cur.right;
|
||||||
|
}
|
||||||
|
let node = new TreeNode(val);
|
||||||
|
if (parent.val > val)
|
||||||
|
parent.left = node;
|
||||||
|
else
|
||||||
|
parent.right = node;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||||
|
@ -127,7 +127,9 @@ Java:
|
|||||||
```Java
|
```Java
|
||||||
class Solution {
|
class Solution {
|
||||||
public String removeDuplicates(String S) {
|
public String removeDuplicates(String S) {
|
||||||
Deque<Character> deque = new LinkedList<>();
|
//ArrayDeque会比LinkedList在除了删除元素这一点外会快一点
|
||||||
|
//参考:https://stackoverflow.com/questions/6163166/why-is-arraydeque-better-than-linkedlist
|
||||||
|
ArrayDeque<Character> deque = new ArrayDeque<>();
|
||||||
char ch;
|
char ch;
|
||||||
for (int i = 0; i < S.length(); i++) {
|
for (int i = 0; i < S.length(); i++) {
|
||||||
ch = S.charAt(i);
|
ch = S.charAt(i);
|
||||||
@ -171,6 +173,29 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
拓展:双指针
|
||||||
|
```java
|
||||||
|
class Solution {
|
||||||
|
public String removeDuplicates(String s) {
|
||||||
|
char[] ch = s.toCharArray();
|
||||||
|
int fast = 0;
|
||||||
|
int slow = 0;
|
||||||
|
while(fast < s.length()){
|
||||||
|
// 直接用fast指针覆盖slow指针的值
|
||||||
|
ch[slow] = ch[fast];
|
||||||
|
// 遇到前后相同值的,就跳过,即slow指针后退一步,下次循环就可以直接被覆盖掉了
|
||||||
|
if(slow > 0 && ch[slow] == ch[slow - 1]){
|
||||||
|
slow--;
|
||||||
|
}else{
|
||||||
|
slow++;
|
||||||
|
}
|
||||||
|
fast++;
|
||||||
|
}
|
||||||
|
return new String(ch,0,slow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
```python3
|
```python3
|
||||||
class Solution:
|
class Solution:
|
||||||
|
@ -155,9 +155,82 @@ public:
|
|||||||
|
|
||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 前序遍历顺序:中-左-右,入栈顺序:中-右-左
|
||||||
|
class Solution {
|
||||||
|
public List<Integer> preorderTraversal(TreeNode root) {
|
||||||
|
List<Integer> result = new ArrayList<>();
|
||||||
|
if (root == null){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Stack<TreeNode> stack = new Stack<>();
|
||||||
|
stack.push(root);
|
||||||
|
while (!stack.isEmpty()){
|
||||||
|
TreeNode node = stack.pop();
|
||||||
|
result.add(node.val);
|
||||||
|
if (node.right != null){
|
||||||
|
stack.push(node.right);
|
||||||
|
}
|
||||||
|
if (node.left != null){
|
||||||
|
stack.push(node.left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 中序遍历顺序: 左-中-右 入栈顺序: 左-右
|
||||||
|
class Solution {
|
||||||
|
public List<Integer> inorderTraversal(TreeNode root) {
|
||||||
|
List<Integer> result = new ArrayList<>();
|
||||||
|
if (root == null){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Stack<TreeNode> stack = new Stack<>();
|
||||||
|
TreeNode cur = root;
|
||||||
|
while (cur != null || !stack.isEmpty()){
|
||||||
|
if (cur != null){
|
||||||
|
stack.push(cur);
|
||||||
|
cur = cur.left;
|
||||||
|
}else{
|
||||||
|
cur = stack.pop();
|
||||||
|
result.add(cur.val);
|
||||||
|
cur = cur.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 后序遍历顺序 左-右-中 入栈顺序:中-左-右 出栈顺序:中-右-左, 最后翻转结果
|
||||||
|
class Solution {
|
||||||
|
public List<Integer> postorderTraversal(TreeNode root) {
|
||||||
|
List<Integer> result = new ArrayList<>();
|
||||||
|
if (root == null){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Stack<TreeNode> stack = new Stack<>();
|
||||||
|
stack.push(root);
|
||||||
|
while (!stack.isEmpty()){
|
||||||
|
TreeNode node = stack.pop();
|
||||||
|
result.add(node.val);
|
||||||
|
if (node.left != null){
|
||||||
|
stack.push(node.left);
|
||||||
|
}
|
||||||
|
if (node.right != null){
|
||||||
|
stack.push(node.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.reverse(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
```python3
|
```python3
|
||||||
|
Reference in New Issue
Block a user