Skip to content

Commit 59ea0f5

Browse files
author
FreeTymeKiyan
committed
add DesignHitCounter, MaxSumOfRectangleNoLargerThanK, PlusOneLinkedList, DesignPhoneDirectory
1 parent 78bf829 commit 59ea0f5

17 files changed

+928
-593
lines changed
Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.freetymekiyan.algorithms.level.easy;
22

33
/**
4+
* 371. Sum of Two Integers
5+
* <p>
46
* Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.
57
* <p>
68
* Example:
@@ -11,29 +13,29 @@
1113
*/
1214
public class SumOfTwoIntegers {
1315

14-
/**
15-
* For example, a = 0001, b = 0011.
16-
* First, we can use "and"("&") operation between a and b to find a carry.
17-
* carry = a & b, then carry = 0001
18-
* Second, we can use "xor" ("^") operation between a and b to find the different bit, and assign it to a.
19-
* Then, we shift carry one position left and assign it to b, b = 0010.
20-
* Iterate until there is no carry (or b == 0)
21-
*/
22-
public int getSum(int a, int b) {
23-
if (b == 0) return a;
24-
25-
while (b != 0) {
26-
int carry = a & b;
27-
a = a ^ b;
28-
b = carry << 1;
29-
}
16+
/**
17+
* For example, a = 0001, b = 0011.
18+
* First, we can use "and"("&") operation between a and b to find a carry.
19+
* carry = a & b, then carry = 0001
20+
* Second, we can use "xor" ("^") operation between a and b to find the different bit, and assign it to a.
21+
* Then, we shift carry one position left and assign it to b, b = 0010.
22+
* Iterate until there is no carry (or b == 0)
23+
*/
24+
public int getSum(int a, int b) {
25+
if (b == 0) return a;
3026

31-
return a;
27+
while (b != 0) {
28+
int carry = a & b;
29+
a = a ^ b;
30+
b = carry << 1;
3231
}
3332

34-
public int getSumRecursive(int a, int b) {
35-
if (b == 0) return a;
36-
return getSumRecursive(a ^ b, (a & b) << 1);
37-
}
33+
return a;
34+
}
35+
36+
public int getSumRecursive(int a, int b) {
37+
if (b == 0) return a;
38+
return getSumRecursive(a ^ b, (a & b) << 1);
39+
}
3840

3941
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.freetymekiyan.algorithms.level.hard;
2+
3+
import java.util.TreeSet;
4+
5+
/**
6+
* 363. Max Sum of Rectangle No Larger Than K
7+
* <p>
8+
* Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix such that its sum
9+
* is no larger than k.
10+
* <p>
11+
* Example:
12+
* <p>
13+
* Input: matrix = [[1,0,1],[0,-2,3]], k = 2
14+
* Output: 2
15+
* Explanation: Because the sum of rectangle [[0, 1], [-2, 3]] is 2,
16+
* and 2 is the max number no larger than k (k = 2).
17+
* Note:
18+
* <p>
19+
* The rectangle inside the matrix must have an area > 0.
20+
* What if the number of rows is much larger than the number of columns?
21+
* <p>
22+
* Companies: Google, Facebook
23+
* <p>
24+
* Related Topics: Binary Search, Dynamic Programming, Queue
25+
*/
26+
public class MaxSumOfRectangleNoLargerThanK {
27+
28+
public int maxSumSubmatrix(int[][] matrix, int target) {
29+
int row = matrix.length;
30+
if (row == 0) return 0;
31+
int col = matrix[0].length;
32+
int m = Math.min(row, col);
33+
int n = Math.max(row, col);
34+
//indicating sum up in every row or every column
35+
boolean colIsBig = col > row;
36+
int res = Integer.MIN_VALUE;
37+
for (int i = 0; i < m; i++) {
38+
int[] array = new int[n];
39+
// sum from row j to row i
40+
for (int j = i; j >= 0; j--) {
41+
int val = 0;
42+
TreeSet<Integer> set = new TreeSet<Integer>();
43+
set.add(0);
44+
//traverse every column/row and sum up
45+
for (int k = 0; k < n; k++) {
46+
array[k] = array[k] + (colIsBig ? matrix[j][k] : matrix[k][j]);
47+
val = val + array[k];
48+
//use TreeMap to binary search previous sum to get possible result
49+
Integer subres = set.ceiling(val - target);
50+
if (null != subres) {
51+
res = Math.max(res, val - subres);
52+
}
53+
set.add(val);
54+
}
55+
}
56+
}
57+
return res;
58+
}
59+
}

src/main/java/com/freetymekiyan/algorithms/level/medium/BombEnemy.java

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -23,57 +23,57 @@
2323
*/
2424
public class BombEnemy {
2525

26-
private static final char WALL = 'W';
27-
private static final char ENEMY = 'E';
28-
private static final char EMPTY = '0';
26+
private static final char WALL = 'W';
27+
private static final char ENEMY = 'E';
28+
private static final char EMPTY = '0';
2929

30-
/**
31-
* DP.
32-
* Avoid duplicate searching for number of enemies on the cell's left and top.
33-
* Since they will be already traversed.
34-
* So maintain an integer of number of enemy hits of current row, rowHits.
35-
* Maintain an array of integers of numbers of enemy hits of each column, colHits of size grid[0].length.
36-
* Recurrence Relation:
37-
* rowHits = from this cell to the end of row or WALL. Re-calculate when j = 0 or left cell is a 'W'.
38-
* colHits = from this cell to the bottom of column or WALL. Re-calculate when i = 0 or top cell is a 'W'.
39-
* When the cell is 'E' (empty), we can place a bomb.
40-
* Update the max with rowHits + colHits[j] if bigger.
41-
*/
42-
public int maxKilledEnemies(char[][] grid) {
43-
if (grid == null) {
44-
return 0;
30+
/**
31+
* DP.
32+
* Avoid duplicate searching for number of enemies on the cell's left and top.
33+
* Since they will be already traversed.
34+
* So maintain an integer of number of enemy hits of current row, rowHits.
35+
* Maintain an array of integers of numbers of enemy hits of each column, colHits of size grid[0].length.
36+
* Recurrence Relation:
37+
* rowHits = from this cell to the end of row or WALL. Re-calculate when j = 0 or left cell is a 'W'.
38+
* colHits = from this cell to the bottom of column or WALL. Re-calculate when i = 0 or top cell is a 'W'.
39+
* When the cell is 'E' (empty), we can place a bomb.
40+
* Update the max with rowHits + colHits[j] if bigger.
41+
*/
42+
public int maxKilledEnemies(char[][] grid) {
43+
if (grid == null) {
44+
return 0;
45+
}
46+
int m = grid.length;
47+
int n = m == 0 ? 0 : grid[0].length;
48+
int maxEnemies = 0;
49+
int rowHits = 0;
50+
int[] colHits = new int[n];
51+
for (int i = 0; i < m; i++) {
52+
for (int j = 0; j < n; j++) {
53+
if (grid[i][j] == WALL) { // Note that WALL can be skipped.
54+
continue;
55+
}
56+
if (j == 0 || grid[i][j - 1] == WALL) {
57+
rowHits = 0;
58+
for (int k = j; k < n && grid[i][k] != WALL; k++) {
59+
if (grid[i][k] == ENEMY) {
60+
rowHits++;
61+
}
62+
}
4563
}
46-
int m = grid.length;
47-
int n = m == 0 ? 0 : grid[0].length;
48-
int maxEnemies = 0;
49-
int rowHits = 0;
50-
int[] colHits = new int[n];
51-
for (int i = 0; i < m; i++) {
52-
for (int j = 0; j < n; j++) {
53-
if (grid[i][j] == WALL) { // Note that WALL can be skipped.
54-
continue;
55-
}
56-
if (j == 0 || grid[i][j - 1] == WALL) {
57-
rowHits = 0;
58-
for (int k = j; k < n && grid[i][k] != WALL; k++) {
59-
if (grid[i][k] == ENEMY) {
60-
rowHits++;
61-
}
62-
}
63-
}
64-
if (i == 0 || grid[i - 1][j] == WALL) {
65-
colHits[j] = 0;
66-
for (int k = i; k < m && grid[k][j] != WALL; k++) {
67-
if (grid[k][j] == ENEMY) {
68-
colHits[j]++;
69-
}
70-
}
71-
}
72-
if (grid[i][j] == EMPTY) { // Only update when the cell is empty.
73-
maxEnemies = Integer.max(rowHits + colHits[j], maxEnemies);
74-
}
64+
if (i == 0 || grid[i - 1][j] == WALL) {
65+
colHits[j] = 0;
66+
for (int k = i; k < m && grid[k][j] != WALL; k++) {
67+
if (grid[k][j] == ENEMY) {
68+
colHits[j]++;
7569
}
70+
}
71+
}
72+
if (grid[i][j] == EMPTY) { // Only update when the cell is empty.
73+
maxEnemies = Integer.max(rowHits + colHits[j], maxEnemies);
7674
}
77-
return maxEnemies;
75+
}
7876
}
77+
return maxEnemies;
78+
}
7979
}

src/main/java/com/freetymekiyan/algorithms/level/medium/CombinationSum4.java

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -40,50 +40,50 @@
4040
*/
4141
public class CombinationSum4 {
4242

43-
/**
44-
* DP, Bottom-up. O(n^2) Time, O(n) Space.
45-
* State: S[i] means the # of combinations that can reach sum i.
46-
* Recurrent relation:
47-
* S[i] = sum(S[i - nums[j]]), where 0 <= j < nums.length, and target >= nums[j].
48-
* Base case:
49-
* S[0] = 1. Think about [1], 1, where S[1] = S[1 - 1] = S[0] = 1.
50-
*/
51-
public int combinationSum4(int[] nums, int target) {
52-
int[] comb = new int[target + 1];
53-
comb[0] = 1;
54-
for (int i = 1; i < comb.length; i++) {
55-
for (int j = 0; j < nums.length; j++) {
56-
if (i - nums[j] >= 0) { // Array's not sorted. Need to check each number.
57-
comb[i] += comb[i - nums[j]];
58-
}
59-
}
43+
/**
44+
* DP, Bottom-up. O(n^2) Time, O(n) Space.
45+
* State: S[i] means the # of combinations that can reach sum i.
46+
* Recurrent relation:
47+
* S[i] = sum(S[i - nums[j]]), where 0 <= j < nums.length, and target >= nums[j].
48+
* Base case:
49+
* S[0] = 1. Think about [1], 1, where S[1] = S[1 - 1] = S[0] = 1.
50+
*/
51+
public int combinationSum4(int[] nums, int target) {
52+
int[] comb = new int[target + 1];
53+
comb[0] = 1;
54+
for (int i = 1; i < comb.length; i++) {
55+
for (int j = 0; j < nums.length; j++) {
56+
if (i - nums[j] >= 0) { // Array's not sorted. Need to check each number.
57+
comb[i] += comb[i - nums[j]];
6058
}
61-
return comb[target];
59+
}
6260
}
61+
return comb[target];
62+
}
6363

64-
/**
65-
* DP, Top-down, Memoization.
66-
*/
67-
public int combinationSum4TopDown(int[] nums, int target) {
68-
int[] dp = new int[target + 1];
69-
Arrays.fill(dp, -1);
70-
return helper(nums, target, dp);
71-
}
64+
/**
65+
* DP, Top-down, Memoization.
66+
*/
67+
public int combinationSum4TopDown(int[] nums, int target) {
68+
int[] dp = new int[target + 1];
69+
Arrays.fill(dp, -1);
70+
return helper(nums, target, dp);
71+
}
7272

73-
private int helper(int[] nums, int target, int[] dp) {
74-
if (target == 0) {
75-
return 1;
76-
}
77-
if (dp[target] != -1) {
78-
return dp[target];
79-
}
80-
int res = 0;
81-
for (int i = 0; i < nums.length; i++) {
82-
if (target >= nums[i]) {
83-
res += helper(nums, target - nums[i], dp);
84-
}
85-
}
86-
dp[target] = res;
87-
return res;
73+
private int helper(int[] nums, int target, int[] dp) {
74+
if (target == 0) {
75+
return 1;
76+
}
77+
if (dp[target] != -1) {
78+
return dp[target];
79+
}
80+
int res = 0;
81+
for (int i = 0; i < nums.length; i++) {
82+
if (target >= nums[i]) {
83+
res += helper(nums, target - nums[i], dp);
84+
}
8885
}
86+
dp[target] = res;
87+
return res;
88+
}
8989
}

0 commit comments

Comments
 (0)