Skip to content

Commit 0e9deb9

Browse files
committed
practice
1 parent 07f4c5b commit 0e9deb9

12 files changed

+474
-94
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package problems.leetcode;
2+
3+
public class BitShifts {
4+
public static void main(String[] args) {
5+
6+
// signed left shift:
7+
// - a << b
8+
// - shift bits of a by b times and put 0 to the empty space in the right bits
9+
// - equivalent to multiplication by 2^b
10+
{
11+
System.out.println("Signed left shift");
12+
int x = 12;
13+
x = x << 3;
14+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
15+
x = -3;
16+
x = x << 2;
17+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
18+
x = Integer.MIN_VALUE / 2; // 11000000000000000000000000000000
19+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
20+
x = x << 1; // Integer.MIN_VALUE -2147483648 which is 10000000000000000000000000000000
21+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
22+
x = x << 1; // 0 which is 00000000000000000000000000000000
23+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
24+
x = Integer.MAX_VALUE; // 01111111111111111111111111111111
25+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
26+
x = x << 1; // -2 which is 11111111111111111111111111111110
27+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
28+
x = 1;
29+
x = x << 30; // 1000000000000000000000000000000
30+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
31+
x = x << 1; // -2147483648 which is -2147483648
32+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
33+
}
34+
35+
// signed right shift:
36+
// - a >> b
37+
// - shift a's bits to right by b times.
38+
// - the left bits are filled with the value of the leftmost sign bit,
39+
// which is 1 if a is negative, or filled with 0 if a is positive.
40+
{
41+
System.out.println("Signed right shift");
42+
int x = 12;
43+
x = x >> 2;
44+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
45+
x = -12;
46+
x = x >> 2;
47+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
48+
x = Integer.MIN_VALUE;
49+
x = x >> 2;
50+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
51+
x = -1;
52+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
53+
x = x >> 2; // still -1
54+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
55+
}
56+
57+
// unsigned right shift:
58+
// a >>> b
59+
// shift a's bits to right by b times, fill the left bits with 0 irrespective of the leftmost sign bit.
60+
{
61+
System.out.println("Unsigned right shift");
62+
int x = 12;
63+
x = x >>> 2; // 3
64+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
65+
x = -1; // 11111111111111111111111111111111
66+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
67+
x = x >>> 1; // Integer.MAX_VALUE which is 01111111111111111111111111111111
68+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
69+
x = -4; // 11111111111111111111111111111100
70+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
71+
x = x >>> 1; // Integer.MAX_VALUE - 1 which is 01111111111111111111111111111110
72+
System.out.println("x=" + x + ", binary x=" + Integer.toBinaryString(x));
73+
}
74+
75+
{
76+
byte x = 5;
77+
x = (byte) (x << 1); // cast is needed since (x << 1) returns an int
78+
}
79+
80+
{
81+
long x = Integer.MAX_VALUE;
82+
System.out.println("x=" + x + ", binary x=" + Long.toBinaryString(x));
83+
x = x << 1;
84+
System.out.println("x=" + x + ", binary x=" + Long.toBinaryString(x));
85+
}
86+
87+
}
88+
}

