mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 00:43:04 +08:00
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
@ -402,16 +402,18 @@ public class Solution {
|
||||
### Dart:
|
||||
|
||||
```dart
|
||||
List<int> twoSum(List<int> nums, int target) {
|
||||
var tmp = [];
|
||||
for (var i = 0; i < nums.length; i++) {
|
||||
var rest = target - nums[i];
|
||||
if(tmp.contains(rest)){
|
||||
return [tmp.indexOf(rest), i];
|
||||
}
|
||||
tmp.add(nums[i]);
|
||||
import 'dart:collection';
|
||||
|
||||
List<int> twoSum(List<int> nums, int target) {
|
||||
HashMap<int, int> hashMap = HashMap();
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
int rest = target - nums[i];
|
||||
if (hashMap.containsKey(rest)) {
|
||||
return [hashMap[rest]!, i];
|
||||
}
|
||||
return [0 , 0];
|
||||
hashMap.addEntries({nums[i]: i}.entries);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -51,7 +51,7 @@ class Solution {
|
||||
public:
|
||||
ListNode* swapPairs(ListNode* head) {
|
||||
ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
|
||||
dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
|
||||
dummyHead->next = head; // 将虚拟头结点指向head,这样方便后面做删除操作
|
||||
ListNode* cur = dummyHead;
|
||||
while(cur->next != nullptr && cur->next->next != nullptr) {
|
||||
ListNode* tmp = cur->next; // 记录临时节点
|
||||
@ -160,7 +160,7 @@ class Solution {
|
||||
class Solution {
|
||||
public ListNode swapPairs(ListNode head) {
|
||||
ListNode dumyhead = new ListNode(-1); // 设置一个虚拟头结点
|
||||
dumyhead.next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
|
||||
dumyhead.next = head; // 将虚拟头结点指向head,这样方便后面做删除操作
|
||||
ListNode cur = dumyhead;
|
||||
ListNode temp; // 临时节点,保存两个节点后面的节点
|
||||
ListNode firstnode; // 临时节点,保存两个节点之中的第一个节点
|
||||
|
@ -197,6 +197,26 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
// 相向双指针法(版本二)
|
||||
class Solution {
|
||||
public int removeElement(int[] nums, int val) {
|
||||
int left = 0;
|
||||
int right = nums.length - 1;
|
||||
while(left <= right){
|
||||
if(nums[left] == val){
|
||||
nums[left] = nums[right];
|
||||
right--;
|
||||
}else {
|
||||
// 这里兼容了right指针指向的值与val相等的情况
|
||||
left++;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Python:
|
||||
|
||||
|
||||
|
@ -251,6 +251,60 @@ var spiralOrder = function(matrix) {
|
||||
return arr
|
||||
};
|
||||
```
|
||||
### Python
|
||||
|
||||
```python
|
||||
class Solution(object):
|
||||
def spiralOrder(self, matrix):
|
||||
"""
|
||||
:type matrix: List[List[int]]
|
||||
:rtype: List[int]
|
||||
"""
|
||||
if len(matrix) == 0 or len(matrix[0]) == 0 : # 判定List是否为空
|
||||
return []
|
||||
row, col = len(matrix), len(matrix[0]) # 行数,列数
|
||||
loop = min(row, col) // 2 # 循环轮数
|
||||
stx, sty = 0, 0 # 起始x,y坐标
|
||||
i, j =0, 0
|
||||
count = 0 # 计数
|
||||
offset = 1 # 每轮减少的格子数
|
||||
result = [0] * (row * col)
|
||||
while loop>0 :# 左闭右开
|
||||
i, j = stx, sty
|
||||
while j < col - offset : # 从左到右
|
||||
result[count] = matrix[i][j]
|
||||
count += 1
|
||||
j += 1
|
||||
while i < row - offset : # 从上到下
|
||||
result[count] = matrix[i][j]
|
||||
count += 1
|
||||
i += 1
|
||||
while j>sty : # 从右到左
|
||||
result[count] = matrix[i][j]
|
||||
count += 1
|
||||
j -= 1
|
||||
while i>stx : # 从下到上
|
||||
result[count] = matrix[i][j]
|
||||
count += 1
|
||||
i -= 1
|
||||
stx += 1
|
||||
sty += 1
|
||||
offset += 1
|
||||
loop -= 1
|
||||
if min(row, col) % 2 == 1 : # 判定是否需要填充多出来的一行
|
||||
i = stx
|
||||
if row < col :
|
||||
while i < stx + col - row + 1 :
|
||||
result[count] = matrix[stx][i]
|
||||
count += 1
|
||||
i += 1
|
||||
else :
|
||||
while i < stx + row - col + 1 :
|
||||
result[count] = matrix[i][stx]
|
||||
count += 1
|
||||
i += 1
|
||||
return result
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -278,6 +278,40 @@ class Solution:
|
||||
|
||||
return result
|
||||
```
|
||||
```python
|
||||
# 我们用三个状态去标记每一个格子
|
||||
# 0 代表海水
|
||||
# 1 代表陆地
|
||||
# 2 代表已经访问的陆地
|
||||
class Solution:
|
||||
def traversal(self, grid, i, j):
|
||||
m = len(grid)
|
||||
n = len(grid[0])
|
||||
|
||||
if i < 0 or j < 0 or i >= m or j >= n:
|
||||
return # 越界了
|
||||
elif grid[i][j] == "2" or grid[i][j] == "0":
|
||||
return
|
||||
|
||||
grid[i][j] = "2"
|
||||
self.traversal(grid, i - 1, j) # 往上走
|
||||
self.traversal(grid, i + 1, j) # 往下走
|
||||
self.traversal(grid, i, j - 1) # 往左走
|
||||
self.traversal(grid, i, j + 1) # 往右走
|
||||
|
||||
def numIslands(self, grid: List[List[str]]) -> int:
|
||||
res = 0
|
||||
|
||||
|
||||
for i in range(len(grid)):
|
||||
for j in range(len(grid[0])):
|
||||
if grid[i][j] == "1":
|
||||
res += 1
|
||||
self.traversal(grid, i, j)
|
||||
|
||||
return res
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
|
||||
```javascript
|
||||
|
@ -127,7 +127,7 @@ class Solution {
|
||||
public:
|
||||
ListNode* removeElements(ListNode* head, int val) {
|
||||
ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
|
||||
dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
|
||||
dummyHead->next = head; // 将虚拟头结点指向head,这样方便后面做删除操作
|
||||
ListNode* cur = dummyHead;
|
||||
while (cur->next != NULL) {
|
||||
if(cur->next->val == val) {
|
||||
|
@ -225,32 +225,38 @@ class Solution:
|
||||
// 打家劫舍Ⅱ 动态规划
|
||||
// 时间复杂度O(n) 空间复杂度O(n)
|
||||
func rob(nums []int) int {
|
||||
if len(nums) == 1 {
|
||||
return nums[0]
|
||||
// 如果长度为0或1,那么有没有环的限制都一样
|
||||
if len(nums) <= 1 {
|
||||
return robWithoutCircle(nums)
|
||||
}
|
||||
if len(nums) == 2 {
|
||||
return max(nums[0], nums[1])
|
||||
}
|
||||
|
||||
result1 := robRange(nums, 0)
|
||||
result2 := robRange(nums, 1)
|
||||
return max(result1, result2)
|
||||
|
||||
// 否则,去头或去尾,取最大
|
||||
res1 := robWithoutCircle(nums[:len(nums)-1])
|
||||
res2 := robWithoutCircle(nums[1:])
|
||||
|
||||
return max(res1, res2)
|
||||
}
|
||||
|
||||
// 偷盗指定的范围
|
||||
func robRange(nums []int, start int) int {
|
||||
// 原始的打家劫舍版
|
||||
func robWithoutCircle(nums []int) int {
|
||||
switch len(nums) {
|
||||
case 0: return 0
|
||||
case 1: return nums[0]
|
||||
}
|
||||
dp := make([]int, len(nums))
|
||||
dp[1] = nums[start]
|
||||
|
||||
for i := 2; i < len(nums); i++ {
|
||||
dp[i] = max(dp[i - 2] + nums[i - 1 + start], dp[i - 1])
|
||||
dp[0]=nums[0]
|
||||
dp[1] = max(nums[0], nums[1])
|
||||
|
||||
for i:=2; i<len(nums); i++ {
|
||||
dp[i] = max(dp[i-1], dp[i-2]+nums[i])
|
||||
}
|
||||
|
||||
return dp[len(nums) - 1]
|
||||
|
||||
return dp[len(nums)-1]
|
||||
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
func max(a, b int ) int {
|
||||
if a>b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
|
@ -240,26 +240,45 @@ function isSubsequence(s: string, t: string): boolean {
|
||||
|
||||
### Go:
|
||||
|
||||
二维DP:
|
||||
|
||||
```go
|
||||
func isSubsequence(s string, t string) bool {
|
||||
dp := make([][]int,len(s)+1)
|
||||
for i:=0;i<len(dp);i++{
|
||||
dp[i] = make([]int,len(t)+1)
|
||||
dp := make([][]int, len(s) + 1)
|
||||
for i := 0; i < len(dp); i ++{
|
||||
dp[i] = make([]int, len(t) + 1)
|
||||
}
|
||||
for i:=1;i<len(dp);i++{
|
||||
for j:=1;j<len(dp[i]);j++{
|
||||
if s[i-1] == t[j-1]{
|
||||
dp[i][j] = dp[i-1][j-1] +1
|
||||
for i := 1; i < len(dp); i ++{
|
||||
for j := 1; j < len(dp[i]); j ++{
|
||||
if s[i - 1] == t[j - 1] {
|
||||
dp[i][j] = dp[i - 1][j - 1] +1
|
||||
}else{
|
||||
dp[i][j] = dp[i][j-1]
|
||||
dp[i][j] = dp[i][j - 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[len(s)][len(t)]==len(s)
|
||||
return dp[len(s)][len(t)] == len(s)
|
||||
}
|
||||
```
|
||||
|
||||
Rust:
|
||||
一维DP:
|
||||
|
||||
```go
|
||||
func isSubsequence(s string, t string) bool {
|
||||
dp := make([]int, len(s) + 1)
|
||||
for i := 1; i <= len(t); i ++ {
|
||||
for j := len(s); j >= 1; j -- {
|
||||
if t[i - 1] == s[j - 1] {
|
||||
dp[j] = dp[j - 1] + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[len(s)] == len(s)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Rust:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
|
@ -769,6 +769,38 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### C#
|
||||
|
||||
> 递归法:
|
||||
```C#
|
||||
public TreeNode DeleteNode(TreeNode root, int key) {
|
||||
// 第一种情况:没找到删除的节点,遍历到空节点直接返回了
|
||||
if (root == null) return null;
|
||||
if(key == root.val) {
|
||||
//第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
|
||||
if(root.left == null && root.right == null) return null;
|
||||
//第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点
|
||||
if (root.left == null && root.right != null) return root.right;
|
||||
//第四种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
|
||||
if (root.left != null && root.right == null) return root.left;
|
||||
//第五种情况:左右孩子节点都不为空,则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置
|
||||
// 并返回删除节点右孩子为新的根节点。
|
||||
if(root.left != null && root.right != null) {
|
||||
TreeNode leftNode = root.right; // 找右子树最左面的节点
|
||||
while(leftNode.left != null)
|
||||
leftNode = leftNode.left;
|
||||
leftNode.left = root.left; // 把要删除的节点(root)左子树放在leftNode的左孩子的位置
|
||||
return root.right; // 返回旧root的右孩子作为新root
|
||||
}
|
||||
}
|
||||
|
||||
if(root.val > key) root.left = DeleteNode(root.left, key);
|
||||
if(root.val < key) root.right = DeleteNode(root.right, key);
|
||||
|
||||
return root;
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -89,7 +89,7 @@ if (x == graph.size() - 1) { // 找到符合条件的一条路径
|
||||
for (int i = 0; i < graph[x].size(); i++) { // 遍历节点n链接的所有节点
|
||||
```
|
||||
|
||||
接下来就是将 选中的x所连接的节点,加入到 单一路劲来。
|
||||
接下来就是将 选中的x所连接的节点,加入到 单一路径来。
|
||||
|
||||
```C++
|
||||
path.push_back(graph[x][i]); // 遍历到的节点加入到路径中来
|
||||
|
@ -171,36 +171,29 @@ class Solution:
|
||||
|
||||
```go
|
||||
func sortByBits(arr []int) []int {
|
||||
var tmp int
|
||||
for i := 0; i < len(arr); i++ {
|
||||
for j := i+1; j < len(arr); j++ {
|
||||
// 冒泡排序的手法,但是排序的规则从比大小变成了比位运算1的个数
|
||||
if isCmp(arr[i], arr[j]) {
|
||||
tmp = arr[i]
|
||||
arr[i] = arr[j]
|
||||
arr[j] = tmp
|
||||
}
|
||||
}
|
||||
// 是否arr[i]<=arr[j]
|
||||
// 先比较1的数量,后比较值本身
|
||||
cmp := func(i, j int) bool {
|
||||
c1, c2 := bitCount(arr[i]), bitCount(arr[j])
|
||||
if c1 == c2 {
|
||||
return arr[i] <= arr[j]
|
||||
}
|
||||
return c1 <= c2
|
||||
}
|
||||
|
||||
// 调用库函数
|
||||
// 第一个参数是待排序切片,第二个是第i位是否小于第j位的函数
|
||||
sort.Slice(arr, cmp)
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
func isCmp(a, b int) bool {
|
||||
bitA := bitCount(a)
|
||||
bitB := bitCount(b)
|
||||
if bitA == bitB {
|
||||
return a > b
|
||||
} else {
|
||||
return bitA > bitB
|
||||
}
|
||||
}
|
||||
|
||||
func bitCount(n int) int {
|
||||
count := 0
|
||||
for n != 0 {
|
||||
n &= (n-1) // 清除最低位的1
|
||||
func bitCount(num int) (count int) {
|
||||
for num != 0 {
|
||||
num &= num-1 // 每次运算将最右侧的1变成0
|
||||
count++
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
```
|
||||
|
@ -133,7 +133,7 @@ dp[1] = dp[1 - weight[0]] + value[0] = 15
|
||||
|
||||
所以从后往前循环,每次取得状态不会和之前取得状态重合,这样每种物品就只取一次了。
|
||||
|
||||
**那么问题又来了,为什么二维dp数组历的时候不用倒序呢?**
|
||||
**那么问题又来了,为什么二维dp数组遍历的时候不用倒序呢?**
|
||||
|
||||
因为对于二维dp,dp[i][j]都是通过上一层即dp[i - 1][j]计算而来,本层的dp[i][j]并不会被覆盖!
|
||||
|
||||
|
Reference in New Issue
Block a user