Skip to content

Commit 62a817e

Browse files
[LEET-0000] clean up
1 parent 254a642 commit 62a817e

18 files changed

+791
-3
lines changed

leetcode-algorithms/README.md

Lines changed: 18 additions & 2 deletions
Large diffs are not rendered by default.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.stevesun.solutions;
2+
3+
/**
4+
* Given an Android 3x3 key lock screen and two integers m and n, where 1 ≤ m ≤ n ≤ 9, count the total number of unlock patterns of the Android lock screen, which consist of minimum of m keys and maximum n keys.
5+
6+
Rules for a valid pattern:
7+
Each pattern must connect at least m keys and at most n keys.
8+
All the keys must be distinct.
9+
If the line connecting two consecutive keys in the pattern passes through any other keys, the other keys must have previously selected in the pattern. No jumps through non selected key is allowed.
10+
The order of keys used matters.
11+
12+
Explanation:
13+
| 1 | 2 | 3 |
14+
| 4 | 5 | 6 |
15+
| 7 | 8 | 9 |
16+
Invalid move: 4 - 1 - 3 - 6
17+
Line 1 - 3 passes through key 2 which had not been selected in the pattern.
18+
19+
Invalid move: 4 - 1 - 9 - 2
20+
Line 1 - 9 passes through key 5 which had not been selected in the pattern.
21+
22+
Valid move: 2 - 4 - 1 - 3 - 6
23+
Line 1 - 3 is valid because it passes through key 2, which had been selected in the pattern
24+
25+
Valid move: 6 - 5 - 4 - 1 - 9 - 2
26+
Line 1 - 9 is valid because it passes through key 5, which had been selected in the pattern.
27+
28+
Example:
29+
Given m = 1, n = 1, return 9.
30+
31+
32+
*/
33+
public class AndroidUnlockPatterns {
34+
35+
private int[][] jumps;
36+
private boolean[] visited;
37+
38+
public int numberOfPatterns(int m, int n) {
39+
jumps = new int[10][10];
40+
jumps[1][3] = jumps[3][1] = 2;
41+
jumps[4][6] = jumps[6][4] = 5;
42+
jumps[7][9] = jumps[9][7] = 8;
43+
jumps[1][7] = jumps[7][1] = 4;
44+
jumps[2][8] = jumps[8][2] = jumps[1][9] = jumps[9][1]= 5;
45+
jumps[9][3] = jumps[3][9] = 6;
46+
jumps[3][7] = jumps[7][3] = 5;
47+
visited = new boolean[10];
48+
int count = 0;
49+
count += dfs(1, 1, 0, m, n)*4;//1,3,7,9 are symmetric, so we only need to use 1 to do it once and then multiply the result by 4
50+
count += dfs(2, 1, 0, m, n)*4;//2,4,6,8 are symmetric, so we only need to use 1 to do it once and then multiply the result by 4
51+
count += dfs(5, 1, 0, m, n);
52+
return count;
53+
}
54+
55+
private int dfs(int num, int len, int count, int m, int n){
56+
if(len >= m) count++;
57+
len++;
58+
if(len > n) return count;
59+
visited[num] = true;
60+
for(int next = 1; next <= 9; next++){
61+
int jump = jumps[num][next];
62+
if(!visited[next] && (jump == 0 || visited[jump])){
63+
count = dfs(next, len, count, m, n);
64+
}
65+
}
66+
visited[num] = false;//backtracking
67+
return count;
68+
}
69+
70+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.stevesun.solutions;
2+
3+
/**
4+
* Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return the maximum enemies you can kill using one bomb.
5+
The bomb kills all the enemies in the same row and column from the planted point until it hits the wall since the wall is too strong to be destroyed.
6+
Note that you can only put the bomb at an empty cell.
7+
8+
Example:
9+
For the given grid
10+
11+
0 E 0 0
12+
E 0 W E
13+
0 E 0 0
14+
15+
return 3. (Placing a bomb at (1,1) kills 3 enemies)
16+
*/
17+
public class BombEnemies {
18+
19+
public int maxKilledEnemies(char[][] grid) {
20+
int m = grid.length;
21+
if(grid == null || m == 0) return 0;
22+
int n = grid[0].length;
23+
24+
int[][] max = new int[m][n];
25+
26+
for(int i = 0; i < m; i++){
27+
for(int j = 0; j < n; j++){
28+
29+
if(grid[i][j] == '0'){
30+
int count = 0;
31+
32+
//count all possible hits in its upward direction
33+
for(int k = j-1; k >= 0; k--){
34+
if(grid[i][k] == 'E') {
35+
count++;
36+
} else if(grid[i][k] == 'W') {
37+
break;
38+
}
39+
}
40+
41+
//count all possible hits in its downward direction
42+
for(int k = j+1; k < n; k++){
43+
if(grid[i][k] == 'E') {
44+
count++;
45+
} else if(grid[i][k] == 'W') {
46+
break;
47+
}
48+
}
49+
50+
//count all possible hits in its right direction
51+
for(int k = i+1; k < m; k++){
52+
if(grid[k][j] == 'E') {
53+
count++;
54+
} else if(grid[k][j] == 'W') {
55+
break;
56+
}
57+
}
58+
59+
//count all possible hits in its left direction
60+
for(int k = i-1; k >= 0; k--){
61+
if(grid[k][j] == 'E') {
62+
count++;
63+
} else if(grid[k][j] == 'W') {
64+
break;
65+
}
66+
}
67+
68+
max[i][j] = count;
69+
70+
}
71+
}
72+
}
73+
74+
int result = 0;
75+
76+
for(int i = 0; i < m; i++){
77+
for(int j = 0; j < n; j++){
78+
if(max[i][j] > result) result = max[i][j];
79+
}
80+
}
81+
return result;
82+
}
83+
84+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.stevesun.solutions;
2+
3+
/**
4+
* Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins. Here left and right are adjacent indices of i. After the burst, the left and right then becomes adjacent.
5+
6+
Find the maximum coins you can collect by bursting the balloons wisely.
7+
8+
Note:
9+
(1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.
10+
(2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100
11+
12+
Example:
13+
14+
Given [3, 1, 5, 8]
15+
16+
Return 167
17+
18+
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
19+
coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
20+
*/
21+
public class BurstBalloons {
22+
23+
public int maxCoins(int[] iNums) {
24+
int[] nums = new int[iNums.length + 2];
25+
int n = 1;
26+
for (int x : iNums)
27+
if (x > 0)
28+
nums[n++] = x;
29+
nums[0] = nums[n++] = 1;
30+
31+
int[][] dp = new int[n][n];
32+
for (int k = 2; k < n; ++k)
33+
for (int left = 0; left < n - k; ++left) {
34+
int right = left + k;
35+
for (int i = left + 1; i < right; ++i)
36+
dp[left][right] = Math.max(dp[left][right],
37+
nums[left] * nums[i] * nums[right] + dp[left][i] + dp[i][right]);
38+
}
39+
40+
return dp[0][n - 1];
41+
}
42+
43+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.stevesun.solutions;
2+
3+
/**
4+
* You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.
5+
6+
Example 1:
7+
coins = [1, 2, 5], amount = 11
8+
return 3 (11 = 5 + 5 + 1)
9+
10+
Example 2:
11+
coins = [2], amount = 3
12+
return -1.
13+
14+
Note:
15+
You may assume that you have an infinite number of each kind of coin.
16+
*/
17+
public class CoinChange {
18+
19+
public int coinChange(int[] coins, int amount) {
20+
if(amount < 1) return 0;
21+
int[] count = new int[amount];
22+
int result = helper(coins, amount, count);
23+
24+
return result;
25+
}
26+
27+
//remaining means the remaining coins after the last step;
28+
//count[remaining] means the minimum number of coins to sum up to remaining
29+
private int helper(int[] coins, int remaining, int[] count) {
30+
if(remaining < 0) return -1;//not valid case, thus, per problem description, we should return -1
31+
if(remaining == 0) return 0;//completed, this is also a base case for this recursive function
32+
if(count[remaining-1] != 0) return count[remaining-1];//already computed, so reuse it.
33+
int min = Integer.MAX_VALUE;
34+
for(int coin : coins){
35+
int res = helper(coins, remaining-coin, count);
36+
if(res >= 0 && res < min){
37+
min = 1+res;
38+
}
39+
}
40+
return count[remaining-1] = (min == Integer.MAX_VALUE) ? -1 : min;
41+
42+
}
43+
44+
}

leetcode-algorithms/src/main/java/com/stevesun/solutions/CombinationSum.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@
66
import java.util.Arrays;
77
import java.util.List;
88

9+
/**Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
10+
11+
The same repeated number may be chosen from C unlimited number of times.
12+
13+
Note:
14+
All numbers (including target) will be positive integers.
15+
The solution set must not contain duplicate combinations.
16+
For example, given candidate set [2, 3, 6, 7] and target 7,
17+
A solution set is:
18+
[
19+
[7],
20+
[2, 2, 3]
21+
]*/
922
public class CombinationSum {
1023

1124
public List<List<Integer>> combinationSum(int[] candidates, int target) {

leetcode-algorithms/src/main/java/com/stevesun/solutions/CombinationSumIV.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,29 @@
55
import java.util.ArrayList;
66
import java.util.Arrays;
77
import java.util.List;
8+
/**Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target.
89
10+
Example:
11+
12+
nums = [1, 2, 3]
13+
target = 4
14+
15+
The possible combination ways are:
16+
(1, 1, 1, 1)
17+
(1, 1, 2)
18+
(1, 2, 1)
19+
(1, 3)
20+
(2, 1, 1)
21+
(2, 2)
22+
(3, 1)
23+
24+
Note that different sequences are counted as different combinations.
25+
26+
Therefore the output is 7.
27+
Follow up:
28+
What if negative numbers are allowed in the given array?
29+
How does it change the problem?
30+
What limitation we need to add to the question to allow negative numbers?*/
931
public class CombinationSumIV {
1032
//since this question doesn't require to return all the combination result, instead, it just wants one number, we could use DP
1133
//the idea is similar to Climbing Stairs.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.stevesun.solutions;
2+
3+
/**
4+
* Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.
5+
Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), inclusive.
6+
7+
Note:
8+
A naive algorithm of O(n2) is trivial. You MUST do better than that.
9+
10+
Example:
11+
Given nums = [-2, 5, -1], lower = -2, upper = 2,
12+
Return 3.
13+
The three ranges are : [0, 0], [2, 2], [0, 2] and their respective sums are: -2, -1, 2.
14+
*/
15+
public class CountOfRangeSum {
16+
17+
public int countRangeSum(int[] nums, int lower, int upper) {
18+
int n = nums.length;
19+
long[] sums = new long[n+1];
20+
for(int i = 0; i < n; i++){
21+
sums[i+1] = sums[i] + nums[i];
22+
}
23+
return countWhileMergeSort(sums, 0, n+1, lower, upper);
24+
}
25+
26+
private int countWhileMergeSort(long[] sums, int start, int end, int lower, int upper) {
27+
if(end - start <= 1) return 0;
28+
int mid = (start+end)/2;
29+
int count = countWhileMergeSort(sums, start, mid, lower, upper) + countWhileMergeSort(sums, mid, end, lower, upper);
30+
int j = mid, k = mid, t = mid;
31+
long[] cache = new long[end-start];
32+
for(int i = start, r = 0; i < mid; i++, r++){
33+
while(k < end && sums[k] - sums[i] < lower) k++;
34+
while(j < end && sums[j] - sums[i] <= upper) j++;
35+
while(t < end && sums[t] < sums[i]) cache[r++] = sums[t++];
36+
cache[r] = sums[i];
37+
count += j-k;
38+
}
39+
System.arraycopy(cache, 0, sums, start, t-start);
40+
return count;
41+
}
42+
43+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.stevesun.solutions;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
6+
/**
7+
* You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].
8+
9+
Example:
10+
11+
Given nums = [5, 2, 6, 1]
12+
13+
To the right of 5 there are 2 smaller elements (2 and 1).
14+
To the right of 2 there is only 1 smaller element (1).
15+
To the right of 6 there is 1 smaller element (1).
16+
To the right of 1 there is 0 smaller element.
17+
Return the array [2, 1, 1, 0].
18+
19+
*/
20+
public class CountOfSmallerNumbersAfterSelf {
21+
22+
class Node{
23+
int val;
24+
int sum;
25+
int dup = 1;
26+
Node left;
27+
Node right;
28+
public Node(int v, int s){
29+
this.val = v;
30+
this.sum = s;
31+
}
32+
}
33+
34+
public List<Integer> countSmaller(int[] nums) {
35+
Integer[] ans = new Integer[nums.length];
36+
Node root = null;
37+
for(int i = nums.length-1; i >= 0; i--){
38+
root = insertNode(nums[i], root, i, 0, ans);
39+
}
40+
return Arrays.asList(ans);
41+
}
42+
43+
Node insertNode(int val, Node node, int i, int prevSum, Integer[] ans){
44+
if(node == null){
45+
node = new Node(val, 0);
46+
ans[i] = prevSum;
47+
} else if(val == node.val){
48+
node.dup += 1;
49+
ans[i] = prevSum + node.sum;
50+
} else if(val > node.val){
51+
node.right = insertNode(val, node.right, i, prevSum + node.sum + node.dup, ans);
52+
} else {
53+
node.sum += 1;
54+
node.left = insertNode(val, node.left, i, prevSum, ans);
55+
}
56+
57+
return node;
58+
}
59+
60+
}

0 commit comments

Comments
 (0)