Skip to content

Commit

Permalink
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
Browse files Browse the repository at this point in the history
  • Loading branch information
youngyangyang04 committed Nov 21, 2021
2 parents 39fbb59 + efa673e commit 5ecb270
Show file tree
Hide file tree
Showing 19 changed files with 501 additions and 9 deletions.
27 changes: 27 additions & 0 deletions problems/0005.最长回文子串.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,32 @@ public:
## Java

```java
// 双指针 中心扩散法
class Solution {
public String longestPalindrome(String s) {
String s1 = "";
String s2 = "";
String res = "";
for (int i = 0; i < s.length(); i++) {
// 分两种情况:即一个元素作为中心点,两个元素作为中心点
s1 = extend(s, i, i); // 情况1
res = s1.length() > res.length() ? s1 : res;
s2 = extend(s, i, i + 1); // 情况2
res = s2.length() > res.length() ? s2 : res;
}
return res; // 返回最长的
}
public String extend(String s, int start, int end){
String tmp = "";
while (start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)){
tmp = s.substring(start, end + 1); // Java中substring是左闭右开的,所以要+1
// 向两边扩散
start--;
end++;
}
return tmp;
}
}
```

## Python
Expand Down Expand Up @@ -317,6 +343,7 @@ class Solution:
## Go
```go
```

## JavaScript
Expand Down
4 changes: 2 additions & 2 deletions problems/0028.实现strStr.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ next数组就是一个前缀表(prefix table)。

此时就要问了**前缀表是如何记录的呢?**

首先要知道前缀表的任务是当前位置匹配失败,找到之前已经匹配上的位置,在重新匹配,此也意味着在某个字符失配时,前缀表会告诉你下一步匹配中,模式串应该跳到哪个位置。
首先要知道前缀表的任务是当前位置匹配失败,找到之前已经匹配上的位置,再重新匹配,此也意味着在某个字符失配时,前缀表会告诉你下一步匹配中,模式串应该跳到哪个位置。

那么什么是前缀表:**记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。**

Expand Down Expand Up @@ -146,7 +146,7 @@ next数组就是一个前缀表(prefix table)。

# 为什么一定要用前缀表

这就是前缀表那为啥就能告诉我们 上次匹配的位置,并跳过去呢?
这就是前缀表,那为啥就能告诉我们 上次匹配的位置,并跳过去呢?

回顾一下,刚刚匹配的过程在下标5的地方遇到不匹配,模式串是指向f,如图:
<img src='https://code-thinking.cdn.bcebos.com/pics/KMP%E7%B2%BE%E8%AE%B21.png' width=600 alt='KMP精讲1'> </img></div>
Expand Down
23 changes: 23 additions & 0 deletions problems/0031.下一个排列.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,29 @@ class Solution:
low += 1
high -= 1
```
>上一版本简化版
'''python
class Solution(object):
def nextPermutation(self, nums: List[int]) -> None:
n = len(nums)
i = n-2
while i >= 0 and nums[i] >= nums[i+1]:
i -= 1
if i > -1: // i==-1,不存在下一个更大的排列
j = n-1
while j >= 0 and nums[j] <= nums[i]:
j -= 1
nums[i], nums[j] = nums[j], nums[i]
start, end = i+1, n-1
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start += 1
end -= 1
return nums
'''

## Go

Expand Down
41 changes: 41 additions & 0 deletions problems/0042.接雨水.md
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,48 @@ func trap(height []int) int {
}
```

动态规划解法:

```go
func trap(height []int) int {
sum:=0
n:=len(height)
lh:=make([]int,n)
rh:=make([]int,n)
lh[0]=height[0]
rh[n-1]=height[n-1]
for i:=1;i<n;i++{
lh[i]=max(lh[i-1],height[i])
}
for i:=n-2;i>=0;i--{
rh[i]=max(rh[i+1],height[i])
}
for i:=1;i<n-1;i++{
h:=min(rh[i],lh[i])-height[i]
if h>0{
sum+=h
}
}
return sum
}
func max(a,b int)int{
if a>b{
return a
}
return b
}
func min(a,b int)int{
if a<b{
return a
}
return b
}
```



JavaScript:

