mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 08:50:15 +08:00
Merge branch 'master' into XiongGu-branch
This commit is contained in:
@ -110,7 +110,7 @@ public ListNode removeNthFromEnd(ListNode head, int n){
|
|||||||
fastIndex = fastIndex.next;
|
fastIndex = fastIndex.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fastIndex.next != null){
|
while (fastIndex != null){
|
||||||
fastIndex = fastIndex.next;
|
fastIndex = fastIndex.next;
|
||||||
slowIndex = slowIndex.next;
|
slowIndex = slowIndex.next;
|
||||||
}
|
}
|
||||||
|
@ -226,18 +226,20 @@ object Solution {
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
function maxSubArray(nums: number[]): number {
|
function maxSubArray(nums: number[]): number {
|
||||||
/**
|
const len = nums.length
|
||||||
dp[i]:以nums[i]结尾的最大和
|
if (len === 1) return nums[0]
|
||||||
*/
|
|
||||||
const dp: number[] = []
|
const dp: number[] = new Array(len)
|
||||||
dp[0] = nums[0];
|
let resMax: number = dp[0] = nums[0]
|
||||||
let resMax: number = 0;
|
|
||||||
for (let i = 1; i < nums.length; i++) {
|
for (let i = 1; i < len; i++) {
|
||||||
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
|
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i])
|
||||||
resMax = Math.max(resMax, dp[i]);
|
// 注意值为负数的情况
|
||||||
|
if (dp[i] > resMax) resMax = dp[i]
|
||||||
}
|
}
|
||||||
return resMax;
|
|
||||||
};
|
return resMax
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -595,6 +595,43 @@ var isValidBST = function (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
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
let pre = null;
|
||||||
|
var isValidBST = function (root) {
|
||||||
|
const queue = [];
|
||||||
|
let cur = root;
|
||||||
|
let pre = null;
|
||||||
|
while (cur !== null || queue.length !== 0) {
|
||||||
|
if (cur !== null) {
|
||||||
|
queue.push(cur);
|
||||||
|
cur = cur.left;
|
||||||
|
} else {
|
||||||
|
cur = queue.pop();
|
||||||
|
if (pre !== null && cur.val <= pre.val) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pre = cur;
|
||||||
|
cur = cur.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### TypeScript
|
### TypeScript
|
||||||
|
|
||||||
> 辅助数组解决:
|
> 辅助数组解决:
|
||||||
@ -637,6 +674,30 @@ function isValidBST(root: TreeNode | null): boolean {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> 迭代法:
|
||||||
|
|
||||||
|
```TypeScript
|
||||||
|
function isValidBST(root: TreeNode | null): boolean {
|
||||||
|
const queue: TreeNode[] = [];
|
||||||
|
let cur: TreeNode | null = root;
|
||||||
|
let pre: TreeNode | null = null;
|
||||||
|
while (cur !== null || queue.length !== 0) {
|
||||||
|
if (cur !== null) {
|
||||||
|
queue.push(cur);
|
||||||
|
cur = cur.left;
|
||||||
|
} else {
|
||||||
|
cur = queue.pop()!;
|
||||||
|
if (pre !== null && cur!.val <= pre.val) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pre = cur;
|
||||||
|
cur = cur!.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Scala
|
### Scala
|
||||||
|
|
||||||
辅助数组解决:
|
辅助数组解决:
|
||||||
|
@ -62,9 +62,9 @@ public:
|
|||||||
|
|
||||||
每次窗口移动的时候,调用que.pop(滑动窗口中移除元素的数值),que.push(滑动窗口添加元素的数值),然后que.front()就返回我们要的最大值。
|
每次窗口移动的时候,调用que.pop(滑动窗口中移除元素的数值),que.push(滑动窗口添加元素的数值),然后que.front()就返回我们要的最大值。
|
||||||
|
|
||||||
这么个队列香不香,要是有现成的这种数据结构是不是更香了!
|
这么个队列香不香,要是有现成的这种数据结构是不是更香了!
|
||||||
|
|
||||||
**可惜了,没有! 我们需要自己实现这么个队列。**
|
其实在C++中,可以使用 multiset 来模拟这个过程,文末提供这个解法仅针对C++,以下讲解我们还是靠自己来实现这个单调队列。
|
||||||
|
|
||||||
然后再分析一下,队列里的元素一定是要排序的,而且要最大值放在出队口,要不然怎么知道最大值呢。
|
然后再分析一下,队列里的元素一定是要排序的,而且要最大值放在出队口,要不然怎么知道最大值呢。
|
||||||
|
|
||||||
@ -839,6 +839,28 @@ impl Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### C++
|
||||||
|
使用multiset作为单调队列
|
||||||
|
|
||||||
|
多重集合(`multiset`) 用以有序地存储元素的容器。允许存在相等的元素。
|
||||||
|
|
||||||
|
在遍历原数组的时候,只需要把窗口的头元素加入到multiset中,然后把窗口的尾元素删除即可。因为multiset是有序的,并且提供了*rbegin(),可以直接获取窗口最大值。
|
||||||
|
```cpp
|
||||||
|
class Solution {
|
||||||
|
public:
|
||||||
|
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
|
||||||
|
multiset<int> st;
|
||||||
|
vector<int> ans;
|
||||||
|
for (int i = 0; i < nums.size(); i++) {
|
||||||
|
if (i >= k) st.erase(st.find(nums[i - k]));
|
||||||
|
st.insert(nums[i]);
|
||||||
|
if (i >= k - 1) ans.push_back(*st.rbegin());
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||||
|
@ -216,26 +216,51 @@ const isSubsequence = (s, t) => {
|
|||||||
|
|
||||||
### TypeScript:
|
### TypeScript:
|
||||||
|
|
||||||
|
> 二维数组
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
function isSubsequence(s: string, t: string): boolean {
|
function isSubsequence(s: string, t: string): boolean {
|
||||||
/**
|
/**
|
||||||
dp[i][j]: s的前i-1个,t的前j-1个,最长公共子序列的长度
|
dp[i][j]: s的前i-1个,t的前j-1个,最长公共子序列的长度
|
||||||
*/
|
*/
|
||||||
const sLen: number = s.length,
|
const sLen = s.length
|
||||||
tLen: number = t.length;
|
const tLen = t.length
|
||||||
const dp: number[][] = new Array(sLen + 1).fill(0)
|
const dp: number[][] = new Array(sLen + 1).fill(0).map(_ => new Array(tLen + 1).fill(0))
|
||||||
.map(_ => new Array(tLen + 1).fill(0));
|
|
||||||
for (let i = 1; i <= sLen; i++) {
|
for (let i = 1; i <= sLen; i++) {
|
||||||
for (let j = 1; j <= tLen; j++) {
|
for (let j = 1; j <= tLen; j++) {
|
||||||
if (s[i - 1] === t[j - 1]) {
|
if (s[i - 1] === t[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1
|
||||||
dp[i][j] = dp[i - 1][j - 1] + 1;
|
// 只需要取 j-2 的 dp 值即可,不用考虑 i-2
|
||||||
} else {
|
else dp[i][j] = dp[i][j - 1]
|
||||||
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dp[sLen][tLen] === s.length;
|
return dp[sLen][tLen] === s.length
|
||||||
};
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 滚动数组
|
||||||
|
```typescript
|
||||||
|
function isSubsequence(s: string, t: string): boolean {
|
||||||
|
const sLen = s.length
|
||||||
|
const tLen = t.length
|
||||||
|
const dp: number[] = new Array(tLen + 1).fill(0)
|
||||||
|
|
||||||
|
for (let i = 1; i <= sLen; i++) {
|
||||||
|
let prev: number = 0;
|
||||||
|
let temp: number = 0;
|
||||||
|
for (let j = 1; j <= tLen; j++) {
|
||||||
|
// 备份一下当前状态(经过上层迭代后的)
|
||||||
|
temp = dp[j]
|
||||||
|
// prev 相当于 dp[j-1](累加了上层的状态)
|
||||||
|
// 如果单纯 dp[j-1] 则不会包含上层状态
|
||||||
|
if (s[i - 1] === t[j - 1]) dp[j] = prev + 1
|
||||||
|
else dp[j] = dp[j - 1]
|
||||||
|
// 继续使用上一层状态更新参数用于当前层下一个状态
|
||||||
|
prev = temp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[tLen] === sLen
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Go:
|
### Go:
|
||||||
|
@ -345,6 +345,7 @@ class Solution:
|
|||||||
res = max(res, count)
|
res = max(res, count)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -221,6 +221,8 @@ const maxUncrossedLines = (nums1, nums2) => {
|
|||||||
|
|
||||||
### TypeScript:
|
### TypeScript:
|
||||||
|
|
||||||
|
> 二维数组
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
function maxUncrossedLines(nums1: number[], nums2: number[]): number {
|
function maxUncrossedLines(nums1: number[], nums2: number[]): number {
|
||||||
/**
|
/**
|
||||||
@ -243,6 +245,34 @@ function maxUncrossedLines(nums1: number[], nums2: number[]): number {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> 滚动数组
|
||||||
|
```typescript
|
||||||
|
function maxUncrossedLines(nums1: number[], nums2: number[]): number {
|
||||||
|
const len1 = nums1.length
|
||||||
|
const len2 = nums2.length
|
||||||
|
|
||||||
|
const dp: number[] = new Array(len2 + 1).fill(0)
|
||||||
|
|
||||||
|
for (let i = 1; i <= len1; i++) {
|
||||||
|
let prev: number = 0;
|
||||||
|
let temp: number = 0;
|
||||||
|
for (let j = 1; j <= len2; j++) {
|
||||||
|
// 备份一下当前状态(经过上层迭代后的)
|
||||||
|
temp = dp[j]
|
||||||
|
// prev 相当于 dp[j-1](累加了上层的状态)
|
||||||
|
// 如果单纯 dp[j-1] 则不会包含上层状态
|
||||||
|
if (nums1[i - 1] === nums2[j - 1]) dp[j] = prev + 1
|
||||||
|
// dp[j] 表示之前的 dp[i][j-1],dp[j-1] 表示 dp[i-1][j]
|
||||||
|
else dp[j] = Math.max(dp[j], dp[j - 1])
|
||||||
|
// 继续使用上一层状态更新参数用于当前层下一个状态
|
||||||
|
prev = temp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[len2]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||||
|
Reference in New Issue
Block a user