Skip to content

Commit 0e4ac09

Browse files
committed
update
1 parent 618a063 commit 0e4ac09

File tree

6 files changed

+169
-6
lines changed

6 files changed

+169
-6
lines changed

0045-跳跃游戏 II.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ class Solution {
3939
return step;
4040
}
4141
}
42-
```
42+
```

0046-全排列.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,13 @@ public class Solution {
3030
dfs(nums, 0, results);
3131
return results;
3232
}
33-
33+
3434
private void swap(int[] nums, int i, int j) {
3535
int temp = nums[i];
3636
nums[i] = nums[j];
3737
nums[j] = temp;
3838
}
39-
40-
39+
4140
private void dfs(int[] nums, int l, List<List<Integer>> results) {
4241
if (l == nums.length) {
4342
List<Integer> result = new ArrayList<Integer>();
@@ -46,12 +45,12 @@ public class Solution {
4645
}
4746
results.add(result);
4847
}
49-
48+
5049
for (int i = l; i < nums.length; i++) {
5150
swap(nums, l, i);
5251
dfs(nums, l+1, results);
5352
swap(nums, l, i);
5453
}
5554
}
5655
}
57-
```
56+
```

0047-全排列 II.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# 全排列 II
2+
3+
## 题目描述
4+
5+
给定一个可包含重复数字的序列,返回所有不重复的全排列。
6+
7+
```
8+
输入: [1,1,2]
9+
输出:
10+
[
11+
[1,1,2],
12+
[1,2,1],
13+
[2,1,1]
14+
]
15+
```
16+
17+
## 分析
18+
19+
1. 在开始回溯算法之前,对数组进行一次排序操作,这是上面多次提到的;
20+
2. 在进入一个新的分支之前,看一看这个数是不是和之前的数一样,如果这个数和之前的数一样,并且之前的数还未使用过,那接下来如果走这个分支,就会使用到之前那个和当前一样的数,就会发生重复,此时分支和之前的分支一模一样。
21+
22+
## 算法
23+
24+
```java
25+
class Solution {
26+
private List<List<Integer>> lists = new ArrayList<>();
27+
28+
public List<List<Integer>> permuteUnique(int[] nums) {
29+
if(nums == null || nums.length == 0) return lists;
30+
Arrays.sort(nums);
31+
dfs(new LinkedList<Integer>(), nums, new boolean[nums.length]);
32+
return lists;
33+
}
34+
35+
private void dfs(LinkedList<Integer> list, int[] nums, boolean[] used){
36+
if(nums.length == list.length()){
37+
lists.add(new ArrayList<Integer>(list));
38+
return;
39+
}
40+
41+
for(int i = 0; i < nums.length; i++){
42+
if(!used[i]){
43+
if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) {
44+
continue;
45+
}
46+
used[i] = true;
47+
list.addLast(nums[i]);
48+
dfs(list, nums, used);
49+
list.removeLast();
50+
used[i] = false;
51+
}
52+
}
53+
}
54+
}
55+
```

0239-滑动窗口最大值.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# 滑动窗口最大值
2+
3+
## 题目描述
4+
5+
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
6+
7+
返回滑动窗口中的最大值。
8+
9+
## 分析
10+
11+
使用一个双端链表保存数组的索引值。每次向链表中添加元素时保证以下操作即可在链表首端得到当前窗口的最大值的**索引**
12+
13+
* 观察链表尾端的索引对应的值是否大于欲入链表索引对应的值,若是则加入链表尾端。若不是将尾端的索引移除,继续比较,直到满足大于条件,然后将欲入链表索引加入链表尾端。
14+
* 计算出链表尾端的索引和链表首端的索引差值是否大于等于窗口大小,若是则将首端元素移除,反之不做任何操作。
15+
16+
此时链表的首端元素即为该窗口下最大的元素的索引。
17+
18+
## 算法
19+
20+
```java
21+
class Solution {
22+
public int[] maxSlidingWindow(int[] nums, int k) {
23+
if(k == 0 || nums == null || nums.length == 0) return new int[0];
24+
if(k == 1) return nums;
25+
26+
LinkedList<Integer> list = new LinkedList<>();
27+
int []result = new int[nums.length - k + 1];
28+
29+
for(int i = 0; i < k; i++){
30+
add(list, nums, i, k);
31+
}
32+
33+
for(int i = 0; i < result.length; i++){
34+
result[i] = add(list, nums, k + i - 1, k);
35+
}
36+
return result;
37+
}
38+
39+
private int add(LinkedList<Integer> list, int[] nums, int index, int k){
40+
Integer i;
41+
42+
while((i = list.peekLast()) != null && nums[i] < nums[index]){
43+
list.pollLast();
44+
}
45+
46+
list.offerLast(index);
47+
48+
if(index - list.getFirst() >= k) list.pollFirst();
49+
50+
return nums[list.peekFirst()];
51+
}
52+
}
53+
```

0283-移动零.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# 移动零
2+
3+
## 题目描述
4+
5+
给定一个数组 `nums`,编写一个函数将所有 `0` 移动到数组的末尾,同时保持非零元素的相对顺序。
6+
7+
## 分析
8+
9+
如果一个数为零,则利用后面一位非零的值代替0的位置,最后循环补零就行了。
10+
11+
## 算法
12+
13+
```java
14+
class Solution {
15+
public void moveZeroes(int[] nums) {
16+
int index = 0;
17+
18+
for(int i = 0; i < nums.length; i++){
19+
if(nums[i] != 0)
20+
nums[index++] = nums[i];
21+
}
22+
23+
for(int i = index; i < nums.length; i++){
24+
nums[i] = 0;
25+
}
26+
}
27+
}
28+
```

0292-Nim 游戏.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Nim 游戏
2+
3+
## 题目描述
4+
5+
你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。
6+
7+
你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
8+
9+
```
10+
输入: 4
11+
输出: false
12+
解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;
13+
因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。
14+
```
15+
16+
## 分析
17+
18+
巴什博奕,`n%(m+1)!=0` 时,先手总是会赢的。
19+
20+
## 算法
21+
22+
```java
23+
class Solution {
24+
public boolean canWinNim(int n) {
25+
return (n & 3) != 0;
26+
}
27+
}
28+
```

0 commit comments

Comments
 (0)