```javascript
//双指针
var trap = function(height) {
Expand Down
2 changes: 1 addition & 1 deletion problems/0047.全排列II.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

那么排列问题其实也是一样的套路。

**还要强调的是去重一定要对元素经行排序,这样我们才方便通过相邻的节点来判断是否重复使用了**
**还要强调的是去重一定要对元素进行排序,这样我们才方便通过相邻的节点来判断是否重复使用了**

我以示例中的 [1,1,2]为例 (为了方便举例,已经排序)抽象为一棵树,去重过程如图:

Expand Down
55 changes: 55 additions & 0 deletions problems/0104.二叉树的最大深度.md
Original file line number Diff line number Diff line change
Expand Up @@ -598,5 +598,60 @@ var maxDepth = function(root) {
};
```

## C
二叉树最大深度递归
```c
int maxDepth(struct TreeNode* root){
//若传入结点为NULL,返回0
if(!root)
return 0;

//求出左子树深度
int left = maxDepth(root->left);
//求出右子树深度
int right = maxDepth(root->right);
//求出左子树深度和右子树深度的较大值
int max = left > right ? left : right;
//返回较大值+1(1为当前层数)
return max + 1;
}
```
二叉树最大深度迭代
```c
int maxDepth(struct TreeNode* root){
//若传入根节点为NULL,返回0
if(!root)
return 0;
int depth = 0;
//开辟队列空间
struct TreeNode** queue = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 6000);
int queueFront = 0;
int queueEnd = 0;
//将根结点入队
queue[queueEnd++] = root;
int queueSize;
//求出当前队列中元素个数
while(queueSize = queueEnd - queueFront) {
int i;
//若当前队列中结点有左右子树,则将它们的左右子树入队
for(i = 0; i < queueSize; i++) {
struct TreeNode* tempNode = queue[queueFront + i];
if(tempNode->left)
queue[queueEnd++] = tempNode->left;
if(tempNode->right)
queue[queueEnd++] = tempNode->right;
}
//更新队头下标
queueFront += queueSize;
//深度+1
depth++;
}
return depth;
}
```

-----------------------
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
27 changes: 27 additions & 0 deletions problems/0122.买卖股票的最佳时机II(动态规划).md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,33 @@ class Solution:
```

Go:
```go
// 买卖股票的最佳时机Ⅱ 动态规划
// 时间复杂度O(n) 空间复杂度O(n)
func maxProfit(prices []int) int {
dp := make([][]int, len(prices))
status := make([]int, len(prices) * 2)
for i := range dp {
dp[i] = status[:2]
status = status[2:]
}
dp[0][0] = -prices[0]

for i := 1; i < len(prices); i++ {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i])
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i])
}

return dp[len(prices) - 1][1]
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
```

```go
func maxProfit(prices []int) int {
Expand Down
31 changes: 31 additions & 0 deletions problems/0123.买卖股票的最佳时机III.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,38 @@ const maxProfit = prices => {
};
```

Go:

> 版本一:
```go
// 买卖股票的最佳时机III 动态规划
// 时间复杂度O(n) 空间复杂度O(n)
func maxProfit(prices []int) int {
dp := make([][]int, len(prices))
status := make([]int, len(prices) * 4)
for i := range dp {
dp[i] = status[:4]
status = status[4:]
}
dp[0][0], dp[0][2] = -prices[0], -prices[0]

for i := 1; i < len(prices); i++ {
dp[i][0] = max(dp[i - 1][0], -prices[i])
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i])
dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] - prices[i])
dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] + prices[i])
}

return dp[len(prices) - 1][3]
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
```


-----------------------
Expand Down
35 changes: 35 additions & 0 deletions problems/0188.买卖股票的最佳时机IV.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,41 @@ class Solution:
return dp[2*k]
```
Go:
版本一:
```go
// 买卖股票的最佳时机IV 动态规划
// 时间复杂度O(kn) 空间复杂度O(kn)
func maxProfit(k int, prices []int) int {
if k == 0 || len(prices) == 0 {
return 0
}

dp := make([][]int, len(prices))
status := make([]int, (2 * k + 1) * len(prices))
for i := range dp {
dp[i] = status[:2 * k + 1]
status = status[2 * k + 1:]
}
for j := 1; j < 2 * k; j += 2 {
dp[0][j] = -prices[0]
}

for i := 1; i < len(prices); i++ {
for j := 0; j < 2 * k; j += 2 {
dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i])
dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i])
}
}
return dp[len(prices) - 1][2 * k]
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
```

```go
func maxProfit(k int, prices []int) int {
Expand Down
Loading

0 comments on commit 5ecb270

Please sign in to comment.