Merge branch 'youngyangyang04:master' into master

This commit is contained in:
ironerhalo
2021-08-04 20:49:05 +08:00
committed by GitHub
10 changed files with 394 additions and 51 deletions

View File

@ -201,6 +201,54 @@ class Solution(object):
```
Go
```go
func fourSum(nums []int, target int) [][]int {
if len(nums) < 4 {
return nil
}
sort.Ints(nums)
var res [][]int
for i := 0; i < len(nums)-3; i++ {
n1 := nums[i]
// if n1 > target { // 不能这样写,因为可能是负数
// break
// }
if i > 0 && n1 == nums[i-1] {
continue
}
for j := i + 1; j < len(nums)-2; j++ {
n2 := nums[j]
if j > i+1 && n2 == nums[j-1] {
continue
}
l := j + 1
r := len(nums) - 1
for l < r {
n3 := nums[l]
n4 := nums[r]
sum := n1 + n2 + n3 + n4
if sum < target {
l++
} else if sum > target {
r--
} else {
res = append(res, []int{n1, n2, n3, n4})
for l < r && n3 == nums[l+1] { // 去重
l++
}
for l < r && n4 == nums[r-1] { // 去重
r--
}
// 找到答案时,双指针同时靠近
r--
l++
}
}
}
}
return res
}
```
javaScript:

View File

@ -168,6 +168,23 @@ func max(a,b int) int{
}
```
JavaScript
```javascript
const maxSubArray = nums => {
// 数组长度dp初始化
const [len, dp] = [nums.length, [nums[0]]];
// 最大值初始化为dp[0]
let max = dp[0];
for (let i = 1; i < len; i++) {
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
// 更新最大值
max = Math.max(max, dp[i]);
}
return max;
};
```
-----------------------

View File

@ -337,6 +337,8 @@ class Solution {
```
Python
**递归** - 利用BST中序遍历特性,把树"压缩"成数组
```python
# Definition for a binary tree node.
# class TreeNode:
@ -344,29 +346,56 @@ Python
# self.val = val
# self.left = left
# self.right = right
# 递归法
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
res = [] //把二叉搜索树按中序遍历写成list
def buildalist(root):
if not root: return
buildalist(root.left) //左
res.append(root.val) //中
buildalist(root.right) //右
return res
buildalist(root)
return res == sorted(res) and len(set(res)) == len(res) //检查list里的数有没有重复元素以及是否按从小到大排列
# 思路: 利用BST中序遍历的特性.
# 中序遍历输出的二叉搜索树节点的数值是有序序列
candidate_list = []
# 简单递归法
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
def isBST(root, min_val, max_val):
if not root: return True
if root.val >= max_val or root.val <= min_val:
def __traverse(root: TreeNode) -> None:
nonlocal candidate_list
if not root:
return
__traverse(root.left)
candidate_list.append(root.val)
__traverse(root.right)
def __is_sorted(nums: list) -> bool:
for i in range(1, len(nums)):
if nums[i] <= nums[i - 1]: # ⚠️ 注意: Leetcode定义二叉搜索树中不能有重复元素
return False
return isBST(root.left, min_val, root.val) and isBST(root.right, root.val, max_val)
return isBST(root, float("-inf"), float("inf"))
return True
__traverse(root)
res = __is_sorted(candidate_list)
return res
```
**递归** - 标准做法
```python
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
# 规律: BST的中序遍历节点数值是从小到大.
cur_max = -float("INF")
def __isValidBST(root: TreeNode) -> bool:
nonlocal cur_max
if not root:
return True
is_left_valid = __isValidBST(root.left)
if cur_max < root.val:
cur_max = root.val
else:
return False
is_right_valid = __isValidBST(root.right)
return is_left_valid and is_right_valid
return __isValidBST(root)
```
```
# 迭代-中序遍历
class Solution:
def isValidBST(self, root: TreeNode) -> bool:

View File

@ -172,6 +172,22 @@ public:
Java
```java
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
} else if (q == null || p == null) {
return false;
} else if (q.val != p.val) {
return false;
} else {
return isSameTree(q.left, p.left) && isSameTree(q.right, p.right);
}
}
}
```
Python
Go

View File

@ -180,7 +180,30 @@ class Solution:
return False
```
Go
JavaScript
```javascript
const isSubsequence = (s, t) => {
// s、t的长度
const [m, n] = [s.length, t.length];
// dp全初始化为0
const dp = new Array(m + 1).fill(0).map(x => new Array(n + 1).fill(0));
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
// 更新dp[i][j],两种情况
if (s[i - 1] === t[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = dp[i][j - 1];
}
}
}
// 遍历结束判断dp右下角的数是否等于s的长度
return dp[m][n] === m ? true : false;
};
```

View File

@ -312,6 +312,8 @@ class Solution {
```
Python
**递归法 - 前序遍历**
```python
# Definition for a binary tree node.
# class TreeNode:
@ -319,41 +321,57 @@ Python
# self.val = val
# self.left = left
# self.right = right
# 递归法*前序遍历
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
if not root1: return root2 // 如果t1为空合并之后就应该是t2
if not root2: return root1 // 如果t2为空合并之后就应该是t1
root1.val = root1.val + root2.val //中
root1.left = self.mergeTrees(root1.left , root2.left) //左
root1.right = self.mergeTrees(root1.right , root2.right) //右
return root1 //root1修改了结构和数值
# 递归终止条件:
# 但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
if not root1:
return root2
if not root2:
return root1
# 上面的递归终止条件保证了代码执行到这里root1, root2都非空.
root1.val += root2.val # 中
root1.left = self.mergeTrees(root1.left, root2.left) #左
root1.right = self.mergeTrees(root1.right, root2.right) # 右
# 迭代法-覆盖原来的树
return root1 # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间.
```
**迭代法**
```python
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
if not root1: return root2
if not root2: return root1
# 迭代,将树2覆盖到树1
queue1 = [root1]
queue2 = [root2]
root = root1
while queue1 and queue2:
root1 = queue1.pop(0)
root2 = queue2.pop(0)
root1.val += root2.val
if not root1.left: # 如果树1左儿子不存在则覆盖后树1的左儿子为树2的左儿子
root1.left = root2.left
elif root1.left and root2.left:
queue1.append(root1.left)
queue2.append(root2.left)
if not root1:
return root2
if not root2:
return root1
if not root1.right: # 同理,处理右儿子
root1.right = root2.right
elif root1.right and root2.right:
queue1.append(root1.right)
queue2.append(root2.right)
return root
queue = deque()
queue.append(root1)
queue.append(root2)
while queue:
node1 = queue.popleft()
node2 = queue.popleft()
# 更新queue
# 只有两个节点都有左节点时, 再往queue里面放.
if node1.left and node2.left:
queue.append(node1.left)
queue.append(node2.left)
# 只有两个节点都有右节点时, 再往queue里面放.
if node1.right and node2.right:
queue.append(node1.right)
queue.append(node2.right)
# 更新当前节点. 同时改变当前节点的左右孩子.
node1.val += node2.val
if not node1.left and node2.left:
node1.left = node2.left
if not node1.right and node2.right:
node1.right = node2.right
return root1
```
Go

View File

