Skip to content

Commit 08741f4

Browse files
author
FreeTymeKiyan
committed
update more solutions
1 parent 162b5ae commit 08741f4

File tree

8 files changed

+405
-383
lines changed

8 files changed

+405
-383
lines changed

src/main/java/com/freetymekiyan/algorithms/level/hard/FirstMissingPositive.java

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,44 @@
22

33
/**
44
* Given an unsorted integer array, find the first missing positive integer.
5-
*
5+
* <p>
66
* For example,
77
* Given [1,2,0] return 3,
88
* and [3,4,-1,1] return 2.
9-
*
9+
* <p>
1010
* Your algorithm should run in O(n) time and uses constant space.
11-
*
11+
* <p>
1212
* Tags: Array
1313
*/
1414
class FirstMissingPositive {
15-
public static void main(String[] args) {
16-
int[] A = {1,2,0};
17-
System.out.println(new FirstMissingPositive().firstMissingPositive(A));
15+
public static void main(String[] args) {
16+
int[] A = {1, 2, 0};
17+
System.out.println(new FirstMissingPositive().firstMissingPositive(A));
18+
}
19+
20+
/**
21+
* Position of integer n should be n - 1 if sorted
22+
* Correct form [1, 2, 3, 4, ..., #, n]
23+
* If not in position swap it with nums[nums[p]-1]
24+
*/
25+
public int firstMissingPositive(int[] nums) {
26+
if (nums == null || nums.length == 0) {
27+
return 1;
28+
}
29+
int length = nums.length;
30+
for (int i = 0; i < length; i++) {
31+
int num = nums[i];
32+
while (nums[i] <= length && nums[i] > 0 && nums[num - 1] != num) {
33+
nums[i] = nums[num - 1];
34+
nums[num - 1] = num;
35+
num = nums[i];
36+
}
1837
}
19-
20-
/**
21-
* Position of integer n should be n - 1 if sorted
22-
* Correct form [1, 2, 3, 4, ..., #, n]
23-
* If not in position swap it with A[A[p]-1]
24-
*/
25-
public static int firstMissingPositive(int[] A) {
26-
if (A == null || A.length == 0) return 1;
27-
int n = A.length;
28-
for (int i = 0; i < n; i++) {
29-
int num = A[i];
30-
while (A[i] <= n && A[i] > 0 && A[num - 1] != num) {
31-
A[i] = A[num - 1];
32-
A[num - 1] = num;
33-
num = A[i];
34-
}
35-
}
36-
for (int i = 0; i < n; i++)
37-
if (A[i] != i + 1) return i + 1;
38-
return n + 1; // nothing in middle losing, return largest
38+
for (int i = 0; i < length; i++) {
39+
if (nums[i] != i + 1) {
40+
return i + 1;
41+
}
3942
}
43+
return length + 1; // Nothing in middle missing, return largest
44+
}
4045
}

src/main/java/com/freetymekiyan/algorithms/level/hard/JumpGame2.java

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,42 @@
33
/**
44
* Given an array of non-negative integers, you are initially positioned at the
55
* first index of the array.
6-
*
6+
* <p>
77
* Each element in the array represents your maximum jump length at that
88
* position.
9-
*
9+
* <p>
1010
* Your goal is to reach the last index in the minimum number of jumps.
11-
*
11+
* <p>
1212
* For example:
1313
* Given array A = [2,3,1,1,4]
14-
*
14+
* <p>
1515
* The minimum number of jumps to reach the last index is 2. (Jump 1 step from
1616
* index 0 to 1, then 3 steps to the last index.)
17-
*
17+
* <p>
1818
* Tags: Array, Greedy, DP
1919
*/
2020
class JumpGame2 {
21-
public static void main(String[] args) {
22-
23-
}
24-
25-
/**
26-
* Use last to store how far we already can reach
27-
* Compare i with last
28-
* If we run out of it, update and add 1 more step to result
29-
* Return if last is already bigger than or equal to the length
30-
* Use cur to store how far we can reach for the next step
31-
*/
32-
public int jump(int[] A) {
33-
int step = 0;
34-
int last = 0; // how far we already can reach
35-
int cur = 0; // how far can we reach for next step
36-
37-
for (int i = 0; i < A.length; i++) {
38-
if (i > last) { // run out of we can reach, need one more step
39-
last = cur;
40-
step++;
41-
if (last >= A.length) return step;
42-
}
43-
cur = Math.max(cur, i + A[i]);
44-
}
45-
return step;
21+
22+
/**
23+
* Use last to store how far we already can reach
24+
* Compare i with last
25+
* If we run out of it, update and add 1 more step to result
26+
* Return if last is already bigger than or equal to the length
27+
* Use cur to store how far we can reach for the next step
28+
*/
29+
public int jump(int[] A) {
30+
int step = 0;
31+
int last = 0; // How far we already can reach
32+
int cur = 0; // How far can we reach for next step
33+
34+
for (int i = 0; i < A.length; i++) {
35+
if (i > last) { // Run out of we can reach, need one more step
36+
last = cur;
37+
step++;
38+
if (last >= A.length) return step;
39+
}
40+
cur = Math.max(cur, i + A[i]);
4641
}
42+
return step;
43+
}
4744
}
Lines changed: 100 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,121 @@
11
package com.freetymekiyan.algorithms.level.hard;
22

3-
import java.util.*;
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.Collections;
6+
import java.util.List;
47

58
/**
69
* Given a collection of numbers that might contain duplicates, return all
710
* possible unique permutations.
8-
*
11+
* <p>
912
* For example,
1013
* [1,1,2] have the following unique permutations:
1114
* [1,1,2], [1,2,1], and [2,1,1].
12-
*
15+
* <p>
1316
* Tags: Backtracking
1417
*/
1518
class Permutations2 {
16-
public static void main(String[] args) {
17-
List<List<Integer>> res = permuteUniqueB(new int[]{1, 2, 3});
18-
for (List<Integer> l : res) System.out.println(l);
19-
}
20-
21-
/**
22-
* Same idea as Permutation 1 except we skip if duplicate of current element
23-
* is found in previous sequence
24-
*/
25-
public List<List<Integer>> permuteUnique(int[] num) {
26-
List<List<Integer>> res = new ArrayList<List<Integer>>();
27-
if (num == null || num.length == 0) return res;
28-
Arrays.sort(num);
29-
permute(num, 0, res);
30-
return res;
19+
20+
/**
21+
* Lexicography Order next permutation
22+
* Find the next permutation in lexicographic order.
23+
* http://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
24+
*/
25+
public List<List<Integer>> permuteUniqueB(int[] num) {
26+
List<List<Integer>> res = new ArrayList<>();
27+
if (num == null || num.length == 0) return res;
28+
Arrays.sort(num);
29+
List<Integer> row = new ArrayList<>();
30+
for (int a : num) row.add(a);
31+
res.add(new ArrayList<>(row)); // first permutation
32+
while (nextPermutation(row)) { // if there is next permutation
33+
res.add(new ArrayList<>(row));
3134
}
32-
33-
public void permute(int[] num, int pos, List<List<Integer>> res) {
34-
if (pos == num.length) {
35-
List<Integer> row = new ArrayList<Integer>();
36-
for (int a : num) row.add(a);
37-
res.add(row);
38-
return;
39-
}
40-
for (int i = pos; i < num.length; i++) {
41-
// skip if we have duplicates of current element before i
42-
boolean skip = false;
43-
for (int j = pos; j < i; j++) {
44-
if (num[j] == num[i]) {
45-
skip = true;
46-
break;
47-
}
48-
}
49-
if (skip) continue;
50-
swap(num, pos, i);
51-
permute(num, pos + 1, res);
52-
swap(num, pos, i); // reset
53-
}
35+
return res;
36+
}
37+
38+
/**
39+
* e.g.: 1234 -> 1243, 1243 -> 1324
40+
* Traverse backward to get 3
41+
* Then traverse forward to get furthest number bigger than 3
42+
* Swap these two digits and reverse from next to last
43+
*/
44+
private boolean nextPermutation(List<Integer> row) {
45+
int last = row.size() - 1;
46+
for (int pos = last - 1; pos >= 0; pos--) {
47+
if (row.get(pos) < row.get(pos + 1)) {
48+
int smallIdx = pos;
49+
int biggerIdx = pos + 1;
50+
for (int i = pos + 1; i <= last; i++)
51+
if (row.get(i) > row.get(pos)) biggerIdx = i;
52+
swap(row, smallIdx, biggerIdx);
53+
reverse(row, pos + 1, last);
54+
return true;
55+
}
5456
}
57+
return false;
58+
}
59+
60+
private void swap(List<Integer> row, int a, int b) {
61+
int t = row.get(a);
62+
row.set(a, row.get(b));
63+
row.set(b, t);
64+
}
5565

56-
public void swap(int[] num, int i, int j) {
57-
if (i == j) return;
58-
num[i] = num[j] - num[i];
59-
num[j] = num[j] - num[i];
60-
num[i] = num[j] + num[i];
66+
private void reverse(List<Integer> row, int s, int e) {
67+
while (s < e) {
68+
swap(row, s, e);
69+
s++;
70+
e--;
6171
}
62-
63-
/**
64-
* Lexicography Order next permutation
65-
* Find the next permutation in lexicographic order.
66-
*http://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
67-
*/
68-
public static List<List<Integer>> permuteUniqueB(int[] num) {
69-
List<List<Integer>> res = new ArrayList<List<Integer>>();
70-
if (num == null || num.length == 0) return res;
71-
Arrays.sort(num);
72-
List<Integer> row = new ArrayList<Integer>();
73-
for (int a : num) row.add(a);
74-
res.add(new ArrayList<Integer>(row)); // first permutation
75-
while (nextPermutation(row)) { // if there is next permutation
76-
res.add(new ArrayList<Integer>(row));
77-
}
78-
return res;
79-
}
80-
81-
/**
82-
* e.g.: 1234 -> 1243, 1243 -> 1324
83-
* Traverse backward to get 3
84-
* Then traverse forward to get furthest number bigger than 3
85-
* Swap these two digits and reverse from next to last
86-
*/
87-
public static boolean nextPermutation(List<Integer> row) {
88-
int last = row.size() - 1;
89-
for (int pos = last - 1; pos >= 0; pos--) {
90-
if (row.get(pos) < row.get(pos + 1)) {
91-
int smallIdx = pos;
92-
int biggerIdx = pos + 1;
93-
for (int i = pos + 1; i <= last; i++)
94-
if (row.get(i) > row.get(pos)) biggerIdx = i;
95-
swap(row, smallIdx, biggerIdx);
96-
reverse(row, pos + 1, last);
97-
return true;
98-
}
99-
}
100-
return false;
72+
}
73+
74+
/**
75+
* Same idea as Permutation 1 except we skip if duplicate of current element
76+
* is found in previous sequence
77+
*/
78+
public List<List<Integer>> permuteUnique(int[] num) {
79+
if (num == null || num.length == 0) {
80+
return Collections.emptyList();
10181
}
102-
103-
public static void swap(List<Integer> row, int a, int b) {
104-
int t = row.get(a);
105-
row.set(a, row.get(b));
106-
row.set(b, t);
82+
Arrays.sort(num);
83+
final List<List<Integer>> res = new ArrayList<>();
84+
dfs(num, 0, res);
85+
return res;
86+
}
87+
88+
private void dfs(int[] num, int pos, List<List<Integer>> res) {
89+
if (pos == num.length) {
90+
final List<Integer> row = new ArrayList<>(num.length);
91+
for (int a : num) {
92+
row.add(a);
93+
}
94+
res.add(row);
95+
return;
10796
}
108-
109-
public static void reverse(List<Integer> row, int s, int e) {
110-
while (s < e) {
111-
swap(row, s, e);
112-
s++;
113-
e--;
97+
for (int i = pos; i < num.length; i++) {
98+
// Skip if we have duplicates of current element before i
99+
boolean skip = false;
100+
for (int j = pos; j < i; j++) {
101+
if (num[j] == num[i]) {
102+
skip = true;
103+
break;
114104
}
105+
}
106+
if (skip) continue;
107+
swap(num, pos, i);
108+
dfs(num, pos + 1, res);
109+
swap(num, pos, i); // Reset
110+
}
111+
}
112+
113+
private void swap(int[] num, int i, int j) {
114+
if (i == j) {
115+
return;
115116
}
117+
num[i] = num[j] - num[i];
118+
num[j] = num[j] - num[i];
119+
num[i] = num[j] + num[i];
120+
}
116121
}

0 commit comments

Comments
 (0)