mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-09 03:34:02 +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)的贡献的代码,当然我也会严格把控代码质量。
|
||||
|
||||
**所以也欢迎大家参与进来,完善题解的各个语言版本,拥抱开源,让更多小伙伴们收益**。
|
||||
**所以也欢迎大家参与进来,完善题解的各个语言版本,拥抱开源,让更多小伙伴们受益**。
|
||||
|
||||
准备好了么,刷题攻略开始咯,go go go!
|
||||
|
||||
|
@ -152,25 +152,11 @@ class Solution:
|
||||
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
||||
records = dict()
|
||||
|
||||
# 用枚举更方便,就不需要通过索引再去取当前位置的值
|
||||
for idx, val in enumerate(nums):
|
||||
if target - val not in records:
|
||||
records[val] = idx
|
||||
else:
|
||||
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
|
||||
for index, value in enumerate(nums):
|
||||
if target - value in records:
|
||||
return [records[target- value], index]
|
||||
records[value] = index
|
||||
return []
|
||||
```
|
||||
|
||||
Go:
|
||||
|
@ -655,7 +655,7 @@ impl Solution {
|
||||
|
||||
```Rust
|
||||
// 双指针法
|
||||
use std::collections::HashSet;
|
||||
use std::cmp::Ordering;
|
||||
impl Solution {
|
||||
pub fn three_sum(nums: Vec<i32>) -> Vec<Vec<i32>> {
|
||||
let mut result: Vec<Vec<i32>> = Vec::new();
|
||||
@ -667,22 +667,21 @@ impl Solution {
|
||||
if i > 0 && nums[i] == nums[i - 1] { continue; }
|
||||
let (mut left, mut right) = (i + 1, len - 1);
|
||||
while left < right {
|
||||
if nums[i] + nums[left] + nums[right] > 0 {
|
||||
right -= 1;
|
||||
// 去重
|
||||
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]]);
|
||||
// 去重
|
||||
right -= 1;
|
||||
left += 1;
|
||||
while left < right && nums[right] == nums[right + 1] { right -= 1; }
|
||||
while left < right && nums[left] == nums[left - 1] { left += 1; }
|
||||
}
|
||||
match (nums[i] + nums[left] + nums[right]).cmp(&0){
|
||||
Ordering::Equal =>{
|
||||
result.push(vec![nums[i], nums[left], nums[right]]);
|
||||
left +=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,
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
|
@ -527,6 +527,7 @@ public class Solution
|
||||
|
||||
Rust:
|
||||
```Rust
|
||||
use std::cmp::Ordering;
|
||||
impl Solution {
|
||||
pub fn four_sum(nums: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
|
||||
let mut result: Vec<Vec<i32>> = Vec::new();
|
||||
@ -545,22 +546,25 @@ impl Solution {
|
||||
if i > k + 1 && nums[i] == nums[i - 1] { continue; }
|
||||
let (mut left, mut right) = (i + 1, len - 1);
|
||||
while left < right {
|
||||
if nums[k] + nums[i] > target - (nums[left] + nums[right]) {
|
||||
right -= 1;
|
||||
// 去重
|
||||
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]]);
|
||||
// 去重
|
||||
while left < right && nums[right] == nums[right - 1] { right -= 1; }
|
||||
while left < right && nums[left] == nums[left + 1] { left += 1; }
|
||||
left += 1;
|
||||
right -= 1;
|
||||
}
|
||||
match (nums[k] + nums[i] + nums[left] + nums[right]).cmp(&target){
|
||||
Ordering::Equal => {
|
||||
result.push(vec![nums[k], nums[i], nums[left], nums[right]]);
|
||||
left += 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
|
||||
}
|
||||
}
|
||||
```
|
||||
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">
|
||||
|
@ -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">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -256,7 +256,54 @@ int totalNQueens(int n){
|
||||
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">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<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
|
||||
|
@ -262,6 +262,8 @@ class Solution:
|
||||
```
|
||||
|
||||
### Python3
|
||||
|
||||
不使用used数组
|
||||
```python3
|
||||
class Solution:
|
||||
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
|
||||
@ -288,6 +290,28 @@ class Solution:
|
||||
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
|
||||
@ -526,7 +550,7 @@ func subsetsWithDup(_ nums: [Int]) -> [[Int]] {
|
||||
|
||||
### Scala
|
||||
|
||||
不使用userd数组:
|
||||
不使用used数组:
|
||||
|
||||
```scala
|
||||
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">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -169,8 +169,6 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
> 版本一:
|
||||
@ -253,8 +251,6 @@ func max(a,b int)int{
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
Javascript:
|
||||
```javascript
|
||||
// 方法一:动态规划(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">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</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[][]}
|
||||
*/
|
||||
var combinationSum3 = function(k, n) {
|
||||
const backtrack = (start) => {
|
||||
const l = path.length;
|
||||
if (l === k) {
|
||||
const sum = path.reduce((a, b) => a + b);
|
||||
if (sum === n) {
|
||||
res.push([...path]);
|
||||
}
|
||||
return;
|
||||
let res = [];
|
||||
let path = [];
|
||||
let sum = 0;
|
||||
const dfs = (path,index) => {
|
||||
// 剪枝操作
|
||||
if (sum > n){
|
||||
return
|
||||
}
|
||||
for (let i = start; i <= 9 - (k - l) + 1; i++) {
|
||||
if (path.length == k) {
|
||||
if(sum == n){
|
||||
res.push([...path]);
|
||||
return
|
||||
}
|
||||
}
|
||||
for (let i = index; i <= 9 - (k-path.length) + 1;i++) {
|
||||
path.push(i);
|
||||
backtrack(i + 1);
|
||||
path.pop();
|
||||
sum = sum + i;
|
||||
index += 1;
|
||||
dfs(path,index);
|
||||
sum -= i
|
||||
path.pop()
|
||||
}
|
||||
}
|
||||
let res = [], path = [];
|
||||
backtrack(1);
|
||||
return res;
|
||||
dfs(path,1);
|
||||
return res
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -328,13 +328,11 @@ var lowestCommonAncestor = function(root, p, q) {
|
||||
}
|
||||
if(root.val>p.val&&root.val>q.val) {
|
||||
// 向左子树查询
|
||||
let left = lowestCommonAncestor(root.left,p,q);
|
||||
return left !== null&&left;
|
||||
return root.left = lowestCommonAncestor(root.left,p,q);
|
||||
}
|
||||
if(root.val<p.val&&root.val<q.val) {
|
||||
// 向右子树查询
|
||||
let right = lowestCommonAncestor(root.right,p,q);
|
||||
return right !== null&&right;
|
||||
return root.right = lowestCommonAncestor(root.right,p,q);
|
||||
}
|
||||
return root;
|
||||
};
|
||||
|
@ -88,7 +88,7 @@ public:
|
||||
|
||||
对于窗口里的元素{2, 3, 5, 1 ,4},单调队列里只维护{5, 4} 就够了,保持单调队列里单调递减,此时队列出口元素就是窗口里最大元素。
|
||||
|
||||
此时大家应该怀疑单调队列里维护着{5, 4} 怎么配合窗口经行滑动呢?
|
||||
此时大家应该怀疑单调队列里维护着{5, 4} 怎么配合窗口进行滑动呢?
|
||||
|
||||
设计单调队列的时候,pop,和push操作要保持如下规则:
|
||||
|
||||
@ -297,15 +297,18 @@ class Solution {
|
||||
|
||||
Python:
|
||||
```python
|
||||
from collections import deque
|
||||
|
||||
|
||||
class MyQueue: #单调队列(从大到小
|
||||
def __init__(self):
|
||||
self.queue = [] #使用list来实现单调队列
|
||||
self.queue = deque() #这里需要使用deque实现单调队列,直接使用list会超时
|
||||
|
||||
#每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。
|
||||
#同时pop之前判断队列当前是否为空。
|
||||
def pop(self, value):
|
||||
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的数值小于等于队列入口元素的数值为止。
|
||||
#这样就保持了队列里的数值是单调从大到小的了。
|
||||
|
@ -355,16 +355,18 @@ class Solution:
|
||||
tickets_dict = defaultdict(list)
|
||||
for item in tickets:
|
||||
tickets_dict[item[0]].append(item[1])
|
||||
# 给每一个机场的到达机场排序,小的在前面,在回溯里首先被pop(0)出去
|
||||
# 这样最先找的的path就是排序最小的答案,直接返回
|
||||
for airport in tickets_dict: tickets_dict[airport].sort()
|
||||
'''
|
||||
tickets_dict里面的内容是这样的
|
||||
{'JFK': ['SFO', 'ATL'], 'SFO': ['ATL'], 'ATL': ['JFK', 'SFO']})
|
||||
{'JFK': ['ATL', 'SFO'], 'SFO': ['ATL'], 'ATL': ['JFK', 'SFO']})
|
||||
'''
|
||||
path = ["JFK"]
|
||||
def backtracking(start_point):
|
||||
# 终止条件
|
||||
if len(path) == len(tickets) + 1:
|
||||
return True
|
||||
tickets_dict[start_point].sort()
|
||||
for _ in tickets_dict[start_point]:
|
||||
#必须及时删除,避免出现死循环
|
||||
end_point = tickets_dict[start_point].pop(0)
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
|
||||
对应C++代码如下:
|
||||
|
||||
```c++
|
||||
```CPP
|
||||
class Solution {
|
||||
public:
|
||||
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
|
||||
int* intersection1(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
|
||||
|
@ -344,6 +344,48 @@ class Solution:
|
||||
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
|
||||
// 递归版本
|
||||
|
@ -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">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
## 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
|
||||
object Solution {
|
||||
def reverseStr(s: String, k: Int): String = {
|
||||
s.sliding(k, k)
|
||||
.toArray
|
||||
.zipWithIndex
|
||||
.map(v => if (v._2 % 2 == 0) v._1.reverse else v._1)
|
||||
// s = "abcdefg", k = 2
|
||||
s.grouped(k) // Iterator ["ab", "cd", "ef", "g"]
|
||||
.zipWithIndex // Iterator [("ab", 0), ("cd", 1), ("ef", 2), ("g", 3)]
|
||||
.map {
|
||||
case (subStr, index) =>
|
||||
if (index % 2 == 0) subStr.reverse else subStr
|
||||
}
|
||||
.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
|
||||
|
@ -330,6 +330,26 @@ class Solution:
|
||||
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
|
||||
@ -337,16 +357,15 @@ class Solution:
|
||||
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
|
||||
if not root:
|
||||
return TreeNode(val)
|
||||
parent = None
|
||||
parent = None # 此步可以省略
|
||||
cur = root
|
||||
|
||||
# 用while循环不断地找新节点的parent
|
||||
while cur:
|
||||
parent = cur # 首先保存当前非空节点作为下一次迭代的父节点
|
||||
if cur.val < val:
|
||||
parent = cur
|
||||
cur = cur.right
|
||||
elif cur.val > val:
|
||||
parent = cur
|
||||
cur = cur.left
|
||||
|
||||
# 运行到这意味着已经跳出上面的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">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -117,7 +117,7 @@ class Solution:
|
||||
diff -= 1
|
||||
else:
|
||||
diff += 1
|
||||
if tilt == 0:
|
||||
if diff == 0:
|
||||
ans += 1
|
||||
return ans
|
||||
```
|
||||
|
@ -59,7 +59,7 @@ C++标准库是有多个版本的,要知道我们使用的STL是哪个版本
|
||||

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