@ -220,9 +220,18 @@ Python
# self.right = right
class Solution:
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
if not root or root.val == val: return root //为空或者已经找到都是直接返回root所以合并了
if root.val > val: return self.searchBST(root.left,val) //注意一定要加return
else: return self.searchBST(root.right,val)
# 为什么要有返回值:
# 因为搜索到目标节点就要立即return
# 这样才是找到节点就返回搜索某一条边如果不加return就是遍历整棵树了。
if not root or root.val == val:
return root
if root.val > val:
return self.searchBST(root.left, val)
if root.val < val:
return self.searchBST(root.right, val)
```

View File

@ -154,7 +154,129 @@ private:
## 其他语言版本
C:
```C
typedef struct {
int val;
struct MyLinkedList* next;
}MyLinkedList;
/** Initialize your data structure here. */
MyLinkedList* myLinkedListCreate() {
//这个题必须用虚拟头指针,参数都是一级指针,头节点确定后没法改指向了!!!
MyLinkedList* head = (MyLinkedList *)malloc(sizeof (MyLinkedList));
head->next = NULL;
return head;
}
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
int myLinkedListGet(MyLinkedList* obj, int index) {
MyLinkedList *cur = obj->next;
for (int i = 0; cur != NULL; i++){
if (i == index){
return cur->val;
}
else{
cur = cur->next;
}
}
return -1;
}
/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
MyLinkedList *nhead = (MyLinkedList *)malloc(sizeof (MyLinkedList));
nhead->val = val;
nhead->next = obj->next;
obj->next = nhead;
}
/** Append a node of value val to the last element of the linked list. */
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
MyLinkedList *cur = obj;
while(cur->next != NULL){
cur = cur->next;
}
MyLinkedList *ntail = (MyLinkedList *)malloc(sizeof (MyLinkedList));
ntail->val = val;
ntail->next = NULL;
cur->next = ntail;
}
/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
if (index == 0){
myLinkedListAddAtHead(obj, val);
return;
}
MyLinkedList *cur = obj->next;
for (int i = 1 ;cur != NULL; i++){
if (i == index){
MyLinkedList* newnode = (MyLinkedList *)malloc(sizeof (MyLinkedList));
newnode->val = val;
newnode->next = cur->next;
cur->next = newnode;
return;
}
else{
cur = cur->next;
}
}
}
/** Delete the index-th node in the linked list, if the index is valid. */
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
if (index == 0){
MyLinkedList *tmp = obj->next;
if (tmp != NULL){
obj->next = tmp->next;
free(tmp)
}
return;
}
MyLinkedList *cur = obj->next;
for (int i = 1 ;cur != NULL && cur->next != NULL; i++){
if (i == index){
MyLinkedList *tmp = cur->next;
if (tmp != NULL) {
cur->next = tmp->next;
free(tmp);
}
return;
}
else{
cur = cur->next;
}
}
}
void myLinkedListFree(MyLinkedList* obj) {
while(obj != NULL){
MyLinkedList *tmp = obj;
obj = obj->next;
free(tmp);
}
}
/**
* Your MyLinkedList struct will be instantiated and called as such:
* MyLinkedList* obj = myLinkedListCreate();
* int param_1 = myLinkedListGet(obj, index);
* myLinkedListAddAtHead(obj, val);
* myLinkedListAddAtTail(obj, val);
* myLinkedListAddAtIndex(obj, index, val);
* myLinkedListDeleteAtIndex(obj, index);
* myLinkedListFree(obj);
*/
```
Java
```Java

View File

@ -169,6 +169,46 @@ class Solution {
}
}
```
javaScript
```js
var commonChars = function (words) {
let res = []
let size = 26
let firstHash = new Array(size)
for (let i = 0; i < size; i++) { // 初始化 hash 数组
firstHash[i] = 0
}
let a = "a".charCodeAt()
let firstWord = words[0]
for (let i = 0; i < firstWord.length; i++) { // 第 0 个单词的统计
let idx = firstWord[i].charCodeAt()
firstHash[idx - a] += 1
}
for (let i = 1; i < words.length; i++) { // 1-n 个单词统计
let otherHash = new Array(size)
for (let i = 0; i < size; i++) { // 初始化 hash 数组
otherHash[i] = 0
}
for (let j = 0; j < words[i].length; j++) {
let idx = words[i][j].charCodeAt()
otherHash[idx - a] += 1
}
for (let i = 0; i < size; i++) {
firstHash[i] = Math.min(firstHash[i], otherHash[i])
}
}
for (let i = 0; i < size; i++) {
while (firstHash[i] > 0) {
res.push(String.fromCharCode(i + a))
firstHash[i]--
}
}
return res
};
```
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)

View File

@ -109,7 +109,28 @@ class Solution:
return dp[-1][-1]
```
Go
JavaScript
```javascript
const maxUncrossedLines = (nums1, nums2) => {
// 两个数组长度
const [m, n] = [nums1.length, nums2.length];
// 创建dp数组并都初始化为0
const dp = new Array(m + 1).fill(0).map(x => new Array(n + 1).fill(0));
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
// 根据两种情况更新dp[i][j]
if (nums1[i - 1] === nums2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
// 返回dp数组中右下角的元素
return dp[m][n];
};
```