Skip to content

Commit 0a0d11c

Browse files
committed
Update solution 047
1 parent 7b2f148 commit 0a0d11c

File tree

1 file changed

+80
-2
lines changed

1 file changed

+80
-2
lines changed

solution/047.Permutations II/README.md

+80-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
```
1616

1717
### 解法
18+
19+
解法①:
20+
1821
将数组的首元素依次与数组的每个元素交换(两元素不相等才进行交换),对于每一轮交换,对后面的数组进行递归调用。当元素只剩下一个时,添加此时的数组到 list 中。
1922

2023
注意:第 i 个数字与第 j 个数字交换时,要求[i, j) 中没有与第 j 个数字相等的数。
2124

22-
解法①:
23-
2425
```java
2526
class Solution {
2627
public List<List<Integer>> permuteUnique(int[] nums) {
@@ -72,6 +73,8 @@ class Solution {
7273

7374
解法②:
7475

76+
利用空间换取时间,减少 n^2 复杂度。这里的空间,可以采用数组,或者 HashMap。
77+
7578
```java
7679
class Solution {
7780
public List<List<Integer>> permuteUnique(int[] nums) {
@@ -123,4 +126,79 @@ class Solution {
123126
nums[j] = t;
124127
}
125128
}
129+
```
130+
131+
解法➂:
132+
133+
这是非递归的解法。思路就是:
134+
135+
- 先保存升序数组;
136+
- 找到下一个比该数组大的数组,保存;
137+
- 直到数组呈降序。
138+
139+
如何找到下一个数组呢?从后往前,找到第一个升序状态的位置,记为 i-1,在[i, length - 1] 中找到比 nums[i - 1] 大的,且差值最小的元素(如果有多个差值最小且相同的元素,取后者),进行交换。将后面的数组序列升序排列,保存。然后恢复 i,继续循环。
140+
141+
```java
142+
class Solution {
143+
public List<List<Integer>> permuteUnique(int[] nums) {
144+
List<List<Integer>> list = new ArrayList<>();
145+
// 先排序,并添加至 list 中
146+
Arrays.sort(nums);
147+
addList(list, nums);
148+
permute(list, nums);
149+
return list;
150+
}
151+
152+
private void permute(List<List<Integer>> list, int[] nums) {
153+
int n = nums.length;
154+
for (int i = n - 1; i > 0; --i) {
155+
if (nums[i - 1] < nums[i]) {
156+
// 在数组右边找到比 nums[i - 1] 大的,但差值最小的数的下标
157+
// 若有多个最小差值,取后者
158+
int index = findMinIndex(nums, i, nums[i - 1]);
159+
swap(nums, i - 1, index);
160+
sortArr(nums, i);
161+
addList(list, nums);
162+
i = n;
163+
}
164+
}
165+
166+
}
167+
168+
private void sortArr(int[] nums, int start) {
169+
int n = nums.length - 1;
170+
while (start < n) {
171+
swap(nums, start, n);
172+
++start;
173+
--n;
174+
}
175+
}
176+
177+
private int findMinIndex(int[] nums, int start, int val) {
178+
int index = start;
179+
int distance = nums[start] - val;
180+
for (int i = start; i < nums.length; ++i) {
181+
if (nums[i] > val && (nums[i] - val <= distance)) {
182+
distance = nums[i] - val;
183+
index = i;
184+
}
185+
}
186+
return index;
187+
}
188+
189+
private void addList(List<List<Integer>> list, int[] nums) {
190+
List<Integer> tmpList = new ArrayList<>();
191+
for (int val : nums) {
192+
tmpList.add(val);
193+
}
194+
list.add(tmpList);
195+
196+
}
197+
198+
private void swap(int[] nums, int i, int j) {
199+
int t = nums[i];
200+
nums[i] = nums[j];
201+
nums[j] = t;
202+
}
203+
}
126204
```

0 commit comments

Comments
 (0)