src/problems/leetcode/DivideTwoIntegers.java

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,40 @@
55
*/
66
public class DivideTwoIntegers {
77

8+
public static void main(String[] args) {
9+
System.out.println(divide(2147483647, -2147483648));
10+
System.out.println(divide(-2147483648, -1));
11+
System.out.println(divide(-2147483648, -2147483648));
12+
13+
// -2147483648 / -1 = 2147483648 which is greater than 2^32 - 1
14+
}
15+
16+
// Note: Assume we are dealing with an environment that could only store
17+
// integers within the 32-bit signed integer range: [−2^31, 2^31 − 1].
18+
// For this problem, if the quotient is strictly greater than 2^31 - 1,
19+
// then return 2^31 - 1, and if the quotient is strictly less than -2^31,
20+
// then return -2^31.
21+
22+
// runtime: O(lgN)
23+
// space: O(1)
824
public static int divide(int dividend, int divisor) {
25+
if (dividend == Integer.MIN_VALUE && divisor == -1) {
26+
return Integer.MAX_VALUE;
27+
}
28+
29+
int divid = Math.abs(dividend), divis = Math.abs(divisor), res = 0;
30+
while (divid - divis >= 0) {
31+
int x = 0; // 1, 2, 4, 8
32+
for (; divid - (divis << x << 1) >= 0; x++) {
33+
}
34+
res += 1 << x;
35+
divid -= divis << x;
36+
}
37+
38+
return (dividend > 0) == (divisor > 0) ? res : -res;
39+
}
40+
41+
public static int divideWith64BitInteger(int dividend, int divisor) {
942
long divid = dividend, divis = divisor, quot = 0;
1043
divid = Math.abs(divid);
1144
divis = Math.abs(divis);
@@ -29,10 +62,4 @@ public static int divide(int dividend, int divisor) {
2962
return (int) quot;
3063
}
3164

32-
public static void main(String[] args) {
33-
int dividend = 300;
34-
int divisor = 5;
35-
System.out.println(divide(dividend, divisor));
36-
}
37-
3865
}

src/problems/leetcode/FindFirstAndLastPositionOfElementInSortedArray.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,42 @@
88
public class FindFirstAndLastPositionOfElementInSortedArray {
99

1010
public static int[] searchRange(int[] nums, int target) {
11+
if (nums == null || nums.length < 1) {
12+
return new int[]{-1, -1};
13+
}
14+
15+
// find first index of target
16+
int first = -1;
17+
int l = 0, r = nums.length - 1;
18+
while (l <= r) {
19+
int m = (l + r) / 2;
20+
if (nums[m] < target) {
21+
l = m + 1;
22+
} else {
23+
r = m - 1;
24+
}
25+
}
26+
27+
if (l >= nums.length || nums[l] != target) {
28+
return new int[]{-1, -1};
29+
}
30+
31+
first = l;
32+
// find last index of target
33+
r = nums.length - 1;
34+
while (l <= r) {
35+
int m = (l + r) / 2;
36+
if (nums[m] > target) {
37+
r = m - 1;
38+
} else {
39+
l = m + 1;
40+
}
41+
}
42+
43+
return new int[]{first, r};
44+
}
45+
46+
public static int[] searchRange2(int[] nums, int target) {
1147
int startIndex = firstInsertionIndex(nums, target);
1248

1349
// assert that `startIndex` is within the array bounds and that `target`
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package problems.leetcode;
2+
3+
// https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/editorial/
4+
public class FindTheIndexOfTheFirstOccurrenceInAString {
5+
6+
// runtime: O(N*M) where N is len of haystack and M is len of needle
7+
// space: O(1)
8+
public int strStr(String haystack, String needle) {
9+
// haystack = "sazbutsad", needle = "sad"
10+
// "sazbutsad"
11+
// i
12+
// k
13+
// j
14+
// k
15+
// j
16+
//
17+
// k
18+
// j
19+
// i
20+
21+
for (int i = 0; i < haystack.length(); i++) {
22+
boolean match = true;
23+
for (int j = 0; j < needle.length(); j++) {
24+
if (i + j >= haystack.length() || haystack.charAt(i + j) != needle.charAt(j)) {
25+
match = false;
26+
break;
27+
}
28+
}
29+
if (match) {
30+
return i;
31+
}
32+
}
33+
34+
return -1;
35+
}
36+
37+
}

src/problems/leetcode/LongestValidParentheses.java

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,49 @@ public class LongestValidParentheses {
1212
public static void main(String[] args) {
1313
// String s = "(((()())";
1414
// String s = "()(()";
15-
String s = ")(((((()())()()))()(()))(";
16-
System.out.println(longestValidParentheses(s));
15+
// String s = ")(((((()())()()))()(()))(";
16+
String s = "(()(((()";
17+
System.out.println(longestValidParenthesesStack(s));
1718
System.out.println(longestValidParenthesesDP(s));
1819
}
1920

21+
// runtime: O(N)
22+
// space: O(N)
2023
public static int longestValidParenthesesDP(String s) {
24+
// ( ( ) ( ) )
25+
// dp: 0, 0, 0, 0, 0, 0
26+
// i = 0
27+
// i = 1
28+
// i = 2
29+
// dp: 0, 0, 2, 0, 0, 0
30+
// i = 3
31+
// i = 4
32+
// dp: 0, 0, 2, 0, 2, 0
33+
// dp: 0, 0, 2, 0, 4, 0
34+
// i = 5
35+
// dp: 0, 0, 2, 0, 4, 6
36+
2137
int maxLen = 0;
38+
// i'th element represents the length of the longest valid substring ending at i'th index.
2239
int[] dp = new int[s.length()];
2340
for (int i = 1; i < s.length(); i++) {
2441
if (s.charAt(i) == '(') {
2542
continue;
26-
}
27-
28-
if (s.charAt(i - 1) == '(') {
43+
} else if (s.charAt(i - 1) == '(') {
44+
// here we finished a valid pair
2945
dp[i] = 2;
3046
if (i >= 2) {
47+
// if there was a valid pair at i - 2, take it into account
3148
dp[i] += dp[i - 2];
3249
}
3350
} else if (i - dp[i - 1] > 0 && s.charAt(i - dp[i - 1] - 1) == '(') {
51+
// (()()) <-
3452
dp[i] = dp[i - 1] + 2;
3553
if ((i - dp[i - 1]) >= 2) {
54+
// ()(()()) <-
55+
// 0200204
56+
// i=7
57+
// 02002048
3658
dp[i] += dp[i - dp[i - 1] - 2];
3759
}
3860
}
@@ -43,7 +65,66 @@ public static int longestValidParenthesesDP(String s) {
4365
return maxLen;
4466
}
4567

46-
public static int longestValidParentheses(String s) {
68+
// runtime: O(N)
69+
// space: O(N)
70+
public static int longestValidParenthesesStack(String s) {
71+
if (s == null || s.length() < 2) {
72+
return 0;
73+
}
74+
75+
Deque<Integer> stack = new ArrayDeque<>();
76+
int longest = 0;
77+
stack.addLast(-1);
78+
for (int i = 0; i < s.length(); i++) {
79+
if (s.charAt(i) == '(') {
80+
stack.addLast(i);
81+
} else {
82+
stack.removeLast();
83+
if (stack.isEmpty()) {
84+
stack.addLast(i);
85+
} else {
86+
longest = Math.max(longest, i - stack.peekLast());
87+
}
88+
}
89+
}
90+
91+
return longest;
92+
}
93+
94+
// runtime: O(N)
95+
// space: O(N)
96+
public static int longestValidParenthesesStack2(String s) {
97+
// "(()(((()"
98+
// stack:
99+
// i = 0
100+
// open = 1
101+
// stack = (
102+
// i = 1
103+
// open = 2
104+
// stack = ((
105+
// i = 2
106+
// open = 1
107+
// stack = (()
108+
// i = 3
109+
// open = 2
110+
// stack = (()(
111+
// i = 4
112+
// open = 3
113+
// stack = (()((
114+
// i = 5
115+
// open = 4
116+
// stack = (()(((
117+
// i = 6
118+
// open = 5
119+
// stack = (()((((
120+
// i = 7
121+
// open = 4
122+
// stack = (()(((
123+
124+
if (s == null || s.length() < 2) {
125+
return 0;
126+
}
127+
47128
Deque<Character> stack = new ArrayDeque<>();
48129
int maxLen = 0, open = 0;
49130
for (int i = 0; i < s.length(); i++) {

src/problems/leetcode/NextPermutation.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,25 @@ public static void main(String[] args) {
6565
System.out.println(Arrays.toString(nums));
6666
}
6767

68+
// runtime: O(N)
69+
// space: O(1)
6870
public static void nextPermutation(int[] nums) {
69-
/*
70-
71-
Starting from right, we need to find the first pair of two successive
72-
nums[i] and nums[i−1] where nums[i] > nums[i-1]. Now, no rearrangements
73-
to the right of nums[i-1] can create a larger permutation.
74-
75-
*/
71+
// intuition:
72+
// find the right-most number where it is greater than on its left
73+
// swap them then reverse the right side
7674

75+
// Starting from right, we need to find the first pair of two successive
76+
// nums[i] and nums[i−1] where nums[i] > nums[i-1]. Now, no rearrangements
77+
// to the right of nums[i-1] can create a larger permutation.
7778
int len = nums.length, i = len - 2;
7879
while (i >= 0 && nums[i] >= nums[i + 1]) {
7980
i--;
8081
}
8182

8283
if (i >= 0) {
8384
// find the first index j such that nums[j] > nums[i]
85+
// in other words, find the index of the first number greater than
86+
// nums[i] and on the right of index = i
8487
int j = len - 1;
8588
while (j >= i && nums[j] <= nums[i]) {
8689
j--;
@@ -92,12 +95,10 @@ public static void nextPermutation(int[] nums) {
9295
reverse(nums, i + 1);
9396
}
9497

95-
private static void reverse(int[] nums, int start) {
96-
int i = start, j = nums.length - 1;
98+
private static void reverse(int[] nums, int i) {
99+
int j = nums.length - 1;
97100
while (i < j) {
98-
swap(nums, i, j);
99-
i++;
100-
j--;
101+
swap(nums, i++, j--);
101102
}
102103
}
103104

0 commit comments

Comments
 (0)