This commit is contained in:
youngyangyang04
2021-06-28 15:19:46 +08:00
10 changed files with 405 additions and 8 deletions

View File

@ -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

View File

@ -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;
};
```
-----------------------

View File

@ -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

View File

@ -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

View File

@ -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
```

View File

@ -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;
};
```

View File

@ -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:

View File

@ -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)

View File

@ -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:

View File

@ -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