mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-09 19:44:45 +08:00
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
@ -68,7 +68,7 @@
|
|||||||
|
|
||||||
我在题目讲解中统一使用C++,但你会发现下面几乎每篇题解都配有其他语言版本,Java、Python、Go、JavaScript等等,正是这些[热心小伙们](https://github.com/youngyangyang04/leetcode-master/graphs/contributors)的贡献的代码,当然我也会严格把控代码质量。
|
我在题目讲解中统一使用C++,但你会发现下面几乎每篇题解都配有其他语言版本,Java、Python、Go、JavaScript等等,正是这些[热心小伙们](https://github.com/youngyangyang04/leetcode-master/graphs/contributors)的贡献的代码,当然我也会严格把控代码质量。
|
||||||
|
|
||||||
**所以也欢迎大家参与进来,完善题解的各个语言版本,拥抱开源,让更多小伙伴们收益**。
|
**所以也欢迎大家参与进来,完善题解的各个语言版本,拥抱开源,让更多小伙伴们受益**。
|
||||||
|
|
||||||
准备好了么,刷题攻略开始咯,go go go!
|
准备好了么,刷题攻略开始咯,go go go!
|
||||||
|
|
||||||
|
@ -152,25 +152,11 @@ class Solution:
|
|||||||
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
||||||
records = dict()
|
records = dict()
|
||||||
|
|
||||||
# 用枚举更方便,就不需要通过索引再去取当前位置的值
|
for index, value in enumerate(nums):
|
||||||
for idx, val in enumerate(nums):
|
if target - value in records:
|
||||||
if target - val not in records:
|
return [records[target- value], index]
|
||||||
records[val] = idx
|
records[value] = index
|
||||||
else:
|
return []
|
||||||
return [records[target - val], idx] # 如果存在就返回字典记录索引和当前索引
|
|
||||||
```
|
|
||||||
|
|
||||||
Python (v2):
|
|
||||||
|
|
||||||
```python
|
|
||||||
class Solution:
|
|
||||||
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
|
||||||
rec = {}
|
|
||||||
for i in range(len(nums)):
|
|
||||||
rest = target - nums[i]
|
|
||||||
# Use get to get the index of the data, making use of one of the dictionary properties.
|
|
||||||
if rec.get(rest, None) is not None: return [rec[rest], i]
|
|
||||||
rec[nums[i]] = i
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
@ -655,7 +655,7 @@ impl Solution {
|
|||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
// 双指针法
|
// 双指针法
|
||||||
use std::collections::HashSet;
|
use std::cmp::Ordering;
|
||||||
impl Solution {
|
impl Solution {
|
||||||
pub fn three_sum(nums: Vec<i32>) -> Vec<Vec<i32>> {
|
pub fn three_sum(nums: Vec<i32>) -> Vec<Vec<i32>> {
|
||||||
let mut result: Vec<Vec<i32>> = Vec::new();
|
let mut result: Vec<Vec<i32>> = Vec::new();
|
||||||
@ -667,21 +667,20 @@ impl Solution {
|
|||||||
if i > 0 && nums[i] == nums[i - 1] { continue; }
|
if i > 0 && nums[i] == nums[i - 1] { continue; }
|
||||||
let (mut left, mut right) = (i + 1, len - 1);
|
let (mut left, mut right) = (i + 1, len - 1);
|
||||||
while left < right {
|
while left < right {
|
||||||
if nums[i] + nums[left] + nums[right] > 0 {
|
match (nums[i] + nums[left] + nums[right]).cmp(&0){
|
||||||
right -= 1;
|
Ordering::Equal =>{
|
||||||
// 去重
|
|
||||||
while left < right && nums[right] == nums[right + 1] { right -= 1; }
|
|
||||||
} else if nums[i] + nums[left] + nums[right] < 0 {
|
|
||||||
left += 1;
|
|
||||||
// 去重
|
|
||||||
while left < right && nums[left] == nums[left - 1] { left += 1; }
|
|
||||||
} else {
|
|
||||||
result.push(vec![nums[i], nums[left], nums[right]]);
|
result.push(vec![nums[i], nums[left], nums[right]]);
|
||||||
// 去重
|
left +=1;
|
||||||
right -= 1;
|
right -=1;
|
||||||
|
while left < right && nums[left] == nums[left - 1]{
|
||||||
left += 1;
|
left += 1;
|
||||||
while left < right && nums[right] == nums[right + 1] { right -= 1; }
|
}
|
||||||
while left < right && nums[left] == nums[left - 1] { left += 1; }
|
while left < right && nums[right] == nums[right+1]{
|
||||||
|
right -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ordering::Greater => right -= 1,
|
||||||
|
Ordering::Less => left += 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,6 +527,7 @@ public class Solution
|
|||||||
|
|
||||||
Rust:
|
Rust:
|
||||||
```Rust
|
```Rust
|
||||||
|
use std::cmp::Ordering;
|
||||||
impl Solution {
|
impl Solution {
|
||||||
pub fn four_sum(nums: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
|
pub fn four_sum(nums: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
|
||||||
let mut result: Vec<Vec<i32>> = Vec::new();
|
let mut result: Vec<Vec<i32>> = Vec::new();
|
||||||
@ -545,21 +546,24 @@ impl Solution {
|
|||||||
if i > k + 1 && nums[i] == nums[i - 1] { continue; }
|
if i > k + 1 && nums[i] == nums[i - 1] { continue; }
|
||||||
let (mut left, mut right) = (i + 1, len - 1);
|
let (mut left, mut right) = (i + 1, len - 1);
|
||||||
while left < right {
|
while left < right {
|
||||||
if nums[k] + nums[i] > target - (nums[left] + nums[right]) {
|
match (nums[k] + nums[i] + nums[left] + nums[right]).cmp(&target){
|
||||||
right -= 1;
|
Ordering::Equal => {
|
||||||
// 去重
|
|
||||||
while left < right && nums[right] == nums[right + 1] { right -= 1; }
|
|
||||||
} else if nums[k] + nums[i] < target - (nums[left] + nums[right]) {
|
|
||||||
left += 1;
|
|
||||||
// 去重
|
|
||||||
while left < right && nums[left] == nums[left - 1] { left += 1; }
|
|
||||||
} else {
|
|
||||||
result.push(vec![nums[k], nums[i], nums[left], nums[right]]);
|
result.push(vec![nums[k], nums[i], nums[left], nums[right]]);
|
||||||
// 去重
|
|
||||||
while left < right && nums[right] == nums[right - 1] { right -= 1; }
|
|
||||||
while left < right && nums[left] == nums[left + 1] { left += 1; }
|
|
||||||
left += 1;
|
left += 1;
|
||||||
right -= 1;
|
right -= 1;
|
||||||
|
while left < right && nums[left] == nums[left - 1]{
|
||||||
|
left += 1;
|
||||||
|
}
|
||||||
|
while left < right && nums[right] == nums[right + 1]{
|
||||||
|
right -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ordering::Less => {
|
||||||
|
left +=1;
|
||||||
|
},
|
||||||
|
Ordering::Greater => {
|
||||||
|
right -= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,6 +364,40 @@ impl Solution {
|
|||||||
dummy_head.next
|
dummy_head.next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
C语言
|
||||||
|
```c
|
||||||
|
/**c语言单链表的定义
|
||||||
|
* Definition for singly-linked list.
|
||||||
|
* struct ListNode {
|
||||||
|
* int val;
|
||||||
|
* struct ListNode *next;
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
|
||||||
|
//定义虚拟头节点dummy 并初始化使其指向head
|
||||||
|
struct ListNode* dummy = malloc(sizeof(struct ListNode));
|
||||||
|
dummy->val = 0;
|
||||||
|
dummy->next = head;
|
||||||
|
//定义 fast slow 双指针
|
||||||
|
struct ListNode* fast = head;
|
||||||
|
struct ListNode* slow = dummy;
|
||||||
|
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
fast = fast->next;
|
||||||
|
}
|
||||||
|
while (fast) {
|
||||||
|
fast = fast->next;
|
||||||
|
slow = slow->next;
|
||||||
|
}
|
||||||
|
slow->next = slow->next->next;//删除倒数第n个节点
|
||||||
|
head = dummy->next;
|
||||||
|
free(dummy);//删除虚拟节点dummy
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -1299,6 +1299,53 @@ impl Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> 前缀表统一减一
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl Solution {
|
||||||
|
pub fn get_next(next_len: usize, s: &Vec<char>) -> Vec<i32> {
|
||||||
|
let mut next = vec![-1; next_len];
|
||||||
|
let mut j = -1;
|
||||||
|
for i in 1..s.len() {
|
||||||
|
while j >= 0 && s[(j + 1) as usize] != s[i] {
|
||||||
|
j = next[j as usize];
|
||||||
|
}
|
||||||
|
if s[i] == s[(j + 1) as usize] {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
next[i] = j;
|
||||||
|
}
|
||||||
|
next
|
||||||
|
}
|
||||||
|
pub fn str_str(haystack: String, needle: String) -> i32 {
|
||||||
|
if needle.is_empty() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if haystack.len() < needle.len() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
let (haystack_chars, needle_chars) = (
|
||||||
|
haystack.chars().collect::<Vec<char>>(),
|
||||||
|
needle.chars().collect::<Vec<char>>(),
|
||||||
|
);
|
||||||
|
let mut j = -1;
|
||||||
|
let next = Self::get_next(needle.len(), &needle_chars);
|
||||||
|
for (i, v) in haystack_chars.into_iter().enumerate() {
|
||||||
|
while j >= 0 && v != needle_chars[(j + 1) as usize] {
|
||||||
|
j = next[j as usize];
|
||||||
|
}
|
||||||
|
if v == needle_chars[(j + 1) as usize] {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
if j == needle_chars.len() as i32 - 1 {
|
||||||
|
return (i - needle_chars.len() + 1) as i32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
<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"/>
|
||||||
|
@ -256,7 +256,54 @@ int totalNQueens(int n){
|
|||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
Java
|
||||||
|
```java
|
||||||
|
class Solution {
|
||||||
|
int count = 0;
|
||||||
|
public int totalNQueens(int n) {
|
||||||
|
char[][] board = new char[n][n];
|
||||||
|
for (char[] chars : board) {
|
||||||
|
Arrays.fill(chars, '.');
|
||||||
|
}
|
||||||
|
backTrack(n, 0, board);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
private void backTrack(int n, int row, char[][] board) {
|
||||||
|
if (row == n) {
|
||||||
|
count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int col = 0; col < n; col++) {
|
||||||
|
if (isValid(row, col, n, board)) {
|
||||||
|
board[row][col] = 'Q';
|
||||||
|
backTrack(n, row + 1, board);
|
||||||
|
board[row][col] = '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private boolean isValid(int row, int col, int n, char[][] board) {
|
||||||
|
// 检查列
|
||||||
|
for (int i = 0; i < row; ++i) {
|
||||||
|
if (board[i][col] == 'Q') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 检查45度对角线
|
||||||
|
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
|
||||||
|
if (board[i][j] == 'Q') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 检查135度对角线
|
||||||
|
for (int i = row - 1, j = col + 1; i >= 0 && j <= n - 1; i--, j++) {
|
||||||
|
if (board[i][j] == 'Q') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
<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"/>
|
||||||
|
@ -409,7 +409,44 @@ class Solution:
|
|||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
*****
|
|
||||||
|
Go:
|
||||||
|
|
||||||
|
> 单调栈
|
||||||
|
|
||||||
|
```go
|
||||||
|
func largestRectangleArea(heights []int) int {
|
||||||
|
// 声明max并初始化为0
|
||||||
|
max := 0
|
||||||
|
// 使用切片实现栈
|
||||||
|
stack := make([]int, 0)
|
||||||
|
// 数组头部加入0
|
||||||
|
heights = append([]int{0}, heights...)
|
||||||
|
// 数组尾部加入0
|
||||||
|
heights = append(heights, 0)
|
||||||
|
// 初始化栈,序号从0开始
|
||||||
|
stack = append(stack, 0)
|
||||||
|
for i := 1; i < len(heights); i++ {
|
||||||
|
// 结束循环条件为:当即将入栈元素>top元素,也就是形成非单调递增的趋势
|
||||||
|
for heights[stack[len(stack)-1]] > heights[i] {
|
||||||
|
// mid 是top
|
||||||
|
mid := stack[len(stack)-1]
|
||||||
|
// 出栈
|
||||||
|
stack = stack[0 : len(stack)-1]
|
||||||
|
// left是top的下一位元素,i是将要入栈的元素
|
||||||
|
left := stack[len(stack)-1]
|
||||||
|
// 高度x宽度
|
||||||
|
tmp := heights[mid] * (i - left - 1)
|
||||||
|
if tmp > max {
|
||||||
|
max = tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stack = append(stack, i)
|
||||||
|
}
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
JavaScript:
|
JavaScript:
|
||||||
```javascript
|
```javascript
|
||||||
|
@ -262,6 +262,8 @@ class Solution:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Python3
|
### Python3
|
||||||
|
|
||||||
|
不使用used数组
|
||||||
```python3
|
```python3
|
||||||
class Solution:
|
class Solution:
|
||||||
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
|
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
|
||||||
@ -288,6 +290,28 @@ class Solution:
|
|||||||
return res
|
return res
|
||||||
```
|
```
|
||||||
|
|
||||||
|
使用used数组
|
||||||
|
```python3
|
||||||
|
class Solution:
|
||||||
|
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
|
||||||
|
result = []
|
||||||
|
path = []
|
||||||
|
nums.sort()
|
||||||
|
used = [0] * len(nums)
|
||||||
|
def backtrack(nums, startIdx):
|
||||||
|
result.append(path[:])
|
||||||
|
for i in range(startIdx, len(nums)):
|
||||||
|
if i > startIdx and nums[i] == nums[i-1] and used[i-1] == 0:
|
||||||
|
continue
|
||||||
|
used[i] = 1
|
||||||
|
path.append(nums[i])
|
||||||
|
backtrack(nums, i+1)
|
||||||
|
path.pop()
|
||||||
|
used[i] = 0
|
||||||
|
backtrack(nums, 0)
|
||||||
|
return result
|
||||||
|
```
|
||||||
|
|
||||||
### Go
|
### Go
|
||||||
|
|
||||||
```Go
|
```Go
|
||||||
@ -526,7 +550,7 @@ func subsetsWithDup(_ nums: [Int]) -> [[Int]] {
|
|||||||
|
|
||||||
### Scala
|
### Scala
|
||||||
|
|
||||||
不使用userd数组:
|
不使用used数组:
|
||||||
|
|
||||||
```scala
|
```scala
|
||||||
object Solution {
|
object Solution {
|
||||||
|
@ -464,6 +464,47 @@ function maxProfit(prices: number[]): number {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
C#:
|
||||||
|
|
||||||
|
> 贪心法
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class Solution
|
||||||
|
{
|
||||||
|
public int MaxProfit(int[] prices)
|
||||||
|
{
|
||||||
|
int min = Int32.MaxValue;
|
||||||
|
int res = 0;
|
||||||
|
for (int i = 0; i < prices.Length; i++)
|
||||||
|
{
|
||||||
|
min = Math.Min(prices[i], min);
|
||||||
|
res = Math.Max(prices[i] - min, res);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 动态规划
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class Solution
|
||||||
|
{
|
||||||
|
public int MaxProfit(int[] prices)
|
||||||
|
{
|
||||||
|
int[] dp = new int[2];
|
||||||
|
int size = prices.Length;
|
||||||
|
(dp[0], dp[1]) = (-prices[0], 0);
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
dp[0] = Math.Max(dp[0], -prices[i]);
|
||||||
|
dp[1] = Math.Max(dp[1], dp[0]+prices[i]);
|
||||||
|
}
|
||||||
|
return dp[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -471,3 +512,4 @@ function maxProfit(prices: number[]): number {
|
|||||||
<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"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -169,8 +169,6 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
> 版本一:
|
> 版本一:
|
||||||
@ -253,8 +251,6 @@ func max(a,b int)int{
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Javascript:
|
Javascript:
|
||||||
```javascript
|
```javascript
|
||||||
// 方法一:动态规划(dp 数组)
|
// 方法一:动态规划(dp 数组)
|
||||||
@ -331,9 +327,47 @@ function maxProfit(prices: number[]): number {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
C#:
|
||||||
|
|
||||||
|
> 贪心法
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class Solution
|
||||||
|
{
|
||||||
|
public int MaxProfit(int[] prices)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
for (int i = 1; i < prices.Length; i++)
|
||||||
|
res += Math.Max(0, prices[i] - prices[i-1]);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 动态规划
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class Solution
|
||||||
|
{
|
||||||
|
public int MaxProfit(int[] prices)
|
||||||
|
{
|
||||||
|
int[] dp = new int[2];
|
||||||
|
dp[0] = -prices[0];
|
||||||
|
|
||||||
|
for (int i = 1; i < prices.Length; i++)
|
||||||
|
{
|
||||||
|
dp[0] = dp[0]>dp[1] - prices[i]?dp[0]:dp[1] - prices[i];
|
||||||
|
dp[1] = dp[1] > dp[0] + prices[i] ? dp[1] : dp[0] + prices[i];
|
||||||
|
}
|
||||||
|
return dp[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<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"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
# 思路
|
# 思路
|
||||||
|
|
||||||
以示例1为例,从这个图中可以看出 hit 到 cog的路线,不止一条,有三条,两条是最短的长度为5,一条长度为6。
|
以示例1为例,从这个图中可以看出 hit 到 cog的路线,不止一条,有三条,一条是最短的长度为5,两条长度为6。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
@ -416,24 +416,31 @@ func backTree(n,k,startIndex int,track *[]int,result *[][]int){
|
|||||||
* @return {number[][]}
|
* @return {number[][]}
|
||||||
*/
|
*/
|
||||||
var combinationSum3 = function(k, n) {
|
var combinationSum3 = function(k, n) {
|
||||||
const backtrack = (start) => {
|
let res = [];
|
||||||
const l = path.length;
|
let path = [];
|
||||||
if (l === k) {
|
let sum = 0;
|
||||||
const sum = path.reduce((a, b) => a + b);
|
const dfs = (path,index) => {
|
||||||
if (sum === n) {
|
// 剪枝操作
|
||||||
|
if (sum > n){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (path.length == k) {
|
||||||
|
if(sum == n){
|
||||||
res.push([...path]);
|
res.push([...path]);
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
for (let i = start; i <= 9 - (k - l) + 1; i++) {
|
for (let i = index; i <= 9 - (k-path.length) + 1;i++) {
|
||||||
path.push(i);
|
path.push(i);
|
||||||
backtrack(i + 1);
|
sum = sum + i;
|
||||||
path.pop();
|
index += 1;
|
||||||
|
dfs(path,index);
|
||||||
|
sum -= i
|
||||||
|
path.pop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let res = [], path = [];
|
dfs(path,1);
|
||||||
backtrack(1);
|
return res
|
||||||
return res;
|
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -328,13 +328,11 @@ var lowestCommonAncestor = function(root, p, q) {
|
|||||||
}
|
}
|
||||||
if(root.val>p.val&&root.val>q.val) {
|
if(root.val>p.val&&root.val>q.val) {
|
||||||
// 向左子树查询
|
// 向左子树查询
|
||||||
let left = lowestCommonAncestor(root.left,p,q);
|
return root.left = lowestCommonAncestor(root.left,p,q);
|
||||||
return left !== null&&left;
|
|
||||||
}
|
}
|
||||||
if(root.val<p.val&&root.val<q.val) {
|
if(root.val<p.val&&root.val<q.val) {
|
||||||
// 向右子树查询
|
// 向右子树查询
|
||||||
let right = lowestCommonAncestor(root.right,p,q);
|
return root.right = lowestCommonAncestor(root.right,p,q);
|
||||||
return right !== null&&right;
|
|
||||||
}
|
}
|
||||||
return root;
|
return root;
|
||||||
};
|
};
|
||||||
|
@ -88,7 +88,7 @@ public:
|
|||||||
|
|
||||||
对于窗口里的元素{2, 3, 5, 1 ,4},单调队列里只维护{5, 4} 就够了,保持单调队列里单调递减,此时队列出口元素就是窗口里最大元素。
|
对于窗口里的元素{2, 3, 5, 1 ,4},单调队列里只维护{5, 4} 就够了,保持单调队列里单调递减,此时队列出口元素就是窗口里最大元素。
|
||||||
|
|
||||||
此时大家应该怀疑单调队列里维护着{5, 4} 怎么配合窗口经行滑动呢?
|
此时大家应该怀疑单调队列里维护着{5, 4} 怎么配合窗口进行滑动呢?
|
||||||
|
|
||||||
设计单调队列的时候,pop,和push操作要保持如下规则:
|
设计单调队列的时候,pop,和push操作要保持如下规则:
|
||||||
|
|
||||||
@ -297,15 +297,18 @@ class Solution {
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
```python
|
```python
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
|
|
||||||
class MyQueue: #单调队列(从大到小
|
class MyQueue: #单调队列(从大到小
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.queue = [] #使用list来实现单调队列
|
self.queue = deque() #这里需要使用deque实现单调队列,直接使用list会超时
|
||||||
|
|
||||||
#每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。
|
#每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。
|
||||||
#同时pop之前判断队列当前是否为空。
|
#同时pop之前判断队列当前是否为空。
|
||||||
def pop(self, value):
|
def pop(self, value):
|
||||||
if self.queue and value == self.queue[0]:
|
if self.queue and value == self.queue[0]:
|
||||||
self.queue.pop(0)#list.pop()时间复杂度为O(n),这里可以使用collections.deque()
|
self.queue.popleft()#list.pop()时间复杂度为O(n),这里需要使用collections.deque()
|
||||||
|
|
||||||
#如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。
|
#如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。
|
||||||
#这样就保持了队列里的数值是单调从大到小的了。
|
#这样就保持了队列里的数值是单调从大到小的了。
|
||||||
|
@ -355,16 +355,18 @@ class Solution:
|
|||||||
tickets_dict = defaultdict(list)
|
tickets_dict = defaultdict(list)
|
||||||
for item in tickets:
|
for item in tickets:
|
||||||
tickets_dict[item[0]].append(item[1])
|
tickets_dict[item[0]].append(item[1])
|
||||||
|
# 给每一个机场的到达机场排序,小的在前面,在回溯里首先被pop(0)出去
|
||||||
|
# 这样最先找的的path就是排序最小的答案,直接返回
|
||||||
|
for airport in tickets_dict: tickets_dict[airport].sort()
|
||||||
'''
|
'''
|
||||||
tickets_dict里面的内容是这样的
|
tickets_dict里面的内容是这样的
|
||||||
{'JFK': ['SFO', 'ATL'], 'SFO': ['ATL'], 'ATL': ['JFK', 'SFO']})
|
{'JFK': ['ATL', 'SFO'], 'SFO': ['ATL'], 'ATL': ['JFK', 'SFO']})
|
||||||
'''
|
'''
|
||||||
path = ["JFK"]
|
path = ["JFK"]
|
||||||
def backtracking(start_point):
|
def backtracking(start_point):
|
||||||
# 终止条件
|
# 终止条件
|
||||||
if len(path) == len(tickets) + 1:
|
if len(path) == len(tickets) + 1:
|
||||||
return True
|
return True
|
||||||
tickets_dict[start_point].sort()
|
|
||||||
for _ in tickets_dict[start_point]:
|
for _ in tickets_dict[start_point]:
|
||||||
#必须及时删除,避免出现死循环
|
#必须及时删除,避免出现死循环
|
||||||
end_point = tickets_dict[start_point].pop(0)
|
end_point = tickets_dict[start_point].pop(0)
|
||||||
|
@ -91,7 +91,7 @@ public:
|
|||||||
|
|
||||||
对应C++代码如下:
|
对应C++代码如下:
|
||||||
|
|
||||||
```c++
|
```CPP
|
||||||
class Solution {
|
class Solution {
|
||||||
public:
|
public:
|
||||||
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
|
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
|
||||||
@ -310,6 +310,22 @@ impl Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
解法2:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use std::collections::HashSet;
|
||||||
|
impl Solution {
|
||||||
|
pub fn intersection(nums1: Vec<i32>, nums2: Vec<i32>) -> Vec<i32> {
|
||||||
|
nums1
|
||||||
|
.into_iter()
|
||||||
|
.collect::<HashSet<_>>()
|
||||||
|
.intersection(&nums2.into_iter().collect::<HashSet<_>>())
|
||||||
|
.copied()
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
C:
|
C:
|
||||||
```C
|
```C
|
||||||
int* intersection1(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
|
int* intersection1(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
|
||||||
|
@ -344,6 +344,48 @@ class Solution:
|
|||||||
return root
|
return root
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**迭代法**
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
|
||||||
|
# 找到节点后分两步,1. 把节点的左子树和右子树连起来,2. 把右子树跟父节点连起来
|
||||||
|
# root is None
|
||||||
|
if not root: return root
|
||||||
|
p = root
|
||||||
|
last = None
|
||||||
|
while p:
|
||||||
|
if p.val==key:
|
||||||
|
# 1. connect left to right
|
||||||
|
# right is not None -> left is None | left is not None
|
||||||
|
if p.right:
|
||||||
|
if p.left:
|
||||||
|
node = p.right
|
||||||
|
while node.left:
|
||||||
|
node = node.left
|
||||||
|
node.left = p.left
|
||||||
|
right = p.right
|
||||||
|
else:
|
||||||
|
# right is None -> right=left
|
||||||
|
right = p.left
|
||||||
|
# 2. connect right to last
|
||||||
|
if last==None:
|
||||||
|
root = right
|
||||||
|
elif last.val>key:
|
||||||
|
last.left = right
|
||||||
|
else:
|
||||||
|
last.right = right
|
||||||
|
# 3. return
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# Update last and continue
|
||||||
|
last = p
|
||||||
|
if p.val>key:
|
||||||
|
p = p.left
|
||||||
|
else:
|
||||||
|
p = p.right
|
||||||
|
return root
|
||||||
|
```
|
||||||
|
|
||||||
## Go
|
## Go
|
||||||
```Go
|
```Go
|
||||||
// 递归版本
|
// 递归版本
|
||||||
|
@ -615,6 +615,37 @@ impl Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
>前缀表统一减一
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl Solution {
|
||||||
|
pub fn get_next(next_len: usize, s: &Vec<char>) -> Vec<i32> {
|
||||||
|
let mut next = vec![-1; next_len];
|
||||||
|
let mut j = -1;
|
||||||
|
for i in 1..s.len() {
|
||||||
|
while j >= 0 && s[i] != s[(j + 1) as usize] {
|
||||||
|
j = next[j as usize];
|
||||||
|
}
|
||||||
|
if s[i] == s[(j + 1) as usize] {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
next[i] = j;
|
||||||
|
}
|
||||||
|
next
|
||||||
|
}
|
||||||
|
pub fn repeated_substring_pattern(s: String) -> bool {
|
||||||
|
let s_chars = s.chars().collect::<Vec<char>>();
|
||||||
|
let next = Self::get_next(s_chars.len(), &s_chars);
|
||||||
|
if next[s_chars.len() - 1] >= 0
|
||||||
|
&& s_chars.len() % (s_chars.len() - (next[s_chars.len() - 1] + 1) as usize) == 0
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
<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">
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
## 518. 零钱兑换 II
|
## 518. 零钱兑换 II
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode.cn/problems/coin-change-2/)
|
[力扣题目链接](https://leetcode.cn/problems/coin-change-ii/)
|
||||||
|
|
||||||
难度:中等
|
难度:中等
|
||||||
|
|
||||||
|
@ -399,19 +399,42 @@ object Solution {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
版本二: 首先利用sliding每隔k个进行分割,随后转换为数组,再使用zipWithIndex添加每个数组的索引,紧接着利用map做变换,如果索引%2==0则说明需要翻转,否则原封不动,最后再转换为String
|
版本二: 首先利用grouped每隔k个进行分割,再使用zipWithIndex添加每个数组的索引,紧接着利用map做变换,如果索引%2==0则说明需要翻转,否则原封不动,最后再转换为String
|
||||||
```scala
|
```scala
|
||||||
object Solution {
|
object Solution {
|
||||||
def reverseStr(s: String, k: Int): String = {
|
def reverseStr(s: String, k: Int): String = {
|
||||||
s.sliding(k, k)
|
// s = "abcdefg", k = 2
|
||||||
.toArray
|
s.grouped(k) // Iterator ["ab", "cd", "ef", "g"]
|
||||||
.zipWithIndex
|
.zipWithIndex // Iterator [("ab", 0), ("cd", 1), ("ef", 2), ("g", 3)]
|
||||||
.map(v => if (v._2 % 2 == 0) v._1.reverse else v._1)
|
.map {
|
||||||
|
case (subStr, index) =>
|
||||||
|
if (index % 2 == 0) subStr.reverse else subStr
|
||||||
|
}
|
||||||
.mkString
|
.mkString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
版本三: (递归)
|
||||||
|
```scala
|
||||||
|
import scala.annotation.tailrec
|
||||||
|
|
||||||
|
object Solution {
|
||||||
|
def reverseStr(s: String, k: Int): String = {
|
||||||
|
@tailrec // 这个函数已经优化成了尾递归
|
||||||
|
def reverse(s: String, needToReverse: Boolean, history: String): String = {
|
||||||
|
// 截取前k个字符(判断是否翻转)
|
||||||
|
val subStr = if (needToReverse) s.take(k).reverse else s.take(k)
|
||||||
|
// 如果字符串长度小于k,返回结果
|
||||||
|
// 否则,对于剩余字符串进行同样的操作
|
||||||
|
if (s.length < k) history + subStr
|
||||||
|
else reverse(s.drop(k), !needToReverse, history + subStr)
|
||||||
|
}
|
||||||
|
reverse(s, true, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Rust:
|
Rust:
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
|
@ -330,6 +330,26 @@ class Solution:
|
|||||||
return root
|
return root
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**递归法** - 无返回值 有注释 不用Helper function
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
|
||||||
|
if not root: # for root==None
|
||||||
|
return TreeNode(val)
|
||||||
|
if root.val<val:
|
||||||
|
if root.right==None: # find the parent
|
||||||
|
root.right = TreeNode(val)
|
||||||
|
else: # not found, keep searching
|
||||||
|
self.insertIntoBST(root.right, val)
|
||||||
|
if root.val>val:
|
||||||
|
if root.left==None: # found the parent
|
||||||
|
root.left = TreeNode(val)
|
||||||
|
else: # not found, keep searching
|
||||||
|
self.insertIntoBST(root.left, val)
|
||||||
|
# return the final tree
|
||||||
|
return root
|
||||||
|
```
|
||||||
|
|
||||||
**迭代法**
|
**迭代法**
|
||||||
与无返回值的递归函数的思路大体一致
|
与无返回值的递归函数的思路大体一致
|
||||||
```python
|
```python
|
||||||
@ -337,16 +357,15 @@ class Solution:
|
|||||||
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
|
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
|
||||||
if not root:
|
if not root:
|
||||||
return TreeNode(val)
|
return TreeNode(val)
|
||||||
parent = None
|
parent = None # 此步可以省略
|
||||||
cur = root
|
cur = root
|
||||||
|
|
||||||
# 用while循环不断地找新节点的parent
|
# 用while循环不断地找新节点的parent
|
||||||
while cur:
|
while cur:
|
||||||
|
parent = cur # 首先保存当前非空节点作为下一次迭代的父节点
|
||||||
if cur.val < val:
|
if cur.val < val:
|
||||||
parent = cur
|
|
||||||
cur = cur.right
|
cur = cur.right
|
||||||
elif cur.val > val:
|
elif cur.val > val:
|
||||||
parent = cur
|
|
||||||
cur = cur.left
|
cur = cur.left
|
||||||
|
|
||||||
# 运行到这意味着已经跳出上面的while循环,
|
# 运行到这意味着已经跳出上面的while循环,
|
||||||
|
@ -451,6 +451,42 @@ object Solution {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Rust:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl Solution {
|
||||||
|
pub fn common_chars(words: Vec<String>) -> Vec<String> {
|
||||||
|
if words.is_empty() {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
let mut res = vec![];
|
||||||
|
let mut hash = vec![0; 26];
|
||||||
|
for i in words[0].bytes() {
|
||||||
|
hash[(i - b'a') as usize] += 1;
|
||||||
|
}
|
||||||
|
for i in words.iter().skip(1) {
|
||||||
|
let mut other_hash_str = vec![0; 26];
|
||||||
|
for j in i.bytes() {
|
||||||
|
other_hash_str[(j - b'a') as usize] += 1;
|
||||||
|
}
|
||||||
|
for k in 0..26 {
|
||||||
|
hash[k] = hash[k].min(other_hash_str[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, v) in hash.iter_mut().enumerate() {
|
||||||
|
while *v > 0 {
|
||||||
|
res.push(((i as u8 + b'a') as char).to_string());
|
||||||
|
*v -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
<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"/>
|
||||||
|
@ -117,7 +117,7 @@ class Solution:
|
|||||||
diff -= 1
|
diff -= 1
|
||||||
else:
|
else:
|
||||||
diff += 1
|
diff += 1
|
||||||
if tilt == 0:
|
if diff == 0:
|
||||||
ans += 1
|
ans += 1
|
||||||
return ans
|
return ans
|
||||||
```
|
```
|
||||||
|
@ -59,7 +59,7 @@ C++标准库是有多个版本的,要知道我们使用的STL是哪个版本
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
**我们常用的SGI STL,如果没有指定底层实现的话,默认是以deque为缺省情况下栈的低层结构。**
|
**我们常用的SGI STL,如果没有指定底层实现的话,默认是以deque为缺省情况下栈的底层结构。**
|
||||||
|
|
||||||
deque是一个双向队列,只要封住一段,只开通另一端就可以实现栈的逻辑了。
|
deque是一个双向队列,只要封住一段,只开通另一端就可以实现栈的逻辑了。
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user