mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 00:43:04 +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]
|
||||
```
|
||||
|
||||
```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:
|
||||
|
||||
|
@ -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
|
||||
//解法一
|
||||
//自定义数组
|
||||
class MyQueue {
|
||||
Deque<Integer> deque = new LinkedList<>();
|
||||
@ -260,6 +261,40 @@ class Solution {
|
||||
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:
|
||||
|
@ -155,7 +155,7 @@ class Solution {
|
||||
```
|
||||
|
||||
Python:
|
||||
```python3
|
||||
```python
|
||||
class Solution:
|
||||
def reverseString(self, s: List[str]) -> None:
|
||||
"""
|
||||
@ -166,6 +166,17 @@ class Solution:
|
||||
s[left], s[right] = s[right], s[left]
|
||||
left += 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:
|
||||
|
@ -214,13 +214,10 @@ Python:
|
||||
```python
|
||||
class Solution:
|
||||
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 = []
|
||||
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
|
||||
```
|
||||
|
||||
|
@ -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)}
|
||||
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:
|
||||
|
@ -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)
|
||||
|
@ -127,7 +127,9 @@ Java:
|
||||
```Java
|
||||
class Solution {
|
||||
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;
|
||||
for (int i = 0; i < S.length(); 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:
|
||||
```python3
|
||||
class Solution:
|
||||
|
@ -155,9 +155,82 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
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:
|
||||
```python3
|
||||
|
Reference in New Issue
Block a user