Merge branch 'master' of github.com:youngyangyang04/leetcode-master

This commit is contained in:
programmercarl
2022-08-14 20:26:11 +08:00
18 changed files with 531 additions and 25 deletions

View File

@ -195,7 +195,7 @@ class Solution:
break
self.reverse(nums, i, length-1)
break
else:
if n == 1:
# 若正常结束循环,则对原数组直接翻转
self.reverse(nums, 0, length-1)

View File

@ -488,6 +488,52 @@ function solveSudoku(board: string[][]): void {
};
```
### Rust
```Rust
impl Solution {
fn is_valid(row: usize, col: usize, val: char, board: &mut Vec<Vec<char>>) -> bool{
for i in 0..9 {
if board[row][i] == val { return false; }
}
for j in 0..9 {
if board[j][col] == val {
return false;
}
}
let start_row = (row / 3) * 3;
let start_col = (col / 3) * 3;
for i in start_row..(start_row + 3) {
for j in start_col..(start_col + 3) {
if board[i][j] == val { return false; }
}
}
return true;
}
fn backtracking(board: &mut Vec<Vec<char>>) -> bool{
for i in 0..board.len() {
for j in 0..board[0].len() {
if board[i][j] != '.' { continue; }
for k in '1'..='9' {
if Self::is_valid(i, j, k, board) {
board[i][j] = k;
if Self::backtracking(board) { return true; }
board[i][j] = '.';
}
}
return false;
}
}
return true;
}
pub fn solve_sudoku(board: &mut Vec<Vec<char>>) {
Self::backtracking(board);
}
}
```
### C
```C

View File

@ -305,6 +305,56 @@ object Solution {
}
```
### Rust
```Rust
//版本一
impl Solution {
fn max(a: i32, b:i32) -> i32 {
if a > b { a } else { b }
}
pub fn jump(nums: Vec<i32>) -> i32 {
if nums.len() == 0 { return 0; }
let mut cur_distance: i32 = 0;
let mut ans: i32 = 0;
let mut next_distance: i32 = 0;
for i in 0..nums.len() {
next_distance = Self::max(nums[i] + i as i32, next_distance);
if i as i32 == cur_distance {
if cur_distance != (nums.len() - 1) as i32 {
ans += 1;
cur_distance = next_distance;
if next_distance == (nums.len() - 1) as i32 { break; }
}
else { break; }
}
}
ans
}
}
```
```Rust
//版本二
impl Solution {
fn max(a: i32, b:i32) -> i32 {
if a > b { a } else { b }
}
pub fn jump(nums: Vec<i32>) -> i32 {
let mut cur_distance: i32 = 0;
let mut ans: i32 = 0;
let mut next_distance: i32 = 0;
for i in 0..nums.len() - 1 {
next_distance = Self::max(nums[i] + i as i32, next_distance);
if i as i32 == cur_distance {
cur_distance = next_distance;
ans += 1;
}
}
ans
}
}
```
-----------------------

View File

@ -351,6 +351,40 @@ func permuteUnique(_ nums: [Int]) -> [[Int]] {
}
```
### Rust
```Rust
impl Solution {
fn backtracking(result: &mut Vec<Vec<i32>>, path: &mut Vec<i32>, nums: &Vec<i32>, used: &mut Vec<bool>) {
let len = nums.len();
if path.len() == len {
result.push(path.clone());
return;
}
for i in 0..len {
if i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false { continue; }
if used[i] == false {
used[i] = true;
path.push(nums[i]);
Self::backtracking(result, path, nums, used);
path.pop();
used[i] = false;
}
}
}
pub fn permute_unique(nums: Vec<i32>) -> Vec<Vec<i32>> {
let mut result: Vec<Vec<i32>> = Vec::new();
let mut path: Vec<i32> = Vec::new();
let mut used = vec![false; nums.len()];
let mut nums= nums;
nums.sort();
Self::backtracking(&mut result, &mut path, &nums, &mut used);
result
}
}
```
### C
```c
//临时数组

View File

@ -558,6 +558,56 @@ func solveNQueens(_ n: Int) -> [[String]] {
}
```
### Rust
```Rust
impl Solution {
fn is_valid(row: usize, col: usize, chessboard: &mut Vec<Vec<char>>, n: usize) -> bool {
let mut i = 0 as usize;
while i < row {
if chessboard[i][col] == 'Q' { return false; }
i += 1;
}
let (mut i, mut j) = (row as i32 - 1, col as i32 - 1);
while i >= 0 && j >= 0 {
if chessboard[i as usize][j as usize] == 'Q' { return false; }
i -= 1;
j -= 1;
}
let (mut i, mut j) = (row as i32 - 1, col as i32 + 1);
while i >= 0 && j < n as i32 {
if chessboard[i as usize][j as usize] == 'Q' { return false; }
i -= 1;
j += 1;
}
return true;
}
fn backtracking(result: &mut Vec<Vec<String>>, n: usize, row: usize, chessboard: &mut Vec<Vec<char>>) {
if row == n {
let mut chessboard_clone: Vec<String> = Vec::new();
for i in chessboard {
chessboard_clone.push(i.iter().collect::<String>());
}
result.push(chessboard_clone);
return;
}
for col in 0..n {
if Self::is_valid(row, col, chessboard, n) {
chessboard[row][col] = 'Q';
Self::backtracking(result, n, row + 1, chessboard);
chessboard[row][col] = '.';
}
}
}
pub fn solve_n_queens(n: i32) -> Vec<Vec<String>> {
let mut result: Vec<Vec<String>> = Vec::new();
let mut chessboard: Vec<Vec<char>> = vec![vec!['.'; n as usize]; n as usize];
Self::backtracking(&mut result, n as usize, 0, &mut chessboard);
result
}
}
```
### C
```c
char ***ans;

View File

@ -154,6 +154,26 @@ var canJump = function(nums) {
};
```
### Rust
```Rust
impl Solution {
fn max(a: usize, b: usize) -> usize {
if a > b { a } else { b }
}
pub fn can_jump(nums: Vec<i32>) -> bool {
let mut cover = 0;
if (nums.len() == 1) { return true; }
let mut i = 0;
while i <= cover {
cover = Self::max(i + nums[i] as usize, cover);
if cover >= nums.len() - 1 { return true; }
i += 1;
}
false
}
}
```
### C
```c

View File

@ -292,6 +292,30 @@ function subsets(nums: number[]): number[][] {
};
```
## Rust
```Rust
impl Solution {
fn backtracking(result: &mut Vec<Vec<i32>>, path: &mut Vec<i32>, nums: &Vec<i32>, start_index: usize) {
result.push(path.clone());
let len = nums.len();
// if start_index >= len { return; }
for i in start_index..len {
path.push(nums[i]);
Self::backtracking(result, path, nums, i + 1);
path.pop();
}
}
pub fn subsets(nums: Vec<i32>) -> Vec<Vec<i32>> {
let mut result: Vec<Vec<i32>> = Vec::new();
let mut path: Vec<i32> = Vec::new();
Self::backtracking(&mut result, &mut path, &nums, 0);
result
}
}
```
## C
```c

View File

@ -367,6 +367,36 @@ function subsetsWithDup(nums: number[]): number[][] {
};
```
### Rust
```Rust
impl Solution {
fn backtracking(result: &mut Vec<Vec<i32>>, path: &mut Vec<i32>, nums: &Vec<i32>, start_index: usize, used: &mut Vec<bool>) {
result.push(path.clone());
let len = nums.len();
// if start_index >= len { return; }
for i in start_index..len {
if i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false { continue; }
path.push(nums[i]);
used[i] = true;
Self::backtracking(result, path, nums, i + 1, used);
used[i] = false;
path.pop();
}
}
pub fn subsets_with_dup(nums: Vec<i32>) -> Vec<Vec<i32>> {
let mut result: Vec<Vec<i32>> = Vec::new();
let mut path: Vec<i32> = Vec::new();
let mut used = vec![false; nums.len()];
let mut nums = nums;
nums.sort();
Self::backtracking(&mut result, &mut path, &nums, 0, &mut used);
result
}
}
```
### C
```c

View File

@ -536,6 +536,53 @@ func isNormalIp(s string,startIndex,end int)bool{
```
## Rust
```Rust
impl Solution {
fn is_valid(s: &Vec<char>, start: usize, end: usize) -> bool {
if start > end { return false; }
if s[start] == '0' && start != end { return false; }
let mut num = 0;
for i in start..=end {
if s[i] > '9' || s[i] < '0' { return false; }
if let Some(digit) = s[i].to_digit(10) { num = num * 10 + digit; }
if num > 255 { return false; }
}
true
}
fn backtracking(result: &mut Vec<String>, s: &mut Vec<char>, start_index: usize, mut point_num: usize) {
let len = s.len();
if point_num == 3 {
if Self::is_valid(s, start_index, len - 1) {
result.push(s.iter().collect::<String>());
}
return;
}
for i in start_index..len {
if Self::is_valid(s, start_index, i) {
point_num += 1;
s.insert(i + 1, '.');
Self::backtracking(result, s, i + 2, point_num);
point_num -= 1;
s.remove(i + 1);
} else { break; }
}
}
pub fn restore_ip_addresses(s: String) -> Vec<String> {
let mut result: Vec<String> = Vec::new();
let len = s.len();
if len < 4 || len > 12 { return result; }
let mut s = s.chars().collect::<Vec<char>>();
Self::backtracking(&mut result, &mut s, 0, 0);
result
}
}
```
## C
```c
//记录结果

View File

@ -205,6 +205,36 @@ class Solution {
go:
```go
/**
102. 二叉树的递归遍历
*/
func levelOrder(root *TreeNode) [][]int {
arr := [][]int{}
depth := 0
var order func(root *TreeNode, depth int)
order = func(root *TreeNode, depth int) {
if root == nil {
return
}
if len(arr) == depth {
arr = append(arr, []int{})
}
arr[depth] = append(arr[depth], root.Val)
order(root.Left, depth+1)
order(root.Right, depth+1)
}
order(root, depth)
return arr
}
```
```go
/**
102. 二叉树的层序遍历

View File

@ -282,6 +282,43 @@ function maxProfit(prices: number[]): number {
};
```
### Rust
贪心:
```Rust
impl Solution {
fn max(a: i32, b: i32) -> i32 {
if a > b { a } else { b }
}
pub fn max_profit(prices: Vec<i32>) -> i32 {
let mut result = 0;
for i in 1..prices.len() {
result += Self::max(prices[i] - prices[i - 1], 0);
}
result
}
}
```
动态规划:
```Rust
impl Solution {
fn max(a: i32, b: i32) -> i32 {
if a > b { a } else { b }
}
pub fn max_profit(prices: Vec<i32>) -> i32 {
let n = prices.len();
let mut dp = vec![vec![0; 2]; n];
dp[0][0] -= prices[0];
for i in 1..n {
dp[i][0] = Self::max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
dp[i][1] = Self::max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
}
Self::max(dp[n - 1][0], dp[n - 1][1])
}
}
```
### C:
贪心:
```c

View File

@ -742,5 +742,33 @@ func (p ticketSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
```
### Rust
** 文中的Hashmap嵌套Hashmap的方法因为Rust的所有权问题暂时无法实现此方法为删除哈希表中元素法 **
```Rust
use std::collections::HashMap;
impl Solution {
fn backtracking(airport: String, targets: &mut HashMap<&String, Vec<&String>>, result: &mut Vec<String>) {
while let Some(next_airport) = targets.get_mut(&airport).unwrap_or(&mut vec![]).pop() {
Self::backtracking(next_airport.clone(), targets, result);
}
result.push(airport.clone());
}
pub fn find_itinerary(tickets: Vec<Vec<String>>) -> Vec<String> {
let mut targets: HashMap<&String, Vec<&String>> = HashMap::new();
let mut result = Vec::new();
for t in 0..tickets.len() {
targets.entry(&tickets[t][0]).or_default().push(&tickets[t][1]);
}
for (_, target) in targets.iter_mut() {
target.sort_by(|a, b| b.cmp(a));
}
Self::backtracking("JFK".to_string(), &mut targets, &mut result);
result.reverse();
result
}
}
```
-----------------------
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>

View File

@ -353,18 +353,30 @@ class Solution:
# self.left = left
# self.right = right
class Solution:
def rob(self, root: TreeNode) -> int:
result = self.rob_tree(root)
return max(result[0], result[1])
def rob(self, root: Optional[TreeNode]) -> int:
# dp数组dp table以及下标的含义
# 1. 下标为 0 记录 **不偷该节点** 所得到的的最大金钱
# 2. 下标为 1 记录 **偷该节点** 所得到的的最大金钱
dp = self.traversal(root)
return max(dp)
def rob_tree(self, node):
if node is None:
return (0, 0) # (偷当前节点金额,不偷当前节点金额)
left = self.rob_tree(node.left)
right = self.rob_tree(node.right)
val1 = node.val + left[1] + right[1] # 偷当前节点,不能偷子节点
val2 = max(left[0], left[1]) + max(right[0], right[1]) # 不偷当前节点,可偷可不偷子节点
return (val1, val2)
# 要用后序遍历, 因为要通过递归函数的返回值来做下一步计算
def traversal(self, node):
# 递归终止条件,就是遇到了空节点,那肯定是不偷的
if not node:
return (0, 0)
left = self.traversal(node.left)
right = self.traversal(node.right)
# 不偷当前节点, 偷子节点
val_0 = max(left[0], left[1]) + max(right[0], right[1])
# 偷当前节点, 不偷子节点
val_1 = node.val + left[0] + right[0]
return (val_0, val_1)
```
### Go

View File

@ -150,6 +150,7 @@ class Solution {
int count = 1;
//重叠气球的最小右边界
int leftmostRightBound = points[0][1];
for (int i = 1; i < points.length; i++) {
//如果下一个气球的左边界大于最小右边界
for(int i = 1; i < points.length; i++){
if (points[i][0] > leftmostRightBound ) {

View File

@ -423,6 +423,57 @@ function findSubsequences(nums: number[]): number[][] {
};
```
### Rust
**回溯+哈希**
```Rust
use std::collections::HashSet;
impl Solution {
fn backtracking(result: &mut Vec<Vec<i32>>, path: &mut Vec<i32>, nums: &Vec<i32>, start_index: usize) {
if path.len() > 1 { result.push(path.clone()); }
let len = nums.len();
let mut uset: HashSet<i32> = HashSet::new();
for i in start_index..len {
if (!path.is_empty() && nums[i] < *path.last().unwrap()) || uset.contains(&nums[i]) { continue; }
uset.insert(nums[i]);
path.push(nums[i]);
Self::backtracking(result, path, nums, i + 1);
path.pop();
}
}
pub fn find_subsequences(nums: Vec<i32>) -> Vec<Vec<i32>> {
let mut result: Vec<Vec<i32>> = Vec::new();
let mut path: Vec<i32> = Vec::new();
Self::backtracking(&mut result, &mut path, &nums, 0);
result
}
}
```
**回溯+数组**
```Rust
impl Solution {
fn backtracking(result: &mut Vec<Vec<i32>>, path: &mut Vec<i32>, nums: &Vec<i32>, start_index: usize) {
if path.len() > 1 { result.push(path.clone()); }
let len = nums.len();
let mut used = [0; 201];
for i in start_index..len {
if (!path.is_empty() && nums[i] < *path.last().unwrap()) || used[(nums[i] + 100) as usize] == 1 { continue; }
used[(nums[i] + 100) as usize] = 1;
path.push(nums[i]);
Self::backtracking(result, path, nums, i + 1);
path.pop();
}
}
pub fn find_subsequences(nums: Vec<i32>) -> Vec<Vec<i32>> {
let mut result: Vec<Vec<i32>> = Vec::new();
let mut path: Vec<i32> = Vec::new();
Self::backtracking(&mut result, &mut path, &nums, 0);
result
}
}
```
### C
```c

View File

@ -227,6 +227,31 @@ var largestSumAfterKNegations = function(nums, k) {
};
```
### Rust
```Rust
impl Solution {
pub fn largest_sum_after_k_negations(nums: Vec<i32>, k: i32) -> i32 {
let mut nums = nums;
let mut k = k;
let len = nums.len();
nums.sort_by(|a, b| b.abs().cmp(&a.abs()));
for i in 0..len {
if nums[i] < 0 && k > 0 {
nums[i] *= -1;
k -= 1;
}
}
if k % 2 == 1 { nums[len - 1] *= -1; }
let mut result = 0;
for num in nums {
result += num;
}
result
}
}
```
### C
```c

View File

@ -57,11 +57,18 @@ TreeNode* construct_binary_tree(const vector<int>& vec) {
if (i == 0) root = node;
}
// 遍历一遍,根据规则左右孩子赋值就可以了
// 注意这里 结束规则是 i * 2 + 2 < vec.size(),避免空指针
for (int i = 0; i * 2 + 2 < vec.size(); i++) {
// 注意这里 结束规则是 i * 2 + 1 < vec.size(),避免空指针
// 为什么结束规则不能是i * 2 + 2 < arr.length呢?
// 如果i * 2 + 2 < arr.length 是结束条件
// 那么i * 2 + 1这个符合条件的节点就被忽略掉了
// 例如[2,7,9,-1,1,9,6,-1,-1,10] 这样的一个二叉树,最后的10就会被忽略掉
// 遍历一遍,根据规则左右孩子赋值就可以了
for (int i = 0; i * 2 + 1 < vec.size(); i++) {
if (vecTree[i] != NULL) {
// 线性存储转连式存储关键逻辑
vecTree[i]->left = vecTree[i * 2 + 1];
if(i * 2 + 2 < vec.size())
vecTree[i]->right = vecTree[i * 2 + 2];
}
}
@ -114,9 +121,10 @@ TreeNode* construct_binary_tree(const vector<int>& vec) {
vecTree[i] = node;
if (i == 0) root = node;
}
for (int i = 0; i * 2 + 2 < vec.size(); i++) {
for (int i = 0; i * 2 + 1 < vec.size(); i++) {
if (vecTree[i] != NULL) {
vecTree[i]->left = vecTree[i * 2 + 1];
if(i * 2 + 2 < vec.size())
vecTree[i]->right = vecTree[i * 2 + 2];
}
}
@ -249,12 +257,18 @@ public class Solution {
}
}
// 遍历一遍,根据规则左右孩子赋值就可以了
// 注意这里 结束规则是 i * 2 + 2 < arr.length避免空指针
for (int i = 0; i * 2 + 2 < arr.length; i++) {
// 注意这里 结束规则是 i * 2 + 1 < arr.length避免空指针
// 为什么结束规则不能是i * 2 + 2 < arr.length呢?
// 如果i * 2 + 2 < arr.length 是结束条件
// 那么i * 2 + 1这个符合条件的节点就被忽略掉了
// 例如[2,7,9,-1,1,9,6,-1,-1,10] 这样的一个二叉树,最后的10就会被忽略掉
for (int i = 0; i * 2 + 1 < arr.length; i++) {
TreeNode node = treeNodeList.get(i);
if (node != null) {
// 线性存储转连式存储关键逻辑
node.left = treeNodeList.get(2 * i + 1);
// 再次判断下 不忽略任何一个节点
if(i * 2 + 2 < arr.length)
node.right = treeNodeList.get(2 * i + 2);
}
}

View File

@ -263,6 +263,13 @@ function reverseLeftWords(s: string, n: number): string {
return strArr.join('');
};
```
方法二:
```typescript
// 拼接两个字符串,截取符合要求的部分
function reverseLeftWords(s: string, n: number): string {
return (s+s).slice(n,s.length+n);
};
```
Swift: