├── .vscode └── settings.json ├── Chapter 1 ├── Problem1.java ├── Problem10.java ├── Problem100.java ├── Problem11.java ├── Problem12.java ├── Problem13.java ├── Problem14.java ├── Problem15.java ├── Problem16.java ├── Problem17.java ├── Problem18.java ├── Problem19.java ├── Problem2.java ├── Problem20.java ├── Problem21.java ├── Problem22.java ├── Problem23.java ├── Problem24.java ├── Problem25.java ├── Problem26.java ├── Problem27.java ├── Problem29.java ├── Problem3.java ├── Problem30.java ├── Problem31.java ├── Problem32.java ├── Problem33.java ├── Problem34.java ├── Problem35.java ├── Problem36.java ├── Problem37.java ├── Problem38.java ├── Problem39.java ├── Problem4.java ├── Problem40.java ├── Problem41.java ├── Problem42.java ├── Problem43.java ├── Problem44.java ├── Problem45.java ├── Problem46.java ├── Problem47.java ├── Problem48.java ├── Problem49.java ├── Problem5.java ├── Problem50.java ├── Problem51.java ├── Problem52.java ├── Problem53.java ├── Problem54.java ├── Problem55.java ├── Problem56.java ├── Problem57.java ├── Problem58.java ├── Problem59.java ├── Problem6.java ├── Problem60.java ├── Problem61.java ├── Problem62.java ├── Problem63.java ├── Problem64.java ├── Problem65.java ├── Problem66.java ├── Problem67.java ├── Problem68.java ├── Problem7.java ├── Problem70.java ├── Problem71.java ├── Problem72.java ├── Problem73.java ├── Problem74.java ├── Problem75.java ├── Problem76.java ├── Problem77.java ├── Problem78.java ├── Problem79.java ├── Problem80.java ├── Problem81.java ├── Problem82.java ├── Problem83.java ├── Problem84.java ├── Problem85.java ├── Problem86.java ├── Problem87.java ├── Problem88.java ├── Problem89.java ├── Problem9.java ├── Problem90.java ├── Problem91.java ├── Problem92.java ├── Problem93.java ├── Problem94.java ├── Problem95.java ├── Problem96.java ├── Problem97.java ├── Problem98.java └── Problem99.java └── Chapter 2 ├── Problem101.java ├── Problem102.java ├── Problem103.java ├── Problem104.java ├── Problem105.java ├── Problem106.java ├── Problem107.java ├── Problem108.java ├── Problem109.java ├── Problem110.java ├── Problem111.java ├── Problem112.java ├── Problem113.java ├── Problem114.java ├── Problem115.java ├── Problem116.java ├── Problem117.java ├── Problem118.java ├── Problem119.java ├── Problem120.java ├── Problem121.java ├── Problem122.java ├── Problem123.java ├── Problem124.java ├── Problem125.java ├── Problem126.java ├── Problem127.java ├── Problem128.java ├── Problem129.java ├── Problem130.java ├── Problem131.java ├── Problem132.java ├── Problem133.java ├── Problem134.java ├── Problem135.java ├── Problem136.java ├── Problem137.java ├── Problem138.java ├── Problem139.java ├── Problem140.java ├── Problem141.java ├── Problem142.java ├── Problem143.java ├── Problem144.java ├── Problem145.java ├── Problem146.java ├── Problem147.java ├── Problem148.java ├── Problem149.java ├── Problem150.java ├── Problem151.java ├── Problem152.java ├── Problem153.java ├── Problem154.java ├── Problem155.java └── Problem156.java /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": ["strs"] 3 | } 4 | -------------------------------------------------------------------------------- /Chapter 1/Problem1.java: -------------------------------------------------------------------------------- 1 | import java.util.Map; 2 | import java.util.HashMap; 3 | 4 | public class Problem1 { 5 | public static void main(String[] args) { 6 | Solution solution = new Solution(); 7 | int[] nums = { 2, 7, 11, 15 }; 8 | int target = 9; 9 | int[] result = solution.twoSum(nums, target); 10 | System.out.println("Indices: " + result[0] + ", " + result[1]); 11 | } 12 | } 13 | 14 | class Solution { 15 | public int[] twoSum(int[] nums, int target) { 16 | Map m = new HashMap<>(); 17 | for (int i = 0;; ++i) { 18 | int x = nums[i]; 19 | int y = target - x; 20 | if (m.containsKey(y)) { 21 | return new int[] { m.get(y), i }; 22 | } 23 | m.put(x, i); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter 1/Problem10.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem10 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String s = "aab"; 6 | String p = "c*a*b"; 7 | boolean result = solution.isMatch(s, p); 8 | System.out.println("Is match: " + result); 9 | } 10 | } 11 | 12 | class Solution { 13 | public boolean isMatch(String s, String p) { 14 | int m = s.length(), n = p.length(); 15 | boolean[][] f = new boolean[m + 1][n + 1]; 16 | f[0][0] = true; 17 | for (int i = 0; i <= m; ++i) { 18 | for (int j = 1; j <= n; ++j) { 19 | if (p.charAt(j - 1) == '*') { 20 | f[i][j] = f[i][j - 2]; 21 | if (i > 0 && (p.charAt(j - 2) == '.' || p.charAt(j - 2) == s.charAt(i - 1))) { 22 | f[i][j] |= f[i - 1][j]; 23 | } 24 | } else if (i > 0 25 | && (p.charAt(j - 1) == '.' || p.charAt(j - 1) == s.charAt(i - 1))) { 26 | f[i][j] = f[i - 1][j - 1]; 27 | } 28 | } 29 | } 30 | return f[m][n]; 31 | } 32 | } -------------------------------------------------------------------------------- /Chapter 1/Problem100.java: -------------------------------------------------------------------------------- 1 | public class Problem100 { 2 | public static void main(String[] args) { 3 | TreeNode p = new TreeNode(1, new TreeNode(2), new TreeNode(3)); 4 | TreeNode q = new TreeNode(1, new TreeNode(2), new TreeNode(3)); 5 | Solution solution = new Solution(); 6 | boolean result = solution.isSameTree(p, q); 7 | System.out.println("Is Same Tree: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | public boolean isSameTree(TreeNode p, TreeNode q) { 13 | if (p == q) 14 | return true; 15 | if (p == null || q == null || p.val != q.val) 16 | return false; 17 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 18 | } 19 | } -------------------------------------------------------------------------------- /Chapter 1/Problem11.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem11 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] height = { 1, 8, 6, 2, 5, 4, 8, 3, 7 }; 6 | int result = solution.maxArea(height); 7 | System.out.println("Max area: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | public int maxArea(int[] height) { 13 | int i = 0, j = height.length - 1; 14 | int ans = 0; 15 | while (i < j) { 16 | int t = Math.min(height[i], height[j]) * (j - i); 17 | ans = Math.max(ans, t); 18 | if (height[i] < height[j]) { 19 | ++i; 20 | } else { 21 | --j; 22 | } 23 | } 24 | return ans; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter 1/Problem12.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.List; 3 | 4 | public class Problem12 { 5 | public static void main(String[] args) { 6 | Solution solution = new Solution(); 7 | int num = 1994; 8 | String result = solution.intToRoman(num); 9 | System.out.println("Roman numeral: " + result); 10 | } 11 | } 12 | 13 | class Solution { 14 | public String intToRoman(int num) { 15 | List cs = List.of("M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"); 16 | List vs = List.of(1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1); 17 | StringBuilder ans = new StringBuilder(); 18 | for (int i = 0, n = cs.size(); i < n; ++i) { 19 | while (num >= vs.get(i)) { 20 | num -= vs.get(i); 21 | ans.append(cs.get(i)); 22 | } 23 | } 24 | return ans.toString(); 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter 1/Problem13.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.Map; 3 | import java.util.HashMap; 4 | 5 | public class Problem13 { 6 | public static void main(String[] args) { 7 | Solution solution = new Solution(); 8 | String s = "MCMXCIV"; 9 | int result = solution.romanToInt(s); 10 | System.out.println("Roman to Integer: " + result); 11 | } 12 | } 13 | 14 | class Solution { 15 | public int romanToInt(String s) { 16 | String cs = "IVXLCDM"; 17 | int[] vs = { 1, 5, 10, 50, 100, 500, 1000 }; 18 | Map d = new HashMap<>(); 19 | for (int i = 0; i < vs.length; ++i) { 20 | d.put(cs.charAt(i), vs[i]); 21 | } 22 | int n = s.length(); 23 | int ans = d.get(s.charAt(n - 1)); 24 | for (int i = 0; i < n - 1; ++i) { 25 | int sign = d.get(s.charAt(i)) < d.get(s.charAt(i + 1)) ? -1 : 1; 26 | ans += sign * d.get(s.charAt(i)); 27 | } 28 | return ans; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter 1/Problem14.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem14 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String[] strs = { "flower", "flow", "flight" }; 6 | String result = solution.longestCommonPrefix(strs); 7 | System.out.println("Longest common prefix: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | public String longestCommonPrefix(String[] strs) { 13 | int n = strs.length; 14 | for (int i = 0; i < strs[0].length(); ++i) { 15 | for (int j = 1; j < n; ++j) { 16 | if (strs[j].length() <= i || strs[j].charAt(i) != strs[0].charAt(i)) { 17 | return strs[0].substring(0, i); 18 | } 19 | } 20 | } 21 | return strs[0]; 22 | } 23 | } -------------------------------------------------------------------------------- /Chapter 1/Problem15.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.ArrayList; 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class Problem15 { 7 | public static void main(String[] args) { 8 | Solution solution = new Solution(); 9 | int[] nums = { -1, 0, 1, 2, -1, -4 }; 10 | List> result = solution.threeSum(nums); 11 | System.out.println("Three Sum: " + result); 12 | } 13 | } 14 | 15 | class Solution { 16 | public List> threeSum(int[] nums) { 17 | Arrays.sort(nums); 18 | List> ans = new ArrayList<>(); 19 | int n = nums.length; 20 | for (int i = 0; i < n - 2 && nums[i] <= 0; ++i) { 21 | if (i > 0 && nums[i] == nums[i - 1]) { 22 | continue; 23 | } 24 | int j = i + 1, k = n - 1; 25 | while (j < k) { 26 | int x = nums[i] + nums[j] + nums[k]; 27 | if (x < 0) { 28 | ++j; 29 | } else if (x > 0) { 30 | --k; 31 | } else { 32 | ans.add(List.of(nums[i], nums[j++], nums[k--])); 33 | while (j < k && nums[j] == nums[j - 1]) { 34 | ++j; 35 | } 36 | while (j < k && nums[k] == nums[k + 1]) { 37 | --k; 38 | } 39 | } 40 | } 41 | } 42 | return ans; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Chapter 1/Problem16.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.Arrays; 3 | 4 | public class Problem16 { 5 | public static void main(String[] args) { 6 | Solution solution = new Solution(); 7 | int[] nums = { -1, 2, 1, -4 }; 8 | int target = 1; 9 | int result = solution.threeSumClosest(nums, target); 10 | System.out.println("Three Sum Closest: " + result); 11 | } 12 | } 13 | 14 | class Solution { 15 | public int threeSumClosest(int[] nums, int target) { 16 | Arrays.sort(nums); 17 | int ans = 1 << 30; 18 | int n = nums.length; 19 | for (int i = 0; i < n; ++i) { 20 | int j = i + 1, k = n - 1; 21 | while (j < k) { 22 | int t = nums[i] + nums[j] + nums[k]; 23 | if (t == target) { 24 | return t; 25 | } 26 | if (Math.abs(t - target) < Math.abs(ans - target)) { 27 | ans = t; 28 | } 29 | if (t > target) { 30 | --k; 31 | } else { 32 | ++j; 33 | } 34 | } 35 | } 36 | return ans; 37 | } 38 | } -------------------------------------------------------------------------------- /Chapter 1/Problem17.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.List; 3 | import java.util.ArrayList; 4 | 5 | public class Problem17 { 6 | public static void main(String[] args) { 7 | Solution solution = new Solution(); 8 | String digits = "23"; 9 | List result = solution.letterCombinations(digits); 10 | System.out.println("Letter Combinations: " + result); 11 | } 12 | } 13 | 14 | class Solution { 15 | public List letterCombinations(String digits) { 16 | List ans = new ArrayList<>(); 17 | if (digits.length() == 0) { 18 | return ans; 19 | } 20 | ans.add(""); 21 | String[] d = new String[] { "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; 22 | for (char i : digits.toCharArray()) { 23 | String s = d[i - '2']; 24 | List t = new ArrayList<>(); 25 | for (String a : ans) { 26 | for (String b : s.split("")) { 27 | t.add(a + b); 28 | } 29 | } 30 | ans = t; 31 | } 32 | return ans; 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter 1/Problem18.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.ArrayList; 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class Problem18 { 7 | public static void main(String[] args) { 8 | Solution solution = new Solution(); 9 | int[] nums = { 1, 0, -1, 0, -2, 2 }; 10 | int target = 0; 11 | List> result = solution.fourSum(nums, target); 12 | System.out.println("Four Sum: " + result); 13 | } 14 | } 15 | 16 | class Solution { 17 | public List> fourSum(int[] nums, int target) { 18 | int n = nums.length; 19 | List> ans = new ArrayList<>(); 20 | if (n < 4) { 21 | return ans; 22 | } 23 | Arrays.sort(nums); 24 | for (int i = 0; i < n - 3; ++i) { 25 | if (i > 0 && nums[i] == nums[i - 1]) { 26 | continue; 27 | } 28 | for (int j = i + 1; j < n - 2; ++j) { 29 | if (j > i + 1 && nums[j] == nums[j - 1]) { 30 | continue; 31 | } 32 | int k = j + 1, l = n - 1; 33 | while (k < l) { 34 | long x = (long) nums[i] + nums[j] + nums[k] + nums[l]; 35 | if (x < target) { 36 | ++k; 37 | } else if (x > target) { 38 | --l; 39 | } else { 40 | ans.add(List.of(nums[i], nums[j], nums[k++], nums[l--])); 41 | while (k < l && nums[k] == nums[k - 1]) { 42 | ++k; 43 | } 44 | while (k < l && nums[l] == nums[l + 1]) { 45 | --l; 46 | } 47 | } 48 | } 49 | } 50 | } 51 | return ans; 52 | } 53 | } -------------------------------------------------------------------------------- /Chapter 1/Problem19.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem19 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | ListNode head = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5))))); 6 | int n = 2; 7 | ListNode result = solution.removeNthFromEnd(head, n); 8 | System.out.print("Result: "); 9 | while (result != null) { 10 | System.out.print(result.val + " "); 11 | result = result.next; 12 | } 13 | } 14 | } 15 | 16 | class Solution { 17 | public ListNode removeNthFromEnd(ListNode head, int n) { 18 | ListNode dummy = new ListNode(0, head); 19 | ListNode fast = dummy, slow = dummy; 20 | while (n-- > 0) { 21 | fast = fast.next; 22 | } 23 | while (fast.next != null) { 24 | slow = slow.next; 25 | fast = fast.next; 26 | } 27 | slow.next = slow.next.next; 28 | return dummy.next; 29 | } 30 | } 31 | 32 | class ListNode { 33 | int val; 34 | ListNode next; 35 | 36 | ListNode(int val) { 37 | this.val = val; 38 | } 39 | 40 | ListNode(int val, ListNode next) { 41 | this.val = val; 42 | this.next = next; 43 | } 44 | } -------------------------------------------------------------------------------- /Chapter 1/Problem2.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem2 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | ListNode l1 = new ListNode(2); 6 | l1.next = new ListNode(4); 7 | l1.next.next = new ListNode(3); 8 | ListNode l2 = new ListNode(5); 9 | l2.next = new ListNode(6); 10 | l2.next.next = new ListNode(4); 11 | ListNode result = solution.addTwoNumbers(l1, l2); 12 | while (result != null) { 13 | System.out.print(result.val + " "); 14 | result = result.next; 15 | } 16 | } 17 | } 18 | 19 | class ListNode { 20 | int val; 21 | ListNode next; 22 | 23 | ListNode(int val) { 24 | this.val = val; 25 | } 26 | } 27 | 28 | class Solution { 29 | public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 30 | ListNode dummy = new ListNode(0); 31 | int carry = 0; 32 | ListNode cur = dummy; 33 | while (l1 != null || l2 != null || carry != 0) { 34 | int s = (l1 == null ? 0 : l1.val) + (l2 == null ? 0 : l2.val) + carry; 35 | carry = s / 10; 36 | cur.next = new ListNode(s % 10); 37 | cur = cur.next; 38 | l1 = l1 == null ? null : l1.next; 39 | l2 = l2 == null ? null : l2.next; 40 | } 41 | return dummy.next; 42 | } 43 | } -------------------------------------------------------------------------------- /Chapter 1/Problem20.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.Deque; 3 | import java.util.ArrayDeque; 4 | 5 | public class Problem20 { 6 | public static void main(String[] args) { 7 | Solution solution = new Solution(); 8 | String s = "{[()]}"; 9 | boolean result = solution.isValid(s); 10 | System.out.println("Is valid: " + result); 11 | } 12 | } 13 | 14 | class Solution { 15 | public boolean isValid(String s) { 16 | Deque stk = new ArrayDeque<>(); 17 | for (char c : s.toCharArray()) { 18 | if (c == '(' || c == '{' || c == '[') { 19 | stk.push(c); 20 | } else if (stk.isEmpty() || !match(stk.pop(), c)) { 21 | return false; 22 | } 23 | } 24 | return stk.isEmpty(); 25 | } 26 | 27 | private boolean match(char l, char r) { 28 | return (l == '(' && r == ')') || (l == '{' && r == '}') || (l == '[' && r == ']'); 29 | } 30 | } -------------------------------------------------------------------------------- /Chapter 1/Problem21.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem21 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | ListNode list1 = new ListNode(1, new ListNode(2, new ListNode(4))); 6 | ListNode list2 = new ListNode(1, new ListNode(3, new ListNode(4))); 7 | ListNode result = solution.mergeTwoLists(list1, list2); 8 | while (result != null) { 9 | System.out.print(result.val + " "); 10 | result = result.next; 11 | } 12 | } 13 | } 14 | 15 | class Solution { 16 | public ListNode mergeTwoLists(ListNode list1, ListNode list2) { 17 | ListNode dummy = new ListNode(0); 18 | ListNode curr = dummy; 19 | while (list1 != null && list2 != null) { 20 | if (list1.val <= list2.val) { 21 | curr.next = list1; 22 | list1 = list1.next; 23 | } else { 24 | curr.next = list2; 25 | list2 = list2.next; 26 | } 27 | curr = curr.next; 28 | } 29 | curr.next = list1 == null ? list2 : list1; 30 | return dummy.next; 31 | } 32 | } 33 | 34 | class ListNode { 35 | int val; 36 | ListNode next; 37 | 38 | ListNode() { 39 | } 40 | 41 | ListNode(int val) { 42 | this.val = val; 43 | } 44 | 45 | ListNode(int val, ListNode next) { 46 | this.val = val; 47 | this.next = next; 48 | } 49 | } -------------------------------------------------------------------------------- /Chapter 1/Problem22.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.List; 3 | import java.util.ArrayList; 4 | 5 | public class Problem22 { 6 | public static void main(String[] args) { 7 | Solution solution = new Solution(); 8 | int n = 3; 9 | List result = solution.generateParenthesis(n); 10 | System.out.println("Generated Parentheses: " + result); 11 | } 12 | } 13 | 14 | class Solution { 15 | private List ans = new ArrayList<>(); 16 | private int n; 17 | 18 | public List generateParenthesis(int n) { 19 | this.n = n; 20 | dfs(0, 0, ""); 21 | return ans; 22 | } 23 | 24 | private void dfs(int l, int r, String t) { 25 | if (l > n || r > n || l < r) { 26 | return; 27 | } 28 | if (l == n && r == n) { 29 | ans.add(t); 30 | return; 31 | } 32 | dfs(l + 1, r, t + "("); 33 | dfs(l, r + 1, t + ")"); 34 | } 35 | } -------------------------------------------------------------------------------- /Chapter 1/Problem23.java: -------------------------------------------------------------------------------- 1 | import java.util.PriorityQueue; 2 | import java.util.Arrays; 3 | import java.util.Objects; 4 | 5 | public class Problem23 { 6 | public static void main(String[] args) { 7 | Solution_Heap solution = new Solution_Heap(); 8 | ListNode list1 = new ListNode(1); 9 | list1.next = new ListNode(4); 10 | list1.next.next = new ListNode(5); 11 | ListNode list2 = new ListNode(1, new ListNode(3, new ListNode(4))); 12 | ListNode list3 = new ListNode(2, new ListNode(6)); 13 | ListNode[] lists = { list1, list2, list3 }; 14 | ListNode result = solution.mergeKLists(lists); 15 | while (result != null) { 16 | System.out.print(result.val + " "); 17 | result = result.next; 18 | } 19 | } 20 | } 21 | 22 | class ListNode { 23 | int val; 24 | ListNode next; 25 | 26 | ListNode(int val) { 27 | this.val = val; 28 | } 29 | 30 | ListNode(int val, ListNode next) { 31 | this.val = val; 32 | this.next = next; 33 | } 34 | } 35 | 36 | class Solution_Heap { 37 | public ListNode mergeKLists(ListNode[] lists) { 38 | if (lists == null || lists.length == 0) 39 | return null; 40 | 41 | ListNode dummy = new ListNode(0); 42 | ListNode current = dummy; 43 | 44 | PriorityQueue heap = new PriorityQueue<>((a, b) -> a.val - b.val); 45 | 46 | Arrays.stream(lists) 47 | .filter(Objects::nonNull) 48 | .forEach(heap::offer); 49 | 50 | while (!heap.isEmpty()) { 51 | ListNode polled = heap.poll(); 52 | current.next = polled; 53 | current = current.next; 54 | if (polled.next != null) { 55 | heap.offer(polled.next); 56 | } 57 | } 58 | 59 | return dummy.next; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Chapter 1/Problem24.java: -------------------------------------------------------------------------------- 1 | public class Problem24 { 2 | public static void main(String[] args) { 3 | Solution solution = new Solution(); 4 | ListNode head = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4)))); 5 | ListNode result = solution.swapPairs(head); 6 | while (result != null) { 7 | System.out.print(result.val + " "); 8 | result = result.next; 9 | } 10 | } 11 | } 12 | 13 | // Definition for singly-linked list. 14 | class ListNode { 15 | int val; 16 | ListNode next; 17 | 18 | ListNode() { 19 | } 20 | 21 | ListNode(int val) { 22 | this.val = val; 23 | } 24 | 25 | ListNode(int val, ListNode next) { 26 | this.val = val; 27 | this.next = next; 28 | } 29 | } 30 | 31 | class Solution { 32 | public ListNode swapPairs(ListNode head) { 33 | ListNode dummy = new ListNode(0); 34 | dummy.next = head; 35 | ListNode pre = dummy; 36 | 37 | while (pre.next != null && pre.next.next != null) { 38 | ListNode first = pre.next; 39 | ListNode second = first.next; 40 | 41 | // Swapping 42 | first.next = second.next; 43 | second.next = first; 44 | pre.next = second; 45 | 46 | // Move to the next pair 47 | pre = first; 48 | } 49 | 50 | return dummy.next; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Chapter 1/Problem25.java: -------------------------------------------------------------------------------- 1 | public class Problem25 { 2 | public static void main(String[] args) { 3 | Solution solution = new Solution(); 4 | ListNode head = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4)))); 5 | int k = 2; 6 | ListNode result = solution.reverseKGroup(head, k); 7 | while (result != null) { 8 | System.out.print(result.val + " "); 9 | result = result.next; 10 | } 11 | } 12 | } 13 | 14 | class ListNode { 15 | int val; 16 | ListNode next; 17 | 18 | ListNode(int val) { 19 | this.val = val; 20 | } 21 | 22 | ListNode(int val, ListNode next) { 23 | this.val = val; 24 | this.next = next; 25 | } 26 | } 27 | 28 | class Solution { 29 | public ListNode reverseKGroup(ListNode head, int k) { 30 | ListNode dummy = new ListNode(0, head); 31 | ListNode pre = dummy, cur = dummy; 32 | while (cur.next != null) { 33 | for (int i = 0; i < k && cur != null; ++i) { 34 | cur = cur.next; 35 | } 36 | if (cur == null) { 37 | break; 38 | } 39 | ListNode t = cur.next; 40 | cur.next = null; 41 | ListNode start = pre.next; 42 | pre.next = reverseList(start); 43 | start.next = t; 44 | pre = start; 45 | cur = pre; 46 | } 47 | return dummy.next; 48 | } 49 | 50 | private ListNode reverseList(ListNode head) { 51 | ListNode pre = null, p = head; 52 | while (p != null) { 53 | ListNode q = p.next; 54 | p.next = pre; 55 | pre = p; 56 | p = q; 57 | } 58 | return pre; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Chapter 1/Problem26.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem26 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 1, 1, 2 }; 6 | int k = solution.removeDuplicates(nums); 7 | System.out.println(k); 8 | for (int i = 0; i < k; i++) { 9 | System.out.print(nums[i] + " "); 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public int removeDuplicates(int[] nums) { 16 | int k = 0; 17 | for (int x : nums) { 18 | if (k == 0 || x != nums[k - 1]) { 19 | nums[k++] = x; 20 | } 21 | } 22 | return k; 23 | } 24 | } -------------------------------------------------------------------------------- /Chapter 1/Problem27.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem27 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 3, 2, 2, 3 }; 6 | int val = 3; 7 | int k = solution.removeElement(nums, val); 8 | System.out.println(k); 9 | for (int i = 0; i < k; i++) { 10 | System.out.print(nums[i] + " "); 11 | } 12 | } 13 | } 14 | 15 | class Solution { 16 | public int removeElement(int[] nums, int val) { 17 | int k = 0; 18 | for (int x : nums) { 19 | if (x != val) { 20 | nums[k++] = x; 21 | } 22 | } 23 | return k; 24 | } 25 | } -------------------------------------------------------------------------------- /Chapter 1/Problem29.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem29 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int a = 10; 6 | int b = 3; 7 | System.out.println(solution.divide(a, b)); 8 | a = 7; 9 | b = -3; 10 | System.out.println(solution.divide(a, b)); 11 | a = -7; 12 | b = 3; 13 | System.out.println(solution.divide(a, b)); 14 | a = -7; 15 | b = -3; 16 | System.out.println(solution.divide(a, b)); 17 | } 18 | } 19 | 20 | class Solution { 21 | public int divide(int a, int b) { 22 | if (b == 1) { 23 | return a; 24 | } 25 | if (a == Integer.MIN_VALUE && b == -1) { 26 | return Integer.MAX_VALUE; 27 | } 28 | boolean sign = (a > 0 && b > 0) || (a < 0 && b < 0); 29 | a = a > 0 ? -a : a; 30 | b = b > 0 ? -b : b; 31 | int ans = 0; 32 | while (a <= b) { 33 | int x = b; 34 | int cnt = 1; 35 | while (x >= (Integer.MIN_VALUE >> 1) && a <= (x << 1)) { 36 | x <<= 1; 37 | cnt <<= 1; 38 | } 39 | ans += cnt; 40 | a -= x; 41 | } 42 | return sign ? ans : -ans; 43 | } 44 | } -------------------------------------------------------------------------------- /Chapter 1/Problem3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * class Solution { 4 | * public: 5 | * int lengthOfLongestSubstring(string s) { 6 | * unordered_set ss; 7 | * int i = 0, ans = 0; 8 | * for (int j = 0; j < s.size(); ++j) { 9 | * while (ss.count(s[j])) ss.erase(s[i++]); 10 | * ss.insert(s[j]); 11 | * ans = max(ans, j - i + 1); 12 | * } 13 | * return ans; 14 | * } 15 | * }; 16 | * 17 | */ -------------------------------------------------------------------------------- /Chapter 1/Problem30.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.List; 3 | import java.util.ArrayList; 4 | import java.util.Map; 5 | import java.util.HashMap; 6 | 7 | public class Problem30 { 8 | public static void main(String[] args) { 9 | Solution solution = new Solution(); 10 | String s = "barfoothefoobarman"; 11 | String[] words = { "foo", "bar" }; 12 | List ans = solution.findSubstring(s, words); 13 | System.out.println(ans); 14 | } 15 | } 16 | 17 | class Solution { 18 | public List findSubstring(String s, String[] words) { 19 | Map cnt = new HashMap<>(); 20 | for (String w : words) { 21 | cnt.merge(w, 1, Integer::sum); 22 | } 23 | int m = s.length(), n = words.length; 24 | int k = words[0].length(); 25 | List ans = new ArrayList<>(); 26 | for (int i = 0; i < k; ++i) { 27 | Map cnt1 = new HashMap<>(); 28 | int l = i, r = i; 29 | int t = 0; 30 | while (r + k <= m) { 31 | String w = s.substring(r, r + k); 32 | r += k; 33 | if (!cnt.containsKey(w)) { 34 | cnt1.clear(); 35 | l = r; 36 | t = 0; 37 | continue; 38 | } 39 | cnt1.merge(w, 1, Integer::sum); 40 | ++t; 41 | while (cnt1.get(w) > cnt.get(w)) { 42 | String remove = s.substring(l, l + k); 43 | l += k; 44 | cnt1.merge(remove, -1, Integer::sum); 45 | --t; 46 | } 47 | if (t == n) { 48 | ans.add(l); 49 | } 50 | } 51 | } 52 | return ans; 53 | } 54 | } -------------------------------------------------------------------------------- /Chapter 1/Problem31.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem31 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 1, 2, 3 }; 6 | solution.nextPermutation(nums); 7 | for (int x : nums) { 8 | System.out.print(x + " "); 9 | } 10 | } 11 | } 12 | 13 | class Solution { 14 | public void nextPermutation(int[] nums) { 15 | int n = nums.length; 16 | int i = n - 2; 17 | for (; i >= 0; --i) { 18 | if (nums[i] < nums[i + 1]) { 19 | break; 20 | } 21 | } 22 | if (i >= 0) { 23 | for (int j = n - 1; j > i; --j) { 24 | if (nums[j] > nums[i]) { 25 | swap(nums, i, j); 26 | break; 27 | } 28 | } 29 | } 30 | 31 | for (int j = i + 1, k = n - 1; j < k; ++j, --k) { 32 | swap(nums, j, k); 33 | } 34 | } 35 | 36 | private void swap(int[] nums, int i, int j) { 37 | int t = nums[j]; 38 | nums[j] = nums[i]; 39 | nums[i] = t; 40 | } 41 | } -------------------------------------------------------------------------------- /Chapter 1/Problem32.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem32 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String s = "(()"; 6 | System.out.println(solution.longestValidParentheses(s)); 7 | } 8 | } 9 | 10 | class Solution { 11 | public int longestValidParentheses(String s) { 12 | int n = s.length(); 13 | int[] f = new int[n + 1]; 14 | int ans = 0; 15 | for (int i = 2; i <= n; ++i) { 16 | if (s.charAt(i - 1) == ')') { 17 | if (s.charAt(i - 2) == '(') { 18 | f[i] = f[i - 2] + 2; 19 | } else { 20 | int j = i - f[i - 1] - 1; 21 | if (j > 0 && s.charAt(j - 1) == '(') { 22 | f[i] = f[i - 1] + 2 + f[j - 1]; 23 | } 24 | } 25 | ans = Math.max(ans, f[i]); 26 | } 27 | } 28 | return ans; 29 | } 30 | } -------------------------------------------------------------------------------- /Chapter 1/Problem33.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem33 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 4, 5, 6, 7, 0, 1, 2 }; 6 | int target = 0; 7 | int result = solution.search(nums, target); 8 | System.out.println(result); // Output: 4 9 | } 10 | } 11 | 12 | class Solution { 13 | public int search(int[] nums, int target) { 14 | int n = nums.length; 15 | int left = 0, right = n - 1; 16 | while (left < right) { 17 | int mid = (left + right) >> 1; 18 | if (nums[0] <= nums[mid]) { 19 | if (nums[0] <= target && target <= nums[mid]) { 20 | right = mid; 21 | } else { 22 | left = mid + 1; 23 | } 24 | } else { 25 | if (nums[mid] < target && target <= nums[n - 1]) { 26 | left = mid + 1; 27 | } else { 28 | right = mid; 29 | } 30 | } 31 | } 32 | return nums[left] == target ? left : -1; 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter 1/Problem34.java: -------------------------------------------------------------------------------- 1 | public class Problem34 { 2 | public static void main(String[] args) { 3 | Solution solution = new Solution(); 4 | int[] nums = { 1, 2, 3, 4, 5 }; 5 | int target = 3; 6 | int result = solution.search(nums, target); 7 | System.out.println(result); // Output: 2 8 | } 9 | } 10 | 11 | class Solution { 12 | public int search(int[] nums, int target) { 13 | int left = 0, right = nums.length - 1; 14 | 15 | while (left <= right) { 16 | int mid = (left + right) >> 1; 17 | if (nums[mid] == target) { 18 | return mid; 19 | } else if (nums[mid] < target) { 20 | left = mid + 1; 21 | } else { 22 | right = mid - 1; 23 | } 24 | } 25 | 26 | return -1; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chapter 1/Problem35.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem35 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 1, 3, 5, 6 }; 6 | System.out.println(solution.searchInsert(nums, 5)); // Output: 2 7 | System.out.println(solution.searchInsert(nums, 2)); // Output: 1 8 | System.out.println(solution.searchInsert(nums, 7)); // Output: 4 9 | System.out.println(solution.searchInsert(nums, 0)); // Output: 0 10 | } 11 | } 12 | 13 | class Solution { 14 | public int searchInsert(int[] nums, int target) { 15 | int left = 0, right = nums.length; 16 | while (left < right) { 17 | int mid = (left + right) >>> 1; 18 | if (nums[mid] >= target) { 19 | right = mid; 20 | } else { 21 | left = mid + 1; 22 | } 23 | } 24 | return left; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter 1/Problem36.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem36 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | char[][] board = { 6 | { '5', '3', '.', '.', '7', '.', '.', '.', '.' }, 7 | { '6', '.', '.', '1', '9', '5', '.', '.', '.' }, 8 | { '.', '9', '8', '.', '.', '.', '.', '6', '.' }, 9 | { '8', '.', '.', '.', '6', '.', '.', '.', '3' }, 10 | { '4', '.', '6', '8', '.', '3', '.', '.', '1' }, 11 | { '7', '.', '.', '.', '2', '.', '.', '.', '6' }, 12 | { '.', '6', '.', '.', '.', '.', '2', '8', '.' }, 13 | { '.', '.', '2', '4', '1', '9', '.', '.', '.' }, 14 | { '3', '.', '.', '.', '8', '.', '.', '7', '.' } 15 | }; 16 | System.out.println(solution.isValidSudoku(board)); // Output: true 17 | } 18 | } 19 | 20 | class Solution { 21 | public boolean isValidSudoku(char[][] board) { 22 | boolean[][] row = new boolean[9][9]; 23 | boolean[][] col = new boolean[9][9]; 24 | boolean[][] sub = new boolean[9][9]; 25 | for (int i = 0; i < 9; ++i) { 26 | for (int j = 0; j < 9; ++j) { 27 | char c = board[i][j]; 28 | if (c == '.') { 29 | continue; 30 | } 31 | int num = c - '0' - 1; 32 | int k = i / 3 * 3 + j / 3; 33 | if (row[i][num] || col[j][num] || sub[k][num]) { 34 | return false; 35 | } 36 | row[i][num] = true; 37 | col[j][num] = true; 38 | sub[k][num] = true; 39 | } 40 | } 41 | return true; 42 | } 43 | } -------------------------------------------------------------------------------- /Chapter 1/Problem37.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem37 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | 7 | char[][] board = { 8 | { '5', '3', '.', '.', '7', '.', '.', '.', '.' }, 9 | { '6', '.', '.', '1', '9', '5', '.', '.', '.' }, 10 | { '.', '9', '8', '.', '.', '.', '.', '6', '.' }, 11 | { '8', '.', '.', '.', '6', '.', '.', '.', '3' }, 12 | { '4', '.', '6', '8', '.', '3', '.', '.', '1' }, 13 | { '7', '.', '.', '2', '1', '9', '.', '.', '6' }, 14 | { '.', '6', '.', '.', '.', '2', '8', '.', '.' }, 15 | { '.', '.', '4', '4', '3', '7', '9', '1', '.' }, 16 | { '.', '8', '7', '.', '2', '.', '.', '4' } 17 | }; 18 | solution.solveSudoku(board); 19 | for (char[] row : board) { 20 | System.out.println(row); 21 | } 22 | } 23 | } 24 | 25 | class Solution { 26 | private boolean ok; 27 | private char[][] board; 28 | private List t = new ArrayList<>(); 29 | private boolean[][] row = new boolean[9][9]; 30 | private boolean[][] col = new boolean[9][9]; 31 | private boolean[][][] block = new boolean[3][3][9]; 32 | 33 | public void solveSudoku(char[][] board) { 34 | this.board = board; 35 | for (int i = 0; i < 9; ++i) { 36 | for (int j = 0; j < 9; ++j) { 37 | if (board[i][j] == '.') { 38 | t.add(i * 9 + j); 39 | } else { 40 | int v = board[i][j] - '1'; 41 | row[i][v] = col[j][v] = block[i / 3][j / 3][v] = true; 42 | } 43 | } 44 | } 45 | dfs(0); 46 | } 47 | 48 | private void dfs(int k) { 49 | if (k == t.size()) { 50 | ok = true; 51 | return; 52 | } 53 | int i = t.get(k) / 9, j = t.get(k) % 9; 54 | for (int v = 0; v < 9; ++v) { 55 | if (!row[i][v] && !col[j][v] && !block[i / 3][j / 3][v]) { 56 | row[i][v] = col[j][v] = block[i / 3][j / 3][v] = true; 57 | board[i][j] = (char) (v + '1'); 58 | dfs(k + 1); 59 | row[i][v] = col[j][v] = block[i / 3][j / 3][v] = false; 60 | } 61 | if (ok) { 62 | return; 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /Chapter 1/Problem38.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem38 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | System.out.println(solution.countAndSay(4)); // Output: "1211" 6 | } 7 | } 8 | 9 | class Solution { 10 | public String countAndSay(int n) { 11 | String s = "1"; 12 | while (--n > 0) { 13 | StringBuilder t = new StringBuilder(); 14 | for (int i = 0; i < s.length();) { 15 | int j = i; 16 | while (j < s.length() && s.charAt(j) == s.charAt(i)) { 17 | ++j; 18 | } 19 | t.append((j - i) + ""); 20 | t.append(s.charAt(i)); 21 | i = j; 22 | } 23 | s = t.toString(); 24 | } 25 | return s; 26 | } 27 | } -------------------------------------------------------------------------------- /Chapter 1/Problem39.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem39 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | int[] candidates = { 2, 3, 6, 7 }; 7 | int target = 7; 8 | System.out.println(solution.combinationSum(candidates, target)); 9 | } 10 | } 11 | 12 | class Solution { 13 | private List> ans = new ArrayList<>(); 14 | private List t = new ArrayList<>(); 15 | private int[] candidates; 16 | 17 | public List> combinationSum(int[] candidates, int target) { 18 | Arrays.sort(candidates); // Optional: helps with pruning 19 | this.candidates = candidates; 20 | dfs(0, target); 21 | return ans; 22 | } 23 | 24 | private void dfs(int i, int s) { 25 | if (s == 0) { 26 | ans.add(new ArrayList<>(t)); // ✅ Generic safe 27 | return; 28 | } 29 | if (i >= candidates.length || s < candidates[i]) { 30 | return; 31 | } 32 | 33 | // Skip current candidate 34 | dfs(i + 1, s); 35 | 36 | // Include current candidate 37 | t.add(candidates[i]); 38 | dfs(i, s - candidates[i]); 39 | t.remove(t.size() - 1); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Chapter 1/Problem4.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem4 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums1 = { 1, 3 }; 6 | int[] nums2 = { 2 }; 7 | double result = solution.findMedianSortedArrays(nums1, nums2); 8 | System.out.println("Median: " + result); 9 | } 10 | } 11 | 12 | class Solution { 13 | private int m; 14 | private int n; 15 | private int[] nums1; 16 | private int[] nums2; 17 | 18 | public double findMedianSortedArrays(int[] nums1, int[] nums2) { 19 | m = nums1.length; 20 | n = nums2.length; 21 | this.nums1 = nums1; 22 | this.nums2 = nums2; 23 | int a = f(0, 0, (m + n + 1) / 2); 24 | int b = f(0, 0, (m + n + 2) / 2); 25 | return (a + b) / 2.0; 26 | } 27 | 28 | private int f(int i, int j, int k) { 29 | if (i >= m) { 30 | return nums2[j + k - 1]; 31 | } 32 | if (j >= n) { 33 | return nums1[i + k - 1]; 34 | } 35 | if (k == 1) { 36 | return Math.min(nums1[i], nums2[j]); 37 | } 38 | int p = k / 2; 39 | int x = i + p - 1 < m ? nums1[i + p - 1] : 1 << 30; 40 | int y = j + p - 1 < n ? nums2[j + p - 1] : 1 << 30; 41 | return x < y ? f(i + p, j, k - p) : f(i, j + p, k - p); 42 | } 43 | } -------------------------------------------------------------------------------- /Chapter 1/Problem40.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem40 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | int[] candidates = { 10, 1, 2, 7, 6, 1, 5 }; 7 | int target = 8; 8 | System.out.println(solution.combinationSum2(candidates, target)); 9 | } 10 | } 11 | 12 | class Solution { 13 | private List> ans = new ArrayList<>(); 14 | private List t = new ArrayList<>(); 15 | private int[] candidates; 16 | 17 | public List> combinationSum2(int[] candidates, int target) { 18 | Arrays.sort(candidates); 19 | this.candidates = candidates; 20 | dfs(0, target); 21 | return ans; 22 | } 23 | 24 | private void dfs(int i, int s) { 25 | if (s == 0) { 26 | ans.add(new ArrayList<>(t)); 27 | return; 28 | } 29 | if (i >= candidates.length || s < candidates[i]) { 30 | return; 31 | } 32 | for (int j = i; j < candidates.length; ++j) { 33 | if (j > i && candidates[j] == candidates[j - 1]) { 34 | continue; 35 | } 36 | t.add(candidates[j]); 37 | dfs(j + 1, s - candidates[j]); 38 | t.remove(t.size() - 1); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Chapter 1/Problem41.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem41 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 3, 4, -1, 1 }; 6 | System.out.println(solution.firstMissingPositive(nums)); 7 | } 8 | } 9 | 10 | class Solution { 11 | public int firstMissingPositive(int[] nums) { 12 | int n = nums.length; 13 | for (int i = 0; i < n; ++i) { 14 | while (nums[i] >= 1 && nums[i] <= n && nums[i] != nums[nums[i] - 1]) { 15 | swap(nums, i, nums[i] - 1); 16 | } 17 | } 18 | for (int i = 0; i < n; ++i) { 19 | if (i + 1 != nums[i]) { 20 | return i + 1; 21 | } 22 | } 23 | return n + 1; 24 | } 25 | 26 | private void swap(int[] nums, int i, int j) { 27 | int t = nums[i]; 28 | nums[i] = nums[j]; 29 | nums[j] = t; 30 | } 31 | } -------------------------------------------------------------------------------- /Chapter 1/Problem42.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem42 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] height = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 }; 6 | System.out.println(solution.trap(height)); 7 | } 8 | } 9 | 10 | class Solution { 11 | public int trap(int[] height) { 12 | if (height == null || height.length == 0) 13 | return 0; 14 | int length = height.length; 15 | int[] leftMax = new int[length]; // `leftMax` represents the maximum height in the subarray from the leftmost 16 | // index to the current index 17 | int[] rightMax = new int[length]; // `rightMax` represents the maximum height in the subarray from the current 18 | // index to the rightmost index 19 | leftMax[0] = height[0]; 20 | for (int i = 1; i < length; i++) 21 | leftMax[i] = Math.max(height[i], leftMax[i - 1]); 22 | rightMax[length - 1] = height[length - 1]; 23 | for (int i = length - 2; i >= 0; i--) 24 | rightMax[i] = Math.max(height[i], rightMax[i + 1]); 25 | int amount = 0; 26 | for (int i = 0; i < length; i++) 27 | amount += Math.min(leftMax[i], rightMax[i]) - height[i]; 28 | return amount; 29 | } 30 | } -------------------------------------------------------------------------------- /Chapter 1/Problem43.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem43 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String num1 = "123"; 6 | String num2 = "456"; 7 | System.out.println(solution.multiply(num1, num2)); 8 | } 9 | } 10 | 11 | class Solution { 12 | public String multiply(String num1, String num2) { 13 | if ("0".equals(num1) || "0".equals(num2)) { 14 | return "0"; 15 | } 16 | int m = num1.length(), n = num2.length(); 17 | int[] arr = new int[m + n]; 18 | for (int i = m - 1; i >= 0; --i) { 19 | int a = num1.charAt(i) - '0'; 20 | for (int j = n - 1; j >= 0; --j) { 21 | int b = num2.charAt(j) - '0'; 22 | arr[i + j + 1] += a * b; 23 | } 24 | } 25 | for (int i = arr.length - 1; i > 0; --i) { 26 | arr[i - 1] += arr[i] / 10; 27 | arr[i] %= 10; 28 | } 29 | int i = arr[0] == 0 ? 1 : 0; 30 | StringBuilder ans = new StringBuilder(); 31 | for (; i < arr.length; ++i) { 32 | ans.append(arr[i]); 33 | } 34 | return ans.toString(); 35 | } 36 | } -------------------------------------------------------------------------------- /Chapter 1/Problem44.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem44 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String s = "aa"; 6 | String p = "a"; 7 | System.out.println(solution.isMatch(s, p)); // false 8 | s = "aa"; 9 | p = "*"; 10 | System.out.println(solution.isMatch(s, p)); // true 11 | s = "cb"; 12 | p = "?a"; 13 | System.out.println(solution.isMatch(s, p)); // false 14 | s = "adceb"; 15 | p = "*a*b"; 16 | System.out.println(solution.isMatch(s, p)); // true 17 | s = "acdcb"; 18 | p = "a*c?b"; 19 | System.out.println(solution.isMatch(s, p)); // false 20 | } 21 | } 22 | 23 | class Solution { 24 | public boolean isMatch(String s, String p) { 25 | int m = s.length(), n = p.length(); 26 | boolean[][] dp = new boolean[m + 1][n + 1]; 27 | dp[0][0] = true; 28 | for (int j = 1; j <= n; ++j) { 29 | if (p.charAt(j - 1) == '*') { 30 | dp[0][j] = dp[0][j - 1]; 31 | } 32 | } 33 | for (int i = 1; i <= m; ++i) { 34 | for (int j = 1; j <= n; ++j) { 35 | if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?') { 36 | dp[i][j] = dp[i - 1][j - 1]; 37 | } else if (p.charAt(j - 1) == '*') { 38 | dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; 39 | } 40 | } 41 | } 42 | return dp[m][n]; 43 | } 44 | } -------------------------------------------------------------------------------- /Chapter 1/Problem45.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem45 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 2, 3, 1, 1, 4 }; 6 | System.out.println(solution.jump(nums)); // Output: 2 7 | nums = new int[] { 2, 3, 0, 1, 4 }; 8 | System.out.println(solution.jump(nums)); // Output: 2 9 | } 10 | } 11 | 12 | class Solution { 13 | public int jump(int[] nums) { 14 | int ans = 0, mx = 0, last = 0; 15 | for (int i = 0; i < nums.length - 1; ++i) { 16 | mx = Math.max(mx, i + nums[i]); 17 | if (last == i) { 18 | ++ans; 19 | last = mx; 20 | } 21 | } 22 | return ans; 23 | } 24 | } -------------------------------------------------------------------------------- /Chapter 1/Problem46.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem46 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | int[] nums = { 1, 2, 3 }; 7 | System.out.println(solution.permute(nums)); 8 | } 9 | } 10 | 11 | class Solution { 12 | private List> ans = new ArrayList<>(); 13 | private List t = new ArrayList<>(); 14 | private boolean[] vis; 15 | private int[] nums; 16 | 17 | public List> permute(int[] nums) { 18 | this.nums = nums; 19 | vis = new boolean[nums.length]; 20 | dfs(0); 21 | return ans; 22 | } 23 | 24 | private void dfs(int i) { 25 | if (i == nums.length) { 26 | ans.add(new ArrayList<>(t)); 27 | return; 28 | } 29 | for (int j = 0; j < nums.length; ++j) { 30 | if (!vis[j]) { 31 | vis[j] = true; 32 | t.add(nums[j]); 33 | dfs(i + 1); 34 | t.remove(t.size() - 1); 35 | vis[j] = false; 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Chapter 1/Problem47.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem47 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | int[] nums = { 1, 1, 2 }; 7 | System.out.println(solution.permuteUnique(nums)); 8 | } 9 | } 10 | 11 | class Solution { 12 | private List> ans = new ArrayList<>(); 13 | private List t = new ArrayList<>(); 14 | private int[] nums; 15 | private boolean[] vis; 16 | 17 | public List> permuteUnique(int[] nums) { 18 | Arrays.sort(nums); 19 | this.nums = nums; 20 | vis = new boolean[nums.length]; 21 | dfs(0); 22 | return ans; 23 | } 24 | 25 | private void dfs(int i) { 26 | if (i == nums.length) { 27 | ans.add(new ArrayList<>(t)); 28 | return; 29 | } 30 | for (int j = 0; j < nums.length; ++j) { 31 | if (vis[j] || (j > 0 && nums[j] == nums[j - 1] && !vis[j - 1])) { 32 | continue; 33 | } 34 | t.add(nums[j]); 35 | vis[j] = true; 36 | dfs(i + 1); 37 | vis[j] = false; 38 | t.remove(t.size() - 1); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Chapter 1/Problem48.java: -------------------------------------------------------------------------------- 1 | public class Problem48 { 2 | public static void main(String[] args) { 3 | int[][] mat = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; 4 | int N = mat.length; 5 | 6 | System.out.println("Input Matrix:"); 7 | printMatrix(mat); 8 | 9 | rotateMatrix_anticlock(N, mat); 10 | 11 | System.out.println("Rotated Matrix:"); 12 | printMatrix(mat); 13 | } 14 | 15 | static void printMatrix(int mat[][]) { 16 | for (int i = 0; i < mat.length; i++) { 17 | for (int j = 0; j < mat[i].length; j++) 18 | System.out.print(mat[i][j] + " "); 19 | System.out.println(); 20 | } 21 | System.out.println(); 22 | } 23 | 24 | static void rotateMatrix_anticlock(int N, int mat[][]) { 25 | for (int x = 0; x < N / 2; x++) { 26 | for (int y = x; y < N - x - 1; y++) { 27 | int temp = mat[x][y]; 28 | mat[x][y] = mat[y][N - 1 - x]; 29 | mat[y][N - 1 - x] = mat[N - 1 - x][N - 1 - y]; 30 | mat[N - 1 - x][N - 1 - y] = mat[N - 1 - y][x]; 31 | mat[N - 1 - y][x] = temp; 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Chapter 1/Problem49.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem49 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | String[] strs = { "eat", "tea", "tan", "ate", "nat", "bat" }; 7 | System.out.println(solution.groupAnagrams(strs)); 8 | } 9 | } 10 | 11 | class Solution { 12 | @SuppressWarnings("unused") 13 | public List> groupAnagrams(String[] strs) { 14 | Map> d = new HashMap<>(); 15 | for (String s : strs) { 16 | char[] t = s.toCharArray(); 17 | Arrays.sort(t); 18 | String k = String.valueOf(t); 19 | d.computeIfAbsent(k, key -> new ArrayList<>()).add(s); 20 | } 21 | return new ArrayList<>(d.values()); 22 | } 23 | } -------------------------------------------------------------------------------- /Chapter 1/Problem5.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem5 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String s = "PAYPALISHIRING"; 6 | int numRows = 3; 7 | String result = solution.convert(s, numRows); 8 | System.out.println("Converted string: " + result); 9 | } 10 | } 11 | 12 | class Solution { 13 | public String convert(String s, int numRows) { 14 | if (numRows == 1) { 15 | return s; 16 | } 17 | StringBuilder ans = new StringBuilder(); 18 | int group = 2 * numRows - 2; 19 | for (int i = 1; i <= numRows; i++) { 20 | int interval = i == numRows ? group : 2 * numRows - 2 * i; 21 | int idx = i - 1; 22 | while (idx < s.length()) { 23 | ans.append(s.charAt(idx)); 24 | idx += interval; 25 | interval = group - interval; 26 | if (interval == 0) { 27 | interval = group; 28 | } 29 | } 30 | } 31 | return ans.toString(); 32 | } 33 | } -------------------------------------------------------------------------------- /Chapter 1/Problem50.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem50 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | double x = 2.0; 6 | int n = 10; 7 | System.out.println(solution.myPow(x, n)); // Output: 1024.0 8 | } 9 | } 10 | 11 | class Solution { 12 | public double myPow(double x, int n) { 13 | return n >= 0 ? qpow(x, n) : 1 / qpow(x, -(long) n); 14 | } 15 | 16 | private double qpow(double a, long n) { 17 | double ans = 1; 18 | for (; n > 0; n >>= 1) { 19 | if ((n & 1) == 1) { 20 | ans = ans * a; 21 | } 22 | a = a * a; 23 | } 24 | return ans; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter 1/Problem51.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem51 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | int n = 4; 7 | List> result = solution.solveNQueens(n); 8 | for (List list : result) { 9 | for (String s : list) { 10 | System.out.println(s); 11 | } 12 | System.out.println(); 13 | } 14 | } 15 | } 16 | 17 | class Solution { 18 | private List> ans = new ArrayList<>(); 19 | private int[] col; 20 | private int[] dg; 21 | private int[] udg; 22 | private String[][] g; 23 | private int n; 24 | 25 | public List> solveNQueens(int n) { 26 | this.n = n; 27 | col = new int[n]; 28 | dg = new int[n << 1]; 29 | udg = new int[n << 1]; 30 | g = new String[n][n]; 31 | for (int i = 0; i < n; ++i) { 32 | Arrays.fill(g[i], "."); 33 | } 34 | dfs(0); 35 | return ans; 36 | } 37 | 38 | private void dfs(int i) { 39 | if (i == n) { 40 | List t = new ArrayList<>(); 41 | for (int j = 0; j < n; ++j) { 42 | t.add(String.join("", g[j])); 43 | } 44 | ans.add(t); 45 | return; 46 | } 47 | for (int j = 0; j < n; ++j) { 48 | if (col[j] + dg[i + j] + udg[n - i + j] == 0) { 49 | g[i][j] = "Q"; 50 | col[j] = dg[i + j] = udg[n - i + j] = 1; 51 | dfs(i + 1); 52 | col[j] = dg[i + j] = udg[n - i + j] = 0; 53 | g[i][j] = "."; 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /Chapter 1/Problem52.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem52 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int n = 4; 6 | int result = solution.totalNQueens(n); 7 | System.out.println("Total solutions for " + n + " queens: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | private int n; 13 | private int ans; 14 | private boolean[] cols = new boolean[10]; 15 | private boolean[] dg = new boolean[20]; 16 | private boolean[] udg = new boolean[20]; 17 | 18 | public int totalNQueens(int n) { 19 | this.n = n; 20 | dfs(0); 21 | return ans; 22 | } 23 | 24 | private void dfs(int i) { 25 | if (i == n) { 26 | ++ans; 27 | return; 28 | } 29 | for (int j = 0; j < n; ++j) { 30 | int a = i + j, b = i - j + n; 31 | if (cols[j] || dg[a] || udg[b]) { 32 | continue; 33 | } 34 | cols[j] = true; 35 | dg[a] = true; 36 | udg[b] = true; 37 | dfs(i + 1); 38 | cols[j] = false; 39 | dg[a] = false; 40 | udg[b] = false; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Chapter 1/Problem53.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem53 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { -2, 1, -3, 4, -1, 2, 1, -5, 4 }; 6 | System.out.println(solution.maxSubArray(nums)); // Output: 6 7 | } 8 | } 9 | 10 | class Solution { 11 | public int maxSubArray(int[] nums) { 12 | int ans = nums[0]; 13 | for (int i = 1, f = nums[0]; i < nums.length; ++i) { 14 | f = Math.max(f, 0) + nums[i]; 15 | ans = Math.max(ans, f); 16 | } 17 | return ans; 18 | } 19 | } -------------------------------------------------------------------------------- /Chapter 1/Problem54.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Problem54 { 5 | public static void main(String[] args) { 6 | Solution solution = new Solution(); 7 | int[][] matrix = { 8 | { 1, 2, 3 }, 9 | { 4, 5, 6 }, 10 | { 7, 8, 9 } 11 | }; 12 | List result = solution.spiralOrder(matrix); 13 | System.out.println(result); // Output: [1, 2, 3, 6, 9, 8, 7, 4, 5] 14 | } 15 | } 16 | 17 | class Solution { 18 | public List spiralOrder(int[][] matrix) { 19 | int m = matrix.length, n = matrix[0].length; 20 | int[] dirs = { 0, 1, 0, -1, 0 }; 21 | int i = 0, j = 0, k = 0; 22 | List ans = new ArrayList<>(); 23 | boolean[][] vis = new boolean[m][n]; 24 | for (int h = m * n; h > 0; --h) { 25 | ans.add(matrix[i][j]); 26 | vis[i][j] = true; 27 | int x = i + dirs[k], y = j + dirs[k + 1]; 28 | if (x < 0 || x >= m || y < 0 || y >= n || vis[x][y]) { 29 | k = (k + 1) % 4; 30 | } 31 | i += dirs[k]; 32 | j += dirs[k + 1]; 33 | } 34 | return ans; 35 | } 36 | } -------------------------------------------------------------------------------- /Chapter 1/Problem55.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem55 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 2, 3, 1, 1, 4 }; 6 | System.out.println(solution.canJump(nums)); // Output: true 7 | } 8 | } 9 | 10 | class Solution { 11 | public boolean canJump(int[] nums) { 12 | int mx = 0; 13 | for (int i = 0; i < nums.length; ++i) { 14 | if (mx < i) { 15 | return false; 16 | } 17 | mx = Math.max(mx, i + nums[i]); 18 | } 19 | return true; 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter 1/Problem56.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Arrays; 3 | import java.util.List; 4 | 5 | public class Problem56 { 6 | public static void main(String[] args) { 7 | Solution solution = new Solution(); 8 | int[][] intervals = { 9 | { 1, 3 }, 10 | { 2, 6 }, 11 | { 8, 10 }, 12 | { 15, 18 } 13 | }; 14 | int[][] merged = solution.merge(intervals); 15 | for (int[] interval : merged) { 16 | System.out.println("[" + interval[0] + ", " + interval[1] + "]"); 17 | } 18 | } 19 | } 20 | 21 | class Solution { 22 | public int[][] merge(int[][] intervals) { 23 | Arrays.sort(intervals, (a, b) -> a[0] - b[0]); 24 | List ans = new ArrayList<>(); 25 | ans.add(intervals[0]); 26 | for (int i = 1; i < intervals.length; ++i) { 27 | int s = intervals[i][0], e = intervals[i][1]; 28 | if (ans.get(ans.size() - 1)[1] < s) { 29 | ans.add(intervals[i]); 30 | } else { 31 | ans.get(ans.size() - 1)[1] = Math.max(ans.get(ans.size() - 1)[1], e); 32 | } 33 | } 34 | return ans.toArray(new int[ans.size()][]); 35 | } 36 | } -------------------------------------------------------------------------------- /Chapter 1/Problem57.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Arrays; 3 | import java.util.List; 4 | 5 | public class Problem57 { 6 | public static void main(String[] args) { 7 | Solution solution = new Problem57().new Solution(); 8 | int[][] intervals = { { 1, 3 }, { 6, 9 } }; 9 | int[] newInterval = { 2, 5 }; 10 | int[][] result = solution.insert(intervals, newInterval); 11 | for (int[] interval : result) { 12 | System.out.println("[" + interval[0] + ", " + interval[1] + "]"); 13 | } 14 | } 15 | 16 | // LeetCode submit 17 | 18 | class Solution { 19 | public int[][] insert(int[][] intervals, int[] newInterval) { 20 | int[][] newIntervals = new int[intervals.length + 1][2]; 21 | for (int i = 0; i < intervals.length; ++i) { 22 | newIntervals[i] = intervals[i]; 23 | } 24 | newIntervals[intervals.length] = newInterval; 25 | return merge(newIntervals); 26 | } 27 | 28 | private int[][] merge(int[][] intervals) { 29 | Arrays.sort(intervals, (a, b) -> a[0] - b[0]); 30 | List ans = new ArrayList<>(); 31 | ans.add(intervals[0]); 32 | for (int i = 1; i < intervals.length; ++i) { 33 | int s = intervals[i][0], e = intervals[i][1]; 34 | if (ans.get(ans.size() - 1)[1] < s) { 35 | ans.add(intervals[i]); 36 | } else { 37 | ans.get(ans.size() - 1)[1] = Math.max(ans.get(ans.size() - 1)[1], e); 38 | } 39 | } 40 | return ans.toArray(new int[ans.size()][]); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Chapter 1/Problem58.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem58 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String s = "Hello World"; 6 | int result = solution.lengthOfLastWord(s); 7 | System.out.println(result); // Output: 5 8 | } 9 | } 10 | 11 | class Solution { 12 | public int lengthOfLastWord(String s) { 13 | int i = s.length() - 1; 14 | while (i >= 0 && s.charAt(i) == ' ') { 15 | --i; 16 | } 17 | int j = i; 18 | while (j >= 0 && s.charAt(j) != ' ') { 19 | --j; 20 | } 21 | return i - j; 22 | } 23 | } -------------------------------------------------------------------------------- /Chapter 1/Problem59.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem59 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int n = 3; 6 | int[][] result = solution.generateMatrix(n); 7 | for (int[] row : result) { 8 | for (int num : row) { 9 | System.out.print(num + " "); 10 | } 11 | System.out.println(); 12 | } 13 | } 14 | } 15 | 16 | class Solution { 17 | public int[][] generateMatrix(int n) { 18 | int[][] ans = new int[n][n]; 19 | int i = 0, j = 0, k = 0; 20 | int[][] dirs = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; 21 | for (int v = 1; v <= n * n; ++v) { 22 | ans[i][j] = v; 23 | int x = i + dirs[k][0], y = j + dirs[k][1]; 24 | if (x < 0 || y < 0 || x >= n || y >= n || ans[x][y] > 0) { 25 | k = (k + 1) % 4; 26 | x = i + dirs[k][0]; 27 | y = j + dirs[k][1]; 28 | } 29 | i = x; 30 | j = y; 31 | } 32 | return ans; 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter 1/Problem6.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem6 { 3 | 4 | public class Solution { 5 | public String convert(String s, int nRows) { 6 | if (s == null || s.length() <= nRows || nRows == 1) { 7 | return s; 8 | } 9 | StringBuilder sb = new StringBuilder(); 10 | for (int i = 0; i < nRows; i++) { 11 | if (i == 0 || i == nRows - 1) { 12 | int index = i; 13 | while (index < s.length()) { 14 | sb.append(s.charAt(index)); 15 | index += 2 * (nRows - 1); 16 | } 17 | } else { 18 | int index = i; 19 | while (index < s.length()) { 20 | sb.append(s.charAt(index)); 21 | if (index + 2 * nRows - 2 * i - 2 < s.length()) { 22 | sb.append(s.charAt(index + 2 * nRows - 2 * i - 2)); 23 | } 24 | index += 2 * (nRows - 1); 25 | } 26 | } 27 | } 28 | return sb.toString(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Chapter 1/Problem60.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem60 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int n = 3; 6 | int k = 3; 7 | String result = solution.getPermutation(n, k); 8 | System.out.println(result); // Output: "213" 9 | } 10 | } 11 | 12 | class Solution { 13 | public String getPermutation(int n, int k) { 14 | StringBuilder ans = new StringBuilder(); 15 | boolean[] vis = new boolean[n + 1]; 16 | for (int i = 0; i < n; ++i) { 17 | int fact = 1; 18 | for (int j = 1; j < n - i; ++j) { 19 | fact *= j; 20 | } 21 | for (int j = 1; j <= n; ++j) { 22 | if (!vis[j]) { 23 | if (k > fact) { 24 | k -= fact; 25 | } else { 26 | ans.append(j); 27 | vis[j] = true; 28 | break; 29 | } 30 | } 31 | } 32 | } 33 | return ans.toString(); 34 | } 35 | } -------------------------------------------------------------------------------- /Chapter 1/Problem61.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem61 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | ListNode head = new ListNode(1); 6 | head.next = new ListNode(2); 7 | head.next.next = new ListNode(3); 8 | head.next.next.next = new ListNode(4); 9 | head.next.next.next.next = new ListNode(5); 10 | int k = 2; 11 | ListNode result = solution.rotateRight(head, k); 12 | while (result != null) { 13 | System.out.print(result.val + " "); 14 | result = result.next; 15 | } 16 | } 17 | } 18 | 19 | class Solution { 20 | public ListNode rotateRight(ListNode head, int k) { 21 | if (head == null || head.next == null) { 22 | return head; 23 | } 24 | ListNode cur = head; 25 | int n = 0; 26 | for (; cur != null; cur = cur.next) { 27 | n++; 28 | } 29 | k %= n; 30 | if (k == 0) { 31 | return head; 32 | } 33 | ListNode fast = head; 34 | ListNode slow = head; 35 | while (k-- > 0) { 36 | fast = fast.next; 37 | } 38 | while (fast.next != null) { 39 | fast = fast.next; 40 | slow = slow.next; 41 | } 42 | ListNode ans = slow.next; 43 | slow.next = null; 44 | fast.next = head; 45 | return ans; 46 | } 47 | } -------------------------------------------------------------------------------- /Chapter 1/Problem62.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | 3 | public class Problem62 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | int m = 3; 7 | int n = 7; 8 | int result = solution.uniquePaths(m, n); 9 | System.out.println(result); // Output: 28 10 | } 11 | } 12 | 13 | class Solution { 14 | public int uniquePaths(int m, int n) { 15 | int[] f = new int[n]; 16 | Arrays.fill(f, 1); 17 | for (int i = 1; i < m; ++i) { 18 | for (int j = 1; j < n; ++j) { 19 | f[j] += f[j - 1]; 20 | } 21 | } 22 | return f[n - 1]; 23 | } 24 | } -------------------------------------------------------------------------------- /Chapter 1/Problem63.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem63 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[][] obstacleGrid = { 6 | { 0, 0, 0 }, 7 | { 0, 1, 0 }, 8 | { 0, 0, 0 } 9 | }; 10 | int result = solution.uniquePathsWithObstacles(obstacleGrid); 11 | System.out.println(result); // Output: 2 12 | } 13 | } 14 | 15 | class Solution { 16 | public int uniquePathsWithObstacles(int[][] obstacleGrid) { 17 | int m = obstacleGrid.length, n = obstacleGrid[0].length; 18 | int[][] dp = new int[m][n]; 19 | for (int i = 0; i < m && obstacleGrid[i][0] == 0; ++i) { 20 | dp[i][0] = 1; 21 | } 22 | for (int j = 0; j < n && obstacleGrid[0][j] == 0; ++j) { 23 | dp[0][j] = 1; 24 | } 25 | for (int i = 1; i < m; ++i) { 26 | for (int j = 1; j < n; ++j) { 27 | if (obstacleGrid[i][j] == 0) { 28 | dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; 29 | } 30 | } 31 | } 32 | return dp[m - 1][n - 1]; 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter 1/Problem64.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem64 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[][] grid = { 6 | { 1, 3, 1 }, 7 | { 1, 5, 1 }, 8 | { 4, 2, 1 } 9 | }; 10 | int result = solution.minPathSum(grid); 11 | System.out.println(result); // Output: 7 12 | } 13 | } 14 | 15 | class Solution { 16 | public int minPathSum(int[][] grid) { 17 | int m = grid.length, n = grid[0].length; 18 | int[][] f = new int[m][n]; 19 | f[0][0] = grid[0][0]; 20 | for (int i = 1; i < m; ++i) { 21 | f[i][0] = f[i - 1][0] + grid[i][0]; 22 | } 23 | for (int j = 1; j < n; ++j) { 24 | f[0][j] = f[0][j - 1] + grid[0][j]; 25 | } 26 | for (int i = 1; i < m; ++i) { 27 | for (int j = 1; j < n; ++j) { 28 | f[i][j] = Math.min(f[i - 1][j], f[i][j - 1]) + grid[i][j]; 29 | } 30 | } 31 | return f[m - 1][n - 1]; 32 | } 33 | } -------------------------------------------------------------------------------- /Chapter 1/Problem65.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem65 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String s = "2e10"; 6 | boolean result = solution.isNumber(s); 7 | System.out.println(result); // Output: true 8 | } 9 | } 10 | 11 | class Solution { 12 | public boolean isNumber(String s) { 13 | int n = s.length(); 14 | int i = 0; 15 | if (s.charAt(i) == '+' || s.charAt(i) == '-') { 16 | ++i; 17 | } 18 | if (i == n) { 19 | return false; 20 | } 21 | if (s.charAt(i) == '.' 22 | && (i + 1 == n || s.charAt(i + 1) == 'e' || s.charAt(i + 1) == 'E')) { 23 | return false; 24 | } 25 | int dot = 0, e = 0; 26 | for (int j = i; j < n; ++j) { 27 | if (s.charAt(j) == '.') { 28 | if (e > 0 || dot > 0) { 29 | return false; 30 | } 31 | ++dot; 32 | } else if (s.charAt(j) == 'e' || s.charAt(j) == 'E') { 33 | if (e > 0 || j == i || j == n - 1) { 34 | return false; 35 | } 36 | ++e; 37 | if (s.charAt(j + 1) == '+' || s.charAt(j + 1) == '-') { 38 | if (++j == n - 1) { 39 | return false; 40 | } 41 | } 42 | } else if (s.charAt(j) < '0' || s.charAt(j) > '9') { 43 | return false; 44 | } 45 | } 46 | return true; 47 | } 48 | } -------------------------------------------------------------------------------- /Chapter 1/Problem66.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem66 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] digits = { 9, 9, 9 }; 6 | int[] result = solution.plusOne(digits); 7 | for (int digit : result) { 8 | System.out.print(digit + " "); 9 | } 10 | } 11 | } 12 | 13 | class Solution { 14 | public int[] plusOne(int[] digits) { 15 | int n = digits.length; 16 | for (int i = n - 1; i >= 0; --i) { 17 | ++digits[i]; 18 | digits[i] %= 10; 19 | if (digits[i] != 0) { 20 | return digits; 21 | } 22 | } 23 | digits = new int[n + 1]; 24 | digits[0] = 1; 25 | return digits; 26 | } 27 | } -------------------------------------------------------------------------------- /Chapter 1/Problem67.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem67 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String a = "1010"; 6 | String b = "1011"; 7 | String result = solution.addBinary(a, b); 8 | System.out.println(result); // Output: 11001 9 | } 10 | } 11 | 12 | class Solution { 13 | public String addBinary(String a, String b) { 14 | var sb = new StringBuilder(); 15 | int i = a.length() - 1, j = b.length() - 1; 16 | for (int carry = 0; i >= 0 || j >= 0 || carry > 0; --i, --j) { 17 | carry += (i >= 0 ? a.charAt(i) - '0' : 0) + (j >= 0 ? b.charAt(j) - '0' : 0); 18 | sb.append(carry % 2); 19 | carry /= 2; 20 | } 21 | return sb.reverse().toString(); 22 | } 23 | } -------------------------------------------------------------------------------- /Chapter 1/Problem68.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Problem68 { 5 | public static void main(String[] args) { 6 | Solution solution = new Solution(); 7 | String[] words = { "This", "is", "an", "example", "of", "text", "justification." }; 8 | int maxWidth = 16; 9 | List result = solution.fullJustify(words, maxWidth); 10 | for (String line : result) { 11 | System.out.println(line); 12 | } 13 | } 14 | } 15 | 16 | class Solution { 17 | public List fullJustify(String[] words, int maxWidth) { 18 | List ans = new ArrayList<>(); 19 | for (int i = 0, n = words.length; i < n;) { 20 | List t = new ArrayList<>(); 21 | t.add(words[i]); 22 | int cnt = words[i].length(); 23 | ++i; 24 | while (i < n && cnt + 1 + words[i].length() <= maxWidth) { 25 | cnt += 1 + words[i].length(); 26 | t.add(words[i++]); 27 | } 28 | if (i == n || t.size() == 1) { 29 | String left = String.join(" ", t); 30 | String right = " ".repeat(maxWidth - left.length()); 31 | ans.add(left + right); 32 | continue; 33 | } 34 | int spaceWidth = maxWidth - (cnt - t.size() + 1); 35 | int w = spaceWidth / (t.size() - 1); 36 | int m = spaceWidth % (t.size() - 1); 37 | StringBuilder row = new StringBuilder(); 38 | for (int j = 0; j < t.size() - 1; ++j) { 39 | row.append(t.get(j)); 40 | row.append(" ".repeat(w + (j < m ? 1 : 0))); 41 | } 42 | row.append(t.get(t.size() - 1)); 43 | ans.add(row.toString()); 44 | } 45 | return ans; 46 | } 47 | } -------------------------------------------------------------------------------- /Chapter 1/Problem7.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem7 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int x = 123; 6 | int result = solution.reverse(x); 7 | System.out.println("Reversed integer: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | public int reverse(int x) { 13 | int ans = 0; 14 | for (; x != 0; x /= 10) { 15 | if (ans < Integer.MIN_VALUE / 10 || ans > Integer.MAX_VALUE / 10) { 16 | return 0; 17 | } 18 | ans = ans * 10 + x % 10; 19 | } 20 | return ans; 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter 1/Problem70.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem70 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int n = 5; 6 | int result = solution.climbStairs(n); 7 | System.out.println(result); // Output: 8 8 | } 9 | } 10 | 11 | class Solution { 12 | public int climbStairs(int n) { 13 | int a = 0, b = 1; 14 | for (int i = 0; i < n; ++i) { 15 | int c = a + b; 16 | a = b; 17 | b = c; 18 | } 19 | return b; 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter 1/Problem71.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayDeque; 2 | import java.util.Deque; 3 | 4 | public class Problem71 { 5 | public static void main(String[] args) { 6 | Solution solution = new Solution(); 7 | String path = "/a/./b/../../c/"; 8 | String result = solution.simplifyPath(path); 9 | System.out.println(result); // Output: "/c" 10 | } 11 | } 12 | 13 | class Solution { 14 | public String simplifyPath(String path) { 15 | Deque stk = new ArrayDeque<>(); 16 | for (String s : path.split("/")) { 17 | if ("".equals(s) || ".".equals(s)) { 18 | continue; 19 | } 20 | if ("..".equals(s)) { 21 | stk.pollLast(); 22 | } else { 23 | stk.offerLast(s); 24 | } 25 | } 26 | return "/" + String.join("/", stk); 27 | } 28 | } -------------------------------------------------------------------------------- /Chapter 1/Problem72.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem72 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String word1 = "horse"; 6 | String word2 = "ros"; 7 | int result = solution.minDistance(word1, word2); 8 | System.out.println(result); // Output: 3 9 | } 10 | } 11 | 12 | class Solution { 13 | public int minDistance(String word1, String word2) { 14 | int m = word1.length(), n = word2.length(); 15 | int[][] f = new int[m + 1][n + 1]; 16 | for (int j = 1; j <= n; ++j) { 17 | f[0][j] = j; 18 | } 19 | for (int i = 1; i <= m; ++i) { 20 | f[i][0] = i; 21 | for (int j = 1; j <= n; ++j) { 22 | if (word1.charAt(i - 1) == word2.charAt(j - 1)) { 23 | f[i][j] = f[i - 1][j - 1]; 24 | } else { 25 | f[i][j] = Math.min(f[i - 1][j], Math.min(f[i][j - 1], f[i - 1][j - 1])) + 1; 26 | } 27 | } 28 | } 29 | return f[m][n]; 30 | } 31 | } -------------------------------------------------------------------------------- /Chapter 1/Problem73.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem73 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[][] matrix = { 6 | { 1, 1, 1 }, 7 | { 1, 0, 1 }, 8 | { 1, 1, 1 } 9 | }; 10 | solution.setZeroes(matrix); 11 | for (int[] row : matrix) { 12 | for (int num : row) { 13 | System.out.print(num + " "); 14 | } 15 | System.out.println(); 16 | } 17 | } 18 | } 19 | 20 | class Solution { 21 | public void setZeroes(int[][] matrix) { 22 | int m = matrix.length, n = matrix[0].length; 23 | boolean i0 = false, j0 = false; 24 | for (int j = 0; j < n; ++j) { 25 | if (matrix[0][j] == 0) { 26 | i0 = true; 27 | break; 28 | } 29 | } 30 | for (int i = 0; i < m; ++i) { 31 | if (matrix[i][0] == 0) { 32 | j0 = true; 33 | break; 34 | } 35 | } 36 | for (int i = 1; i < m; ++i) { 37 | for (int j = 1; j < n; ++j) { 38 | if (matrix[i][j] == 0) { 39 | matrix[i][0] = 0; 40 | matrix[0][j] = 0; 41 | } 42 | } 43 | } 44 | for (int i = 1; i < m; ++i) { 45 | for (int j = 1; j < n; ++j) { 46 | if (matrix[i][0] == 0 || matrix[0][j] == 0) { 47 | matrix[i][j] = 0; 48 | } 49 | } 50 | } 51 | if (i0) { 52 | for (int j = 0; j < n; ++j) { 53 | matrix[0][j] = 0; 54 | } 55 | } 56 | if (j0) { 57 | for (int i = 0; i < m; ++i) { 58 | matrix[i][0] = 0; 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /Chapter 1/Problem74.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem74 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[][] matrix = { 6 | { 1, 3, 5, 7 }, 7 | { 10, 11, 16, 20 }, 8 | { 23, 30, 34, 50 }, 9 | { 60, 61, 62, 63 } 10 | }; 11 | int target = 3; 12 | boolean result = solution.searchMatrix(matrix, target); 13 | System.out.println(result); // Output: true 14 | } 15 | } 16 | 17 | class Solution { 18 | public boolean searchMatrix(int[][] matrix, int target) { 19 | int m = matrix.length, n = matrix[0].length; 20 | int left = 0, right = m * n - 1; 21 | while (left < right) { 22 | int mid = (left + right) >> 1; 23 | int x = mid / n, y = mid % n; 24 | if (matrix[x][y] >= target) { 25 | right = mid; 26 | } else { 27 | left = mid + 1; 28 | } 29 | } 30 | return matrix[left / n][left % n] == target; 31 | } 32 | } -------------------------------------------------------------------------------- /Chapter 1/Problem75.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem75 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 2, 0, 2, 1, 1, 0 }; 6 | solution.sortColors(nums); 7 | for (int num : nums) { 8 | System.out.print(num + " "); 9 | } 10 | } 11 | } 12 | 13 | class Solution { 14 | public void sortColors(int[] nums) { 15 | int i = -1, j = nums.length, k = 0; 16 | while (k < j) { 17 | if (nums[k] == 0) { 18 | swap(nums, ++i, k++); 19 | } else if (nums[k] == 2) { 20 | swap(nums, --j, k); 21 | } else { 22 | ++k; 23 | } 24 | } 25 | } 26 | 27 | private void swap(int[] nums, int i, int j) { 28 | int t = nums[i]; 29 | nums[i] = nums[j]; 30 | nums[j] = t; 31 | } 32 | } -------------------------------------------------------------------------------- /Chapter 1/Problem76.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem76 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | String s = "ADOBECODEBANC"; 6 | String t = "ABC"; 7 | String result = solution.minWindow(s, t); 8 | System.out.println(result); // Output: "BANC" 9 | } 10 | } 11 | 12 | class Solution { 13 | public String minWindow(String s, String t) { 14 | int[] need = new int[128]; 15 | int[] window = new int[128]; 16 | int m = s.length(), n = t.length(); 17 | for (int i = 0; i < n; ++i) { 18 | ++need[t.charAt(i)]; 19 | } 20 | int cnt = 0, j = 0, k = -1, mi = 1 << 30; 21 | for (int i = 0; i < m; ++i) { 22 | ++window[s.charAt(i)]; 23 | if (need[s.charAt(i)] >= window[s.charAt(i)]) { 24 | ++cnt; 25 | } 26 | while (cnt == n) { 27 | if (i - j + 1 < mi) { 28 | mi = i - j + 1; 29 | k = j; 30 | } 31 | if (need[s.charAt(j)] >= window[s.charAt(j)]) { 32 | --cnt; 33 | } 34 | --window[s.charAt(j++)]; 35 | } 36 | } 37 | return k < 0 ? "" : s.substring(k, k + mi); 38 | } 39 | } -------------------------------------------------------------------------------- /Chapter 1/Problem77.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Problem77 { 5 | public static void main(String[] args) { 6 | Solution solution = new Solution(); 7 | int n = 4, k = 2; 8 | List> result = solution.combine(n, k); 9 | for (List combination : result) { 10 | System.out.println(combination); 11 | } 12 | } 13 | } 14 | 15 | class Solution { 16 | public List> combine(int n, int k) { 17 | List> res = new ArrayList<>(); 18 | dfs(1, n, k, new ArrayList<>(), res); 19 | return res; 20 | } 21 | 22 | private void dfs(int i, int n, int k, List t, List> res) { 23 | if (t.size() == k) { 24 | res.add(new ArrayList<>(t)); 25 | return; 26 | } 27 | for (int j = i; j <= n; ++j) { 28 | t.add(j); 29 | dfs(j + 1, n, k, t, res); 30 | t.remove(t.size() - 1); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Chapter 1/Problem78.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Problem78 { 5 | public static void main(String[] args) { 6 | Solution solution = new Solution(); 7 | int[] nums = { 1, 2, 3 }; 8 | List> result = solution.subsets(nums); 9 | for (List subset : result) { 10 | System.out.println(subset); 11 | } 12 | } 13 | } 14 | 15 | class Solution { 16 | private List> ans = new ArrayList<>(); 17 | private List t = new ArrayList<>(); 18 | private int[] nums; 19 | 20 | public List> subsets(int[] nums) { 21 | this.nums = nums; 22 | dfs(0); 23 | return ans; 24 | } 25 | 26 | private void dfs(int i) { 27 | if (i == nums.length) { 28 | ans.add(new ArrayList<>(t)); 29 | return; 30 | } 31 | dfs(i + 1); 32 | t.add(nums[i]); 33 | dfs(i + 1); 34 | t.remove(t.size() - 1); 35 | } 36 | } -------------------------------------------------------------------------------- /Chapter 1/Problem79.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem79 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | char[][] board = { 6 | { 'A', 'B', 'C', 'E' }, 7 | { 'S', 'F', 'C', 'S' }, 8 | { 'A', 'D', 'E', 'E' } 9 | }; 10 | String word = "ABCCED"; 11 | boolean result = solution.exist(board, word); 12 | System.out.println(result); // Output: false 13 | } 14 | } 15 | 16 | class Solution { 17 | private int m; 18 | private int n; 19 | private String word; 20 | private char[][] board; 21 | 22 | public boolean exist(char[][] board, String word) { 23 | m = board.length; 24 | n = board[0].length; 25 | this.word = word; 26 | this.board = board; 27 | for (int i = 0; i < m; ++i) { 28 | for (int j = 0; j < n; ++j) { 29 | if (dfs(i, j, 0)) { 30 | return true; 31 | } 32 | } 33 | } 34 | return false; 35 | } 36 | 37 | private boolean dfs(int i, int j, int k) { 38 | if (k == word.length() - 1) { 39 | return board[i][j] == word.charAt(k); 40 | } 41 | if (board[i][j] != word.charAt(k)) { 42 | return false; 43 | } 44 | char c = board[i][j]; 45 | board[i][j] = '0'; 46 | int[] dirs = { -1, 0, 1, 0, -1 }; 47 | for (int u = 0; u < 4; ++u) { 48 | int x = i + dirs[u], y = j + dirs[u + 1]; 49 | if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '0' && dfs(x, y, k + 1)) { 50 | return true; 51 | } 52 | } 53 | board[i][j] = c; 54 | return false; 55 | } 56 | } -------------------------------------------------------------------------------- /Chapter 1/Problem80.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem80 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 1, 1, 1, 2, 2, 3 }; 6 | int k = solution.removeDuplicates(nums); 7 | System.out.println(k); // Output: 5 8 | for (int i = 0; i < k; i++) { 9 | System.out.print(nums[i] + " "); 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public int removeDuplicates(int[] nums) { 16 | int k = 0; 17 | for (int x : nums) { 18 | if (k < 2 || x != nums[k - 2]) { 19 | nums[k++] = x; 20 | } 21 | } 22 | return k; 23 | } 24 | } -------------------------------------------------------------------------------- /Chapter 1/Problem81.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem81 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 2, 5, 6, 0, 0, 1, 2 }; 6 | int target = 0; 7 | boolean result = solution.search(nums, target); 8 | System.out.println(result); // Output: true 9 | } 10 | } 11 | 12 | class Solution { 13 | public boolean search(int[] nums, int target) { 14 | int l = 0, r = nums.length - 1; 15 | while (l < r) { 16 | int mid = (l + r) >> 1; 17 | if (nums[mid] > nums[r]) { 18 | if (nums[l] <= target && target <= nums[mid]) { 19 | r = mid; 20 | } else { 21 | l = mid + 1; 22 | } 23 | } else if (nums[mid] < nums[r]) { 24 | if (nums[mid] < target && target <= nums[r]) { 25 | l = mid + 1; 26 | } else { 27 | r = mid; 28 | } 29 | } else { 30 | --r; 31 | } 32 | } 33 | return nums[l] == target; 34 | } 35 | } -------------------------------------------------------------------------------- /Chapter 1/Problem82.java: -------------------------------------------------------------------------------- 1 | public class Problem82 { 2 | public static void main(String[] args) { 3 | ListNode head = new ListNode(1, 4 | new ListNode(2, new ListNode(3, new ListNode(3, new ListNode(4, new ListNode(4, new ListNode(5))))))); 5 | Solution solution = new Solution(); 6 | ListNode result = solution.deleteDuplicates(head); 7 | while (result != null) { 8 | System.out.print(result.val + " "); 9 | result = result.next; 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public ListNode deleteDuplicates(ListNode head) { 16 | ListNode dummy = new ListNode(0, head); 17 | ListNode pre = dummy; 18 | ListNode cur = head; 19 | while (cur != null) { 20 | while (cur.next != null && cur.next.val == cur.val) { 21 | cur = cur.next; 22 | } 23 | if (pre.next == cur) { 24 | pre = cur; 25 | } else { 26 | pre.next = cur.next; 27 | } 28 | cur = cur.next; 29 | } 30 | return dummy.next; 31 | } 32 | } -------------------------------------------------------------------------------- /Chapter 1/Problem83.java: -------------------------------------------------------------------------------- 1 | public class Problem83 { 2 | public static void main(String[] args) { 3 | ListNode head = new ListNode(1, 4 | new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(3))))); 5 | Solution solution = new Solution(); 6 | ListNode result = solution.deleteDuplicates(head); 7 | while (result != null) { 8 | System.out.print(result.val + " "); 9 | result = result.next; 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public ListNode deleteDuplicates(ListNode head) { 16 | ListNode cur = head; 17 | while (cur != null && cur.next != null) { 18 | if (cur.val == cur.next.val) { 19 | cur.next = cur.next.next; 20 | } else { 21 | cur = cur.next; 22 | } 23 | } 24 | return head; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter 1/Problem84.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayDeque; 2 | import java.util.Arrays; 3 | import java.util.Deque; 4 | 5 | public class Problem84 { 6 | public static void main(String[] args) { 7 | Solution solution = new Solution(); 8 | int[] heights = { 2, 1, 5, 6, 2, 3 }; 9 | int result = solution.largestRectangleArea(heights); 10 | System.out.println("Largest Rectangle Area: " + result); 11 | } 12 | } 13 | 14 | class Solution { 15 | public int largestRectangleArea(int[] heights) { 16 | int res = 0, n = heights.length; 17 | Deque stk = new ArrayDeque<>(); 18 | int[] left = new int[n]; 19 | int[] right = new int[n]; 20 | Arrays.fill(right, n); 21 | for (int i = 0; i < n; ++i) { 22 | while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) { 23 | right[stk.pop()] = i; 24 | } 25 | left[i] = stk.isEmpty() ? -1 : stk.peek(); 26 | stk.push(i); 27 | } 28 | for (int i = 0; i < n; ++i) { 29 | res = Math.max(res, heights[i] * (right[i] - left[i] - 1)); 30 | } 31 | return res; 32 | } 33 | } -------------------------------------------------------------------------------- /Chapter 1/Problem85.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayDeque; 2 | import java.util.Arrays; 3 | import java.util.Deque; 4 | 5 | public class Problem85 { 6 | public static void main(String[] args) { 7 | Solution solution = new Solution(); 8 | char[][] matrix = { 9 | { '1', '0', '1', '0', '0' }, 10 | { '1', '0', '1', '1', '1' }, 11 | { '1', '1', '1', '1', '1' }, 12 | { '1', '0', '0', '1', '0' } 13 | }; 14 | int result = solution.maximalRectangle(matrix); 15 | System.out.println("Maximal Rectangle Area: " + result); 16 | } 17 | } 18 | 19 | class Solution { 20 | public int maximalRectangle(char[][] matrix) { 21 | int n = matrix[0].length; 22 | int[] heights = new int[n]; 23 | int ans = 0; 24 | for (var row : matrix) { 25 | for (int j = 0; j < n; ++j) { 26 | if (row[j] == '1') { 27 | heights[j] += 1; 28 | } else { 29 | heights[j] = 0; 30 | } 31 | } 32 | ans = Math.max(ans, largestRectangleArea(heights)); 33 | } 34 | return ans; 35 | } 36 | 37 | private int largestRectangleArea(int[] heights) { 38 | int res = 0, n = heights.length; 39 | Deque stk = new ArrayDeque<>(); 40 | int[] left = new int[n]; 41 | int[] right = new int[n]; 42 | Arrays.fill(right, n); 43 | for (int i = 0; i < n; ++i) { 44 | while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) { 45 | right[stk.pop()] = i; 46 | } 47 | left[i] = stk.isEmpty() ? -1 : stk.peek(); 48 | stk.push(i); 49 | } 50 | for (int i = 0; i < n; ++i) { 51 | res = Math.max(res, heights[i] * (right[i] - left[i] - 1)); 52 | } 53 | return res; 54 | } 55 | } -------------------------------------------------------------------------------- /Chapter 1/Problem86.java: -------------------------------------------------------------------------------- 1 | public class Problem86 { 2 | public static void main(String[] args) { 3 | ListNode head = new ListNode(1, 4 | new ListNode(4, new ListNode(3, new ListNode(2, new ListNode(5, new ListNode(2)))))); 5 | int x = 3; 6 | Solution solution = new Solution(); 7 | ListNode result = solution.partition(head, x); 8 | while (result != null) { 9 | System.out.print(result.val + " "); 10 | result = result.next; 11 | } 12 | } 13 | } 14 | 15 | class Solution { 16 | public ListNode partition(ListNode head, int x) { 17 | ListNode d1 = new ListNode(); 18 | ListNode d2 = new ListNode(); 19 | ListNode t1 = d1, t2 = d2; 20 | while (head != null) { 21 | if (head.val < x) { 22 | t1.next = head; 23 | t1 = t1.next; 24 | } else { 25 | t2.next = head; 26 | t2 = t2.next; 27 | } 28 | head = head.next; 29 | } 30 | t1.next = d2.next; 31 | t2.next = null; 32 | return d1.next; 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter 1/Problem87.java: -------------------------------------------------------------------------------- 1 | public class Problem87 { 2 | public static void main(String[] args) { 3 | String s1 = "great"; 4 | String s2 = "rgeat"; 5 | Solution solution = new Solution(); 6 | boolean result = solution.isScramble(s1, s2); 7 | System.out.println("Is Scramble: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | private Boolean[][][] f; 13 | private String s1; 14 | private String s2; 15 | 16 | public boolean isScramble(String s1, String s2) { 17 | int n = s1.length(); 18 | this.s1 = s1; 19 | this.s2 = s2; 20 | f = new Boolean[n][n][n + 1]; 21 | return dfs(0, 0, n); 22 | } 23 | 24 | private boolean dfs(int i, int j, int k) { 25 | if (f[i][j][k] != null) { 26 | return f[i][j][k]; 27 | } 28 | if (k == 1) { 29 | return s1.charAt(i) == s2.charAt(j); 30 | } 31 | for (int h = 1; h < k; ++h) { 32 | if (dfs(i, j, h) && dfs(i + h, j + h, k - h)) { 33 | return f[i][j][k] = true; 34 | } 35 | if (dfs(i + h, j, k - h) && dfs(i, j + k - h, h)) { 36 | return f[i][j][k] = true; 37 | } 38 | } 39 | return f[i][j][k] = false; 40 | } 41 | } -------------------------------------------------------------------------------- /Chapter 1/Problem88.java: -------------------------------------------------------------------------------- 1 | public class Problem88 { 2 | public static void main(String[] args) { 3 | int[] nums1 = { 1, 2, 3, 0, 0, 0 }; 4 | int m = 3; 5 | int[] nums2 = { 2, 5, 6 }; 6 | int n = 3; 7 | Solution solution = new Solution(); 8 | solution.merge(nums1, m, nums2, n); 9 | for (int num : nums1) { 10 | System.out.print(num + " "); 11 | } 12 | } 13 | } 14 | 15 | class Solution { 16 | public void merge(int[] nums1, int m, int[] nums2, int n) { 17 | for (int i = m - 1, j = n - 1, k = m + n - 1; j >= 0; --k) { 18 | nums1[k] = i >= 0 && nums1[i] > nums2[j] ? nums1[i--] : nums2[j--]; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter 1/Problem89.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Problem89 { 5 | public static void main(String[] args) { 6 | int n = 3; 7 | Solution solution = new Solution(); 8 | List result = solution.grayCode(n); 9 | System.out.println("Gray Code: " + result); 10 | } 11 | } 12 | 13 | class Solution { 14 | public List grayCode(int n) { 15 | List ans = new ArrayList<>(); 16 | for (int i = 0; i < (1 << n); ++i) { 17 | ans.add(i ^ (i >> 1)); 18 | } 19 | return ans; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter 1/Problem9.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem9 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int x = 121; 6 | boolean result = solution.isPalindrome(x); 7 | System.out.println("Is palindrome: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | public boolean isPalindrome(int x) { 13 | if (x < 0 || (x > 0 && x % 10 == 0)) { 14 | return false; 15 | } 16 | int y = 0; 17 | for (; y < x; x /= 10) { 18 | y = y * 10 + x % 10; 19 | } 20 | return x == y || x == y / 10; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter 1/Problem90.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Arrays; 3 | import java.util.List; 4 | 5 | public class Problem90 { 6 | public static void main(String[] args) { 7 | int[] nums = { 1, 2, 2 }; 8 | Solution solution = new Solution(); 9 | List> result = solution.subsetsWithDup(nums); 10 | for (List subset : result) { 11 | System.out.println(subset); 12 | } 13 | } 14 | } 15 | 16 | class Solution { 17 | public List> subsetsWithDup(int[] nums) { 18 | Arrays.sort(nums); 19 | int n = nums.length; 20 | List> ans = new ArrayList<>(); 21 | for (int mask = 0; mask < 1 << n; ++mask) { 22 | List t = new ArrayList<>(); 23 | boolean ok = true; 24 | for (int i = 0; i < n; ++i) { 25 | if ((mask >> i & 1) == 1) { 26 | if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { 27 | ok = false; 28 | break; 29 | } 30 | t.add(nums[i]); 31 | } 32 | } 33 | if (ok) { 34 | ans.add(t); 35 | } 36 | } 37 | return ans; 38 | } 39 | } -------------------------------------------------------------------------------- /Chapter 1/Problem91.java: -------------------------------------------------------------------------------- 1 | public class Problem91 { 2 | public static void main(String[] args) { 3 | String s = "226"; 4 | Solution solution = new Solution(); 5 | int result = solution.numDecodings(s); 6 | System.out.println("Number of ways to decode: " + result); 7 | } 8 | } 9 | 10 | class Solution { 11 | public int numDecodings(String s) { 12 | int n = s.length(); 13 | int f = 0, g = 1; 14 | for (int i = 1; i <= n; ++i) { 15 | int h = s.charAt(i - 1) != '0' ? g : 0; 16 | if (i > 1 && s.charAt(i - 2) != '0' && Integer.valueOf(s.substring(i - 2, i)) <= 26) { 17 | h += f; 18 | } 19 | f = g; 20 | g = h; 21 | } 22 | return g; 23 | } 24 | } -------------------------------------------------------------------------------- /Chapter 1/Problem92.java: -------------------------------------------------------------------------------- 1 | public class Problem92 { 2 | public static void main(String[] args) { 3 | ListNode head = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5))))); 4 | int left = 2; 5 | int right = 4; 6 | Solution solution = new Solution(); 7 | ListNode result = solution.reverseBetween(head, left, right); 8 | while (result != null) { 9 | System.out.print(result.val + " "); 10 | result = result.next; 11 | } 12 | } 13 | } 14 | 15 | class Solution { 16 | public ListNode reverseBetween(ListNode head, int left, int right) { 17 | if (head.next == null || left == right) { 18 | return head; 19 | } 20 | ListNode dummy = new ListNode(0, head); 21 | ListNode pre = dummy; 22 | for (int i = 0; i < left - 1; ++i) { 23 | pre = pre.next; 24 | } 25 | ListNode p = pre; 26 | ListNode q = pre.next; 27 | ListNode cur = q; 28 | for (int i = 0; i < right - left + 1; ++i) { 29 | ListNode t = cur.next; 30 | cur.next = pre; 31 | pre = cur; 32 | cur = t; 33 | } 34 | p.next = pre; 35 | q.next = cur; 36 | return dummy.next; 37 | } 38 | } -------------------------------------------------------------------------------- /Chapter 1/Problem93.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Problem93 { 5 | public static void main(String[] args) { 6 | String s = "25525511135"; 7 | Solution solution = new Solution(); 8 | List result = solution.restoreIpAddresses(s); 9 | System.out.println("Valid IP addresses: " + result); 10 | } 11 | } 12 | 13 | class Solution { 14 | private int n; 15 | private String s; 16 | private List ans = new ArrayList<>(); 17 | private List t = new ArrayList<>(); 18 | 19 | public List restoreIpAddresses(String s) { 20 | n = s.length(); 21 | this.s = s; 22 | dfs(0); 23 | return ans; 24 | } 25 | 26 | private void dfs(int i) { 27 | if (i >= n && t.size() == 4) { 28 | ans.add(String.join(".", t)); 29 | return; 30 | } 31 | if (i >= n || t.size() >= 4) { 32 | return; 33 | } 34 | int x = 0; 35 | for (int j = i; j < Math.min(i + 3, n); ++j) { 36 | x = x * 10 + s.charAt(j) - '0'; 37 | if (x > 255 || (s.charAt(i) == '0' && i != j)) { 38 | break; 39 | } 40 | t.add(s.substring(i, j + 1)); 41 | dfs(j + 1); 42 | t.remove(t.size() - 1); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Chapter 1/Problem94.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Problem94 { 5 | public static void main(String[] args) { 6 | TreeNode root = new TreeNode(1, null, new TreeNode(2, new TreeNode(3), null)); 7 | Solution solution = new Solution(); 8 | List result = solution.inorderTraversal(root); 9 | System.out.println("Inorder Traversal: " + result); 10 | } 11 | } 12 | 13 | class TreeNode { 14 | int val; 15 | TreeNode left; 16 | TreeNode right; 17 | 18 | TreeNode() { 19 | } 20 | 21 | TreeNode(int val) { 22 | this.val = val; 23 | } 24 | 25 | TreeNode(int val, TreeNode left, TreeNode right) { 26 | this.val = val; 27 | this.left = left; 28 | this.right = right; 29 | } 30 | } 31 | 32 | class Solution { 33 | public List inorderTraversal(TreeNode root) { 34 | List ans = new ArrayList<>(); 35 | 36 | while (root != null) { 37 | if (root.left == null) { 38 | ans.add(root.val); 39 | root = root.right; 40 | } else { 41 | TreeNode prev = root.left; 42 | while (prev.right != null && prev.right != root) { 43 | prev = prev.right; 44 | } 45 | 46 | if (prev.right == null) { 47 | prev.right = root; 48 | root = root.left; 49 | } else { 50 | ans.add(root.val); 51 | prev.right = null; 52 | root = root.right; 53 | } 54 | } 55 | } 56 | 57 | return ans; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Chapter 1/Problem95.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Problem95 { 5 | public static void main(String[] args) { 6 | int n = 3; 7 | Solution solution = new Solution(); 8 | List result = solution.generateTrees(n); 9 | System.out.println("Unique BSTs: " + result.size()); 10 | for (TreeNode tree : result) { 11 | printTree(tree); 12 | System.out.println(); 13 | } 14 | } 15 | 16 | private static void printTree(TreeNode root) { 17 | if (root == null) { 18 | return; 19 | } 20 | System.out.print(root.val + " "); 21 | printTree(root.left); 22 | printTree(root.right); 23 | } 24 | } 25 | 26 | class Solution { 27 | public List generateTrees(int n) { 28 | return dfs(1, n); 29 | } 30 | 31 | private List dfs(int i, int j) { 32 | List ans = new ArrayList<>(); 33 | if (i > j) { 34 | ans.add(null); 35 | return ans; 36 | } 37 | for (int v = i; v <= j; ++v) { 38 | var left = dfs(i, v - 1); 39 | var right = dfs(v + 1, j); 40 | for (var l : left) { 41 | for (var r : right) { 42 | ans.add(new TreeNode(v, l, r)); 43 | } 44 | } 45 | } 46 | return ans; 47 | } 48 | } -------------------------------------------------------------------------------- /Chapter 1/Problem96.java: -------------------------------------------------------------------------------- 1 | public class Problem96 { 2 | public static void main(String[] args) { 3 | int n = 3; 4 | Solution solution = new Solution(); 5 | int result = solution.numTrees(n); 6 | System.out.println("Number of unique BSTs: " + result); 7 | } 8 | } 9 | 10 | class Solution { 11 | public int numTrees(int n) { 12 | int[] dp = new int[n + 1]; 13 | dp[0] = 1; 14 | for (int i = 1; i <= n; ++i) { 15 | for (int j = 0; j < i; ++j) { 16 | dp[i] += dp[j] * dp[i - j - 1]; 17 | } 18 | } 19 | return dp[n]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter 1/Problem97.java: -------------------------------------------------------------------------------- 1 | public class Problem97 { 2 | public static void main(String[] args) { 3 | Solution solution = new Solution(); 4 | String s1 = "aab"; 5 | String s2 = "axy"; 6 | String s3 = "aaxaby"; 7 | boolean result = solution.isInterleave(s1, s2, s3); 8 | System.out.println("Is Interleaving: " + result); 9 | } 10 | } 11 | 12 | class Solution { 13 | public boolean isInterleave(String s1, String s2, String s3) { 14 | int m = s1.length(), n = s2.length(); 15 | if (m + n != s3.length()) { 16 | return false; 17 | } 18 | boolean[] f = new boolean[n + 1]; 19 | f[0] = true; 20 | for (int i = 0; i <= m; ++i) { 21 | for (int j = 0; j <= n; ++j) { 22 | int k = i + j - 1; 23 | if (i > 0) { 24 | f[j] &= s1.charAt(i - 1) == s3.charAt(k); 25 | } 26 | if (j > 0) { 27 | f[j] |= (f[j - 1] & s2.charAt(j - 1) == s3.charAt(k)); 28 | } 29 | } 30 | } 31 | return f[n]; 32 | } 33 | } -------------------------------------------------------------------------------- /Chapter 1/Problem98.java: -------------------------------------------------------------------------------- 1 | public class Problem98 { 2 | public static void main(String[] args) { 3 | TreeNode root = new TreeNode(2, new TreeNode(1), new TreeNode(3)); 4 | Solution solution = new Solution(); 5 | boolean result = solution.isValidBST(root); 6 | System.out.println("Is Valid BST: " + result); 7 | } 8 | } 9 | 10 | class Solution { 11 | private Integer prev; 12 | 13 | public boolean isValidBST(TreeNode root) { 14 | prev = null; 15 | return dfs(root); 16 | } 17 | 18 | private boolean dfs(TreeNode root) { 19 | if (root == null) { 20 | return true; 21 | } 22 | if (!dfs(root.left)) { 23 | return false; 24 | } 25 | if (prev != null && prev >= root.val) { 26 | return false; 27 | } 28 | prev = root.val; 29 | if (!dfs(root.right)) { 30 | return false; 31 | } 32 | return true; 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter 1/Problem99.java: -------------------------------------------------------------------------------- 1 | public class Problem99 { 2 | public static void main(String[] args) { 3 | TreeNode root = new TreeNode(1, new TreeNode(3), new TreeNode(2)); 4 | Solution solution = new Solution(); 5 | solution.recoverTree(root); 6 | // Output the tree after recovery 7 | System.out.println("Recovered tree root: " + root.val); 8 | } 9 | } 10 | 11 | class Solution { 12 | private TreeNode prev; 13 | private TreeNode first; 14 | private TreeNode second; 15 | 16 | public void recoverTree(TreeNode root) { 17 | dfs(root); 18 | int t = first.val; 19 | first.val = second.val; 20 | second.val = t; 21 | } 22 | 23 | private void dfs(TreeNode root) { 24 | if (root == null) { 25 | return; 26 | } 27 | dfs(root.left); 28 | if (prev != null && prev.val > root.val) { 29 | if (first == null) { 30 | first = prev; 31 | } 32 | second = root; 33 | } 34 | prev = root; 35 | dfs(root.right); 36 | } 37 | } -------------------------------------------------------------------------------- /Chapter 2/Problem101.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem101 { 3 | public static void main(String[] args) { 4 | TreeNode root = new TreeNode(1, new TreeNode(2), new TreeNode(2)); 5 | Solution solution = new Solution(); 6 | boolean result = solution.isSymmetric(root); 7 | System.out.println("Is Symmetric: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | public boolean isSymmetric(TreeNode root) { 13 | return dfs(root, root); 14 | } 15 | 16 | private boolean dfs(TreeNode root1, TreeNode root2) { 17 | if (root1 == null && root2 == null) { 18 | return true; 19 | } 20 | if (root1 == null || root2 == null || root1.val != root2.val) { 21 | return false; 22 | } 23 | return dfs(root1.left, root2.right) && dfs(root1.right, root2.left); 24 | } 25 | } -------------------------------------------------------------------------------- /Chapter 2/Problem102.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayDeque; 2 | import java.util.ArrayList; 3 | import java.util.Deque; 4 | import java.util.List; 5 | 6 | public class Problem102 { 7 | public static void main(String[] args) { 8 | TreeNode root = new TreeNode(3, new TreeNode(9), new TreeNode(20, new TreeNode(15), new TreeNode(7))); 9 | Solution solution = new Solution(); 10 | List> result = solution.levelOrder(root); 11 | System.out.println("Level Order Traversal: " + result); 12 | } 13 | } 14 | 15 | class Solution { 16 | public List> levelOrder(TreeNode root) { 17 | List> ans = new ArrayList<>(); 18 | if (root == null) { 19 | return ans; 20 | } 21 | Deque q = new ArrayDeque<>(); 22 | q.offer(root); 23 | while (!q.isEmpty()) { 24 | List t = new ArrayList<>(); 25 | for (int n = q.size(); n > 0; --n) { 26 | TreeNode node = q.poll(); 27 | t.add(node.val); 28 | if (node.left != null) { 29 | q.offer(node.left); 30 | } 31 | if (node.right != null) { 32 | q.offer(node.right); 33 | } 34 | } 35 | ans.add(t); 36 | } 37 | return ans; 38 | } 39 | } -------------------------------------------------------------------------------- /Chapter 2/Problem103.java: -------------------------------------------------------------------------------- 1 | import java.util.List; 2 | import java.util.ArrayList; 3 | import java.util.ArrayDeque; 4 | import java.util.Deque; 5 | import java.util.Collections; 6 | 7 | public class Problem103 { 8 | public static void main(String[] args) { 9 | TreeNode root = new TreeNode(3, new TreeNode(9), new TreeNode(20, new TreeNode(15), new TreeNode(7))); 10 | Solution solution = new Solution(); 11 | List> result = solution.zigzagLevelOrder(root); 12 | System.out.println("Zigzag Level Order Traversal: " + result); 13 | } 14 | } 15 | 16 | class Solution { 17 | public List> zigzagLevelOrder(TreeNode root) { 18 | List> ans = new ArrayList<>(); 19 | if (root == null) { 20 | return ans; 21 | } 22 | Deque q = new ArrayDeque<>(); 23 | q.offer(root); 24 | boolean left = true; 25 | while (!q.isEmpty()) { 26 | List t = new ArrayList<>(); 27 | for (int n = q.size(); n > 0; --n) { 28 | TreeNode node = q.poll(); 29 | t.add(node.val); 30 | if (node.left != null) { 31 | q.offer(node.left); 32 | } 33 | if (node.right != null) { 34 | q.offer(node.right); 35 | } 36 | } 37 | if (!left) { 38 | Collections.reverse(t); 39 | } 40 | ans.add(t); 41 | left = !left; 42 | } 43 | return ans; 44 | } 45 | } -------------------------------------------------------------------------------- /Chapter 2/Problem104.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem104 { 3 | public static void main(String[] args) { 4 | TreeNode root = new TreeNode(3, new TreeNode(9), new TreeNode(20, new TreeNode(15), new TreeNode(7))); 5 | Solution solution = new Solution(); 6 | int result = solution.maxDepth(root); 7 | System.out.println("Max Depth: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | public int maxDepth(TreeNode root) { 13 | if (root == null) { 14 | return 0; 15 | } 16 | int l = maxDepth(root.left); 17 | int r = maxDepth(root.right); 18 | return 1 + Math.max(l, r); 19 | } 20 | } -------------------------------------------------------------------------------- /Chapter 2/Problem105.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem105 { 4 | public static void main(String[] args) { 5 | int[] preorder = { 3, 9, 20, 15, 7 }; 6 | int[] inorder = { 9, 3, 15, 20, 7 }; 7 | Solution solution = new Solution(); 8 | TreeNode root = solution.buildTree(preorder, inorder); 9 | System.out.println("Root: " + root.val); 10 | } 11 | } 12 | 13 | class Solution { 14 | private int[] preorder; 15 | private Map d = new HashMap<>(); 16 | 17 | public TreeNode buildTree(int[] preorder, int[] inorder) { 18 | int n = preorder.length; 19 | this.preorder = preorder; 20 | for (int i = 0; i < n; ++i) { 21 | d.put(inorder[i], i); 22 | } 23 | return dfs(0, 0, n); 24 | } 25 | 26 | private TreeNode dfs(int i, int j, int n) { 27 | if (n <= 0) { 28 | return null; 29 | } 30 | int v = preorder[i]; 31 | int k = d.get(v); 32 | TreeNode l = dfs(i + 1, j, k - j); 33 | TreeNode r = dfs(i + 1 + k - j, k + 1, n - 1 - (k - j)); 34 | return new TreeNode(v, l, r); 35 | } 36 | } -------------------------------------------------------------------------------- /Chapter 2/Problem106.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem106 { 4 | public static void main(String[] args) { 5 | int[] inorder = { 9, 3, 15, 20, 7 }; 6 | int[] postorder = { 9, 15, 7, 20, 3 }; 7 | Solution solution = new Solution(); 8 | TreeNode root = solution.buildTree(inorder, postorder); 9 | System.out.println("Root: " + root.val); 10 | } 11 | } 12 | 13 | class Solution { 14 | private Map indexes = new HashMap<>(); 15 | 16 | public TreeNode buildTree(int[] inorder, int[] postorder) { 17 | for (int i = 0; i < inorder.length; ++i) { 18 | indexes.put(inorder[i], i); 19 | } 20 | return dfs(inorder, postorder, 0, 0, inorder.length); 21 | } 22 | 23 | private TreeNode dfs(int[] inorder, int[] postorder, int i, int j, int n) { 24 | if (n <= 0) { 25 | return null; 26 | } 27 | int v = postorder[j + n - 1]; 28 | int k = indexes.get(v); 29 | TreeNode root = new TreeNode(v); 30 | root.left = dfs(inorder, postorder, i, j, k - i); 31 | root.right = dfs(inorder, postorder, k + 1, j + k - i, n - k + i - 1); 32 | return root; 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter 2/Problem107.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem107 { 4 | public static void main(String[] args) { 5 | TreeNode root = new TreeNode(3, new TreeNode(9), new TreeNode(20, new TreeNode(15), new TreeNode(7))); 6 | Solution solution = new Solution(); 7 | List> result = solution.levelOrderBottom(root); 8 | System.out.println("Level Order Traversal Bottom-Up: " + result); 9 | } 10 | } 11 | 12 | class Solution { 13 | public List> levelOrderBottom(TreeNode root) { 14 | LinkedList> ans = new LinkedList<>(); 15 | if (root == null) { 16 | return ans; 17 | } 18 | Deque q = new LinkedList<>(); 19 | q.offerLast(root); 20 | while (!q.isEmpty()) { 21 | List t = new ArrayList<>(); 22 | for (int i = q.size(); i > 0; --i) { 23 | TreeNode node = q.pollFirst(); 24 | t.add(node.val); 25 | if (node.left != null) { 26 | q.offerLast(node.left); 27 | } 28 | if (node.right != null) { 29 | q.offerLast(node.right); 30 | } 31 | } 32 | ans.addFirst(t); 33 | } 34 | return ans; 35 | } 36 | } -------------------------------------------------------------------------------- /Chapter 2/Problem108.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem108 { 3 | public static void main(String[] args) { 4 | int[] nums = { -10, -3, 0, 5, 9 }; 5 | Solution solution = new Solution(); 6 | TreeNode root = solution.sortedArrayToBST(nums); 7 | System.out.println("Root: " + root.val); 8 | } 9 | } 10 | 11 | class Solution { 12 | private int[] nums; 13 | 14 | public TreeNode sortedArrayToBST(int[] nums) { 15 | this.nums = nums; 16 | return dfs(0, nums.length - 1); 17 | } 18 | 19 | private TreeNode dfs(int l, int r) { 20 | if (l > r) { 21 | return null; 22 | } 23 | int mid = (l + r) >> 1; 24 | TreeNode left = dfs(l, mid - 1); 25 | TreeNode right = dfs(mid + 1, r); 26 | return new TreeNode(nums[mid], left, right); 27 | } 28 | } -------------------------------------------------------------------------------- /Chapter 2/Problem109.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem109 { 4 | public static void main(String[] args) { 5 | ListNode head = new ListNode(-10, new ListNode(-3, new ListNode(0, new ListNode(5, new ListNode(9))))); 6 | Solution solution = new Solution(); 7 | TreeNode root = solution.sortedListToBST(head); 8 | System.out.println("Root: " + root.val); 9 | } 10 | } 11 | 12 | class Solution { 13 | public TreeNode sortedListToBST(ListNode head) { 14 | List nums = new ArrayList<>(); 15 | for (; head != null; head = head.next) { 16 | nums.add(head.val); 17 | } 18 | return buildBST(nums, 0, nums.size() - 1); 19 | } 20 | 21 | private TreeNode buildBST(List nums, int start, int end) { 22 | if (start > end) { 23 | return null; 24 | } 25 | int mid = (start + end) >> 1; 26 | TreeNode root = new TreeNode(nums.get(mid)); 27 | root.left = buildBST(nums, start, mid - 1); 28 | root.right = buildBST(nums, mid + 1, end); 29 | return root; 30 | } 31 | } -------------------------------------------------------------------------------- /Chapter 2/Problem110.java: -------------------------------------------------------------------------------- 1 | public class Problem110 { 2 | public static void main(String[] args) { 3 | TreeNode root = new TreeNode(3, new TreeNode(9), new TreeNode(20, new TreeNode(15), new TreeNode(7))); 4 | Solution solution = new Solution(); 5 | boolean result = solution.isBalanced(root); 6 | System.out.println("Is Balanced: " + result); 7 | } 8 | } 9 | 10 | class Solution { 11 | public boolean isBalanced(TreeNode root) { 12 | return height(root) >= 0; 13 | } 14 | 15 | private int height(TreeNode root) { 16 | if (root == null) { 17 | return 0; 18 | } 19 | int l = height(root.left); 20 | int r = height(root.right); 21 | if (l == -1 || r == -1 || Math.abs(l - r) > 1) { 22 | return -1; 23 | } 24 | return 1 + Math.max(l, r); 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter 2/Problem111.java: -------------------------------------------------------------------------------- 1 | public class Problem111 { 2 | public static void main(String[] args) { 3 | TreeNode root = new TreeNode(3, new TreeNode(9), new TreeNode(20, null, new TreeNode(7))); 4 | Solution solution = new Solution(); 5 | int result = solution.minDepth(root); 6 | System.out.println("Min Depth: " + result); 7 | } 8 | } 9 | 10 | class Solution { 11 | public int minDepth(TreeNode root) { 12 | if (root == null) { 13 | return 0; 14 | } 15 | if (root.left == null) { 16 | return 1 + minDepth(root.right); 17 | } 18 | if (root.right == null) { 19 | return 1 + minDepth(root.left); 20 | } 21 | return 1 + Math.min(minDepth(root.left), minDepth(root.right)); 22 | } 23 | } -------------------------------------------------------------------------------- /Chapter 2/Problem112.java: -------------------------------------------------------------------------------- 1 | public class Problem112 { 2 | public static void main(String[] args) { 3 | TreeNode root = new TreeNode(5, new TreeNode(4), new TreeNode(8, 4 | new TreeNode(11, new TreeNode(7), new TreeNode(2)), new TreeNode(13, null, new TreeNode(4)))); 5 | int targetSum = 22; 6 | Solution solution = new Solution(); 7 | boolean result = solution.hasPathSum(root, targetSum); 8 | System.out.println("Has Path Sum: " + result); 9 | } 10 | } 11 | 12 | class Solution { 13 | public boolean hasPathSum(TreeNode root, int targetSum) { 14 | return dfs(root, targetSum); 15 | } 16 | 17 | private boolean dfs(TreeNode root, int s) { 18 | if (root == null) { 19 | return false; 20 | } 21 | s -= root.val; 22 | if (root.left == null && root.right == null && s == 0) { 23 | return true; 24 | } 25 | return dfs(root.left, s) || dfs(root.right, s); 26 | } 27 | } -------------------------------------------------------------------------------- /Chapter 2/Problem113.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem113 { 4 | public static void main(String[] args) { 5 | TreeNode root = new TreeNode(5, new TreeNode(4, new TreeNode(11, new TreeNode(7), new TreeNode(2)), null), 6 | new TreeNode(8, null, new TreeNode(4, null, new TreeNode(1)))); 7 | int targetSum = 22; 8 | Solution solution = new Solution(); 9 | List> result = solution.pathSum(root, targetSum); 10 | System.out.println("Path Sum: " + result); 11 | } 12 | } 13 | 14 | class Solution { 15 | private List> ans = new ArrayList<>(); 16 | private List t = new ArrayList<>(); 17 | 18 | public List> pathSum(TreeNode root, int targetSum) { 19 | dfs(root, targetSum); 20 | return ans; 21 | } 22 | 23 | private void dfs(TreeNode root, int s) { 24 | if (root == null) { 25 | return; 26 | } 27 | s -= root.val; 28 | t.add(root.val); 29 | if (root.left == null && root.right == null && s == 0) { 30 | ans.add(new ArrayList<>(t)); 31 | } 32 | dfs(root.left, s); 33 | dfs(root.right, s); 34 | t.remove(t.size() - 1); 35 | } 36 | } -------------------------------------------------------------------------------- /Chapter 2/Problem114.java: -------------------------------------------------------------------------------- 1 | public class Problem114 { 2 | public static void main(String[] args) { 3 | TreeNode root = new TreeNode(1, new TreeNode(2, new TreeNode(3), null), new TreeNode(4, null, new TreeNode(5))); 4 | Solution solution = new Solution(); 5 | solution.flatten(root); 6 | // Print the flattened tree 7 | while (root != null) { 8 | System.out.print(root.val + " "); 9 | root = root.right; 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public void flatten(TreeNode root) { 16 | while (root != null) { 17 | if (root.left != null) { 18 | TreeNode pre = root.left; 19 | while (pre.right != null) { 20 | pre = pre.right; 21 | } 22 | pre.right = root.right; 23 | root.right = root.left; 24 | root.left = null; 25 | } 26 | root = root.right; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Chapter 2/Problem115.java: -------------------------------------------------------------------------------- 1 | public class Problem115 { 2 | public static void main(String[] args) { 3 | String s = "rabbbit"; 4 | String t = "rabbit"; 5 | Solution solution = new Solution(); 6 | int result = solution.numDistinct(s, t); 7 | System.out.println("Number of Distinct Subsequences: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | public int numDistinct(String s, String t) { 13 | int n = t.length(); 14 | int[] f = new int[n + 1]; 15 | f[0] = 1; 16 | for (char a : s.toCharArray()) { 17 | for (int j = n; j > 0; --j) { 18 | char b = t.charAt(j - 1); 19 | if (a == b) { 20 | f[j] += f[j - 1]; 21 | } 22 | } 23 | } 24 | return f[n]; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter 2/Problem116.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Node { 4 | public int val; 5 | public Node left; 6 | public Node right; 7 | public Node next; 8 | 9 | public Node(int val) { 10 | this.val = val; 11 | } 12 | 13 | public Node(int val, Node left, Node right) { 14 | this.val = val; 15 | this.left = left; 16 | this.right = right; 17 | this.next = null; 18 | } 19 | } 20 | 21 | public class Problem116 { 22 | public static void main(String[] args) { 23 | Node root = new Node(1, new Node(2), new Node(3)); 24 | Solution solution = new Solution(); 25 | solution.connect(root); 26 | // Print the connected nodes 27 | System.out.println("Connected nodes:"); 28 | System.out.println("Node 1 next: " + (root.next != null ? root.next.val : "null")); 29 | System.out.println("Node 2 next: " + (root.left.next != null ? root.left.next.val : "null")); 30 | System.out.println("Node 3 next: " + (root.right.next != null ? root.right.next.val : "null")); 31 | } 32 | } 33 | 34 | class Solution { 35 | public Node connect(Node root) { 36 | if (root == null) { 37 | return root; 38 | } 39 | Deque q = new ArrayDeque<>(); 40 | q.offer(root); 41 | while (!q.isEmpty()) { 42 | Node p = null; 43 | for (int n = q.size(); n > 0; --n) { 44 | Node node = q.poll(); 45 | if (p != null) { 46 | p.next = node; 47 | } 48 | p = node; 49 | if (node.left != null) { 50 | q.offer(node.left); 51 | } 52 | if (node.right != null) { 53 | q.offer(node.right); 54 | } 55 | } 56 | } 57 | return root; 58 | } 59 | } -------------------------------------------------------------------------------- /Chapter 2/Problem117.java: -------------------------------------------------------------------------------- 1 | public class Problem117 { 2 | public static void main(String[] args) { 3 | Node root = new Node(1, new Node(2, null, new Node(5)), new Node(3, null, new Node(4))); 4 | Solution solution = new Solution(); 5 | solution.connect(root); 6 | // Print the connected tree 7 | Node node = root; 8 | while (node != null) { 9 | System.out.print(node.val + " "); 10 | node = node.next; 11 | } 12 | } 13 | } 14 | 15 | class Solution { 16 | private Node prev, next; 17 | 18 | public Node connect(Node root) { 19 | Node node = root; 20 | while (node != null) { 21 | prev = null; 22 | next = null; 23 | while (node != null) { 24 | modify(node.left); 25 | modify(node.right); 26 | node = node.next; 27 | } 28 | node = next; 29 | } 30 | return root; 31 | } 32 | 33 | private void modify(Node curr) { 34 | if (curr == null) { 35 | return; 36 | } 37 | if (next == null) { 38 | next = curr; 39 | } 40 | if (prev != null) { 41 | prev.next = curr; 42 | } 43 | prev = curr; 44 | } 45 | } -------------------------------------------------------------------------------- /Chapter 2/Problem118.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem118 { 4 | public static void main(String[] args) { 5 | int numRows = 5; 6 | Solution solution = new Solution(); 7 | List> result = solution.generate(numRows); 8 | for (List row : result) { 9 | System.out.println(row); 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public List> generate(int numRows) { 16 | List> f = new ArrayList<>(); 17 | f.add(List.of(1)); 18 | for (int i = 0; i < numRows - 1; ++i) { 19 | List g = new ArrayList<>(); 20 | g.add(1); 21 | for (int j = 0; j < f.get(i).size() - 1; ++j) { 22 | g.add(f.get(i).get(j) + f.get(i).get(j + 1)); 23 | } 24 | g.add(1); 25 | f.add(g); 26 | } 27 | return f; 28 | } 29 | } -------------------------------------------------------------------------------- /Chapter 2/Problem119.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem119 { 4 | public static void main(String[] args) { 5 | int rowIndex = 3; 6 | Solution solution = new Solution(); 7 | List result = solution.getRow(rowIndex); 8 | System.out.println(result); 9 | } 10 | } 11 | 12 | class Solution { 13 | public List getRow(int rowIndex) { 14 | List f = new ArrayList<>(); 15 | for (int i = 0; i < rowIndex + 1; ++i) { 16 | f.add(1); 17 | } 18 | for (int i = 2; i < rowIndex + 1; ++i) { 19 | for (int j = i - 1; j > 0; --j) { 20 | f.set(j, f.get(j) + f.get(j - 1)); 21 | } 22 | } 23 | return f; 24 | } 25 | } -------------------------------------------------------------------------------- /Chapter 2/Problem120.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem120 { 4 | public static void main(String[] args) { 5 | List> triangle = new ArrayList<>(); 6 | triangle.add(List.of(2)); 7 | triangle.add(List.of(3, 4)); 8 | triangle.add(List.of(6, 5, 7)); 9 | triangle.add(List.of(4, 1, 8, 3)); 10 | 11 | Solution solution = new Solution(); 12 | int result = solution.minimumTotal(triangle); 13 | System.out.println("Minimum path sum: " + result); 14 | } 15 | } 16 | 17 | class Solution { 18 | public int minimumTotal(List> triangle) { 19 | for (int i = triangle.size() - 2; i >= 0; --i) { 20 | for (int j = 0; j <= i; ++j) { 21 | int x = triangle.get(i).get(j); 22 | int y = Math.min(triangle.get(i + 1).get(j), triangle.get(i + 1).get(j + 1)); 23 | triangle.get(i).set(j, x + y); 24 | } 25 | } 26 | return triangle.get(0).get(0); 27 | } 28 | } -------------------------------------------------------------------------------- /Chapter 2/Problem121.java: -------------------------------------------------------------------------------- 1 | public class Problem121 { 2 | public static void main(String[] args) { 3 | int[] prices = { 7, 1, 5, 3, 6, 4 }; 4 | Solution solution = new Solution(); 5 | int result = solution.maxProfit(prices); 6 | System.out.println("Maximum profit: " + result); 7 | } 8 | } 9 | 10 | class Solution { 11 | public int maxProfit(int[] prices) { 12 | int ans = 0, mi = prices[0]; 13 | for (int v : prices) { 14 | ans = Math.max(ans, v - mi); 15 | mi = Math.min(mi, v); 16 | } 17 | return ans; 18 | } 19 | } -------------------------------------------------------------------------------- /Chapter 2/Problem122.java: -------------------------------------------------------------------------------- 1 | public class Problem122 { 2 | public static void main(String[] args) { 3 | int[] prices = { 7, 1, 5, 3, 6, 4 }; 4 | Solution solution = new Solution(); 5 | int result = solution.maxProfit(prices); 6 | System.out.println("Maximum profit: " + result); 7 | } 8 | } 9 | 10 | class Solution { 11 | public int maxProfit(int[] prices) { 12 | int ans = 0; 13 | for (int i = 1; i < prices.length; ++i) { 14 | ans += Math.max(0, prices[i] - prices[i - 1]); 15 | } 16 | return ans; 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter 2/Problem123.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem123 { 3 | public static void main(String[] args) { 4 | int[] prices = { 3, 2, 6, 5, 0, 3 }; 5 | Solution solution = new Solution(); 6 | int result = solution.MaxProfit(prices); 7 | System.out.println("Maximum profit: " + result); 8 | } 9 | } 10 | 11 | class Solution { 12 | public int MaxProfit(int[] prices) { 13 | int f1 = -prices[0], f2 = 0, f3 = -prices[0], f4 = 0; 14 | for (int i = 1; i < prices.length; ++i) { 15 | f1 = Math.max(f1, -prices[i]); 16 | f2 = Math.max(f2, f1 + prices[i]); 17 | f3 = Math.max(f3, f2 - prices[i]); 18 | f4 = Math.max(f4, f3 + prices[i]); 19 | } 20 | return f4; 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter 2/Problem124.java: -------------------------------------------------------------------------------- 1 | public class Problem124 { 2 | public static void main(String[] args) { 3 | TreeNode root = new TreeNode(1); 4 | root.left = new TreeNode(2); 5 | root.right = new TreeNode(3); 6 | Solution solution = new Solution(); 7 | int result = solution.maxPathSum(root); 8 | System.out.println("Maximum path sum: " + result); 9 | } 10 | } 11 | 12 | class Solution { 13 | private int ans = -1001; 14 | 15 | public int maxPathSum(TreeNode root) { 16 | dfs(root); 17 | return ans; 18 | } 19 | 20 | private int dfs(TreeNode root) { 21 | if (root == null) { 22 | return 0; 23 | } 24 | int left = Math.max(0, dfs(root.left)); 25 | int right = Math.max(0, dfs(root.right)); 26 | ans = Math.max(ans, root.val + left + right); 27 | return root.val + Math.max(left, right); 28 | } 29 | } -------------------------------------------------------------------------------- /Chapter 2/Problem125.java: -------------------------------------------------------------------------------- 1 | public class Problem125 { 2 | public static void main(String[] args) { 3 | Solution solution = new Solution(); 4 | String testString = "A man, a plan, a canal: Panama"; 5 | System.out.println("Is Palindrome: " + solution.isPalindrome(testString)); 6 | } 7 | } 8 | 9 | class Solution { 10 | public boolean isPalindrome(String s) { 11 | int i = 0, j = s.length() - 1; 12 | while (i < j) { 13 | if (!Character.isLetterOrDigit(s.charAt(i))) { 14 | ++i; 15 | } else if (!Character.isLetterOrDigit(s.charAt(j))) { 16 | --j; 17 | } else if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) { 18 | return false; 19 | } else { 20 | ++i; 21 | --j; 22 | } 23 | } 24 | return true; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter 2/Problem126.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Arrays; 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | import java.util.Queue; 8 | import java.util.Set; 9 | 10 | public class Problem126 { 11 | 12 | // iteration bfs 13 | // https://leetcode.com/problems/word-ladder-ii/solution/ 14 | public class Solution { 15 | 16 | List> list = new ArrayList>(); 17 | 18 | public List> findLadders(String start, String end, Set dict) { 19 | 20 | if (start == null || end == null || dict == null) 21 | return list; 22 | 23 | dict.add(end); // !!! 24 | 25 | Queue q = new LinkedList(); 26 | int level = 1; 27 | int currentLevelCount = 1; 28 | int newLevelCount = 0; 29 | boolean found = false; 30 | int foundLevel = -1; 31 | 32 | // from end word, to all paths 33 | HashMap>> hm = new HashMap>>(); 34 | 35 | q.offer(start); 36 | ArrayList singlePath = new ArrayList(); 37 | ArrayList> allPaths = new ArrayList>(); 38 | 39 | singlePath.add(start); 40 | allPaths.add(singlePath); 41 | hm.put(start, allPaths); 42 | 43 | while (!q.isEmpty()) { 44 | 45 | String current = q.poll(); 46 | currentLevelCount--; // 这里用了新旧count来标记每个level,没有用null 47 | 48 | for (int i = 0; i < current.length(); i++) { 49 | char[] array = current.toCharArray(); 50 | 51 | for (char c = 'a'; c <= 'z'; c++) { 52 | array[i] = c; 53 | String each = new String(array); 54 | if (each.equals(end)) { 55 | found = true; 56 | foundLevel = level; 57 | } 58 | 59 | if (dict.contains(each)) { 60 | // q.offer(each); 61 | newLevelCount++; 62 | 63 | ArrayList> prevAllPaths = hm.get(current); 64 | 65 | if (hm.containsKey(each)) 66 | allPaths = hm.get(each); 67 | else { 68 | /* 69 | * @note@note: 70 | * enqueue is here. if no path ending at this one, then has to explore in future 71 | * if there is path ending at this one, meaning it's been explored already. no 72 | * need to enqueue 73 | */ 74 | q.offer(each); 75 | allPaths = new ArrayList>(); 76 | hm.put(each, allPaths); 77 | } 78 | 79 | // @note@note: this if is the key !!! no path for new word, or new word path is 80 | // one more than previous path 81 | // using this if, the"if visited" check can be removed 82 | // if (allPaths.size() == 0 || prevAllPaths.size() + 1 == allPaths.size()) { 83 | if (allPaths.size() == 0 || prevAllPaths.get(0).size() + 1 == allPaths.get(0).size()) { 84 | for (ArrayList eachPath : prevAllPaths) { 85 | ArrayList newone = new ArrayList(eachPath); 86 | newone.add(each); 87 | allPaths.add(newone); 88 | } 89 | } 90 | } 91 | } 92 | } 93 | 94 | // @note@note: also the key, to make sure only find shortest 95 | if (found && foundLevel != level) { 96 | break; 97 | } 98 | 99 | // @note: must be after trying the last word of currentLevel, then update 100 | if (currentLevelCount == 0) { 101 | currentLevelCount = newLevelCount; 102 | newLevelCount = 0; 103 | level++; 104 | 105 | } 106 | 107 | } 108 | 109 | if (!found) { 110 | return list; 111 | } 112 | 113 | for (ArrayList each : hm.get(end)) { 114 | list.add(each); 115 | } 116 | 117 | return list; 118 | 119 | } 120 | } 121 | 122 | public class Solution_recursion { 123 | 124 | @SuppressWarnings("unused") 125 | private List findPath(String fromWord, String toWord, 126 | Set seenWords) { 127 | 128 | if (fromWord.equals(toWord)) { 129 | ArrayList result = new ArrayList<>(); 130 | result.add(toWord); 131 | return result; 132 | } 133 | 134 | // Find all words that you can go to from fromWord 135 | List nextWords = getNextWords(fromWord, seenWords); 136 | for (String word : nextWords) { 137 | Set newSeenWords = new HashSet(seenWords); 138 | newSeenWords.add(word); 139 | List subPath = findPath(word, toWord, newSeenWords); 140 | if (subPath != null) { 141 | subPath.add(fromWord); 142 | return subPath; 143 | } 144 | } 145 | 146 | // There wasn't a path 147 | return null; 148 | 149 | } 150 | 151 | private final List WORDS = Arrays.asList("head", "heal", 152 | "teal", "tell", "tall", "tail"); 153 | 154 | private final List ALPHA = Arrays.asList('a', 'b', 155 | 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 156 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'); 157 | 158 | private final HashSet DICTIONARY = new HashSet( 159 | WORDS); 160 | 161 | private List getNextWords(String fromWord, 162 | Set seenWords) { 163 | List outList = new ArrayList(); 164 | StringBuilder builder; 165 | for (int i = 0; i < fromWord.length(); i++) { 166 | builder = new StringBuilder(fromWord); 167 | for (Character j : ALPHA) { 168 | if (j == fromWord.charAt(i)) { 169 | continue; 170 | } 171 | builder.setCharAt(i, j); 172 | String potentialWord = builder.toString(); 173 | if (DICTIONARY.contains(potentialWord) 174 | && !seenWords.contains(potentialWord)) { 175 | outList.add(potentialWord); 176 | } 177 | } 178 | } 179 | return outList; 180 | } 181 | } 182 | } -------------------------------------------------------------------------------- /Chapter 2/Problem127.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem127 { 4 | public static void main(String[] args) { 5 | String beginWord = "hit"; 6 | String endWord = "cog"; 7 | List wordList = List.of("hot", "dot", "dog", "lot", "log", "cog"); 8 | Solution solution = new Solution(); 9 | int result = solution.ladderLength(beginWord, endWord, wordList); 10 | System.out.println("Length of the shortest transformation sequence: " + result); 11 | } 12 | } 13 | 14 | class Solution { 15 | private Set words; 16 | 17 | public int ladderLength(String beginWord, String endWord, List wordList) { 18 | words = new HashSet<>(wordList); 19 | if (!words.contains(endWord)) { 20 | return 0; 21 | } 22 | Queue q1 = new ArrayDeque<>(); 23 | Queue q2 = new ArrayDeque<>(); 24 | Map m1 = new HashMap<>(); 25 | Map m2 = new HashMap<>(); 26 | q1.offer(beginWord); 27 | q2.offer(endWord); 28 | m1.put(beginWord, 0); 29 | m2.put(endWord, 0); 30 | while (!q1.isEmpty() && !q2.isEmpty()) { 31 | int t = q1.size() <= q2.size() ? extend(m1, m2, q1) : extend(m2, m1, q2); 32 | if (t != -1) { 33 | return t + 1; 34 | } 35 | } 36 | return 0; 37 | } 38 | 39 | private int extend(Map m1, Map m2, Queue q) { 40 | for (int i = q.size(); i > 0; --i) { 41 | String s = q.poll(); 42 | int step = m1.get(s); 43 | char[] chars = s.toCharArray(); 44 | for (int j = 0; j < chars.length; ++j) { 45 | char ch = chars[j]; 46 | for (char k = 'a'; k <= 'z'; ++k) { 47 | chars[j] = k; 48 | String t = new String(chars); 49 | if (!words.contains(t) || m1.containsKey(t)) { 50 | continue; 51 | } 52 | if (m2.containsKey(t)) { 53 | return step + 1 + m2.get(t); 54 | } 55 | q.offer(t); 56 | m1.put(t, step + 1); 57 | } 58 | chars[j] = ch; 59 | } 60 | } 61 | return -1; 62 | } 63 | } -------------------------------------------------------------------------------- /Chapter 2/Problem128.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem128 { 4 | public static void main(String[] args) { 5 | int[] nums = { 100, 4, 200, 1, 3, 2 }; 6 | Solution solution = new Solution(); 7 | int result = solution.longestConsecutive(nums); 8 | System.out.println("Longest Consecutive Sequence Length: " + result); 9 | } 10 | } 11 | 12 | class Solution { 13 | public int longestConsecutive(int[] nums) { 14 | Set s = new HashSet<>(); 15 | for (int x : nums) { 16 | s.add(x); 17 | } 18 | int ans = 0; 19 | for (int x : nums) { 20 | if (!s.contains(x - 1)) { 21 | int y = x + 1; 22 | while (s.contains(y)) { 23 | ++y; 24 | } 25 | ans = Math.max(ans, y - x); 26 | } 27 | } 28 | return ans; 29 | } 30 | } -------------------------------------------------------------------------------- /Chapter 2/Problem129.java: -------------------------------------------------------------------------------- 1 | public class Problem129 { 2 | public static void main(String[] args) { 3 | TreeNode root = new TreeNode(1); 4 | root.left = new TreeNode(2); 5 | root.right = new TreeNode(3); 6 | Solution solution = new Solution(); 7 | int result = solution.sumNumbers(root); 8 | System.out.println("Sum of all numbers formed by root-to-leaf paths: " + result); 9 | } 10 | } 11 | 12 | class Solution { 13 | public int sumNumbers(TreeNode root) { 14 | return dfs(root, 0); 15 | } 16 | 17 | private int dfs(TreeNode root, int s) { 18 | if (root == null) { 19 | return 0; 20 | } 21 | s = s * 10 + root.val; 22 | if (root.left == null && root.right == null) { 23 | return s; 24 | } 25 | return dfs(root.left, s) + dfs(root.right, s); 26 | } 27 | } -------------------------------------------------------------------------------- /Chapter 2/Problem130.java: -------------------------------------------------------------------------------- 1 | public class Problem130 { 2 | public static void main(String[] args) { 3 | char[][] board = { 4 | { 'X', 'X', 'X', 'X' }, 5 | { 'X', 'O', 'O', 'X' }, 6 | { 'X', 'X', 'O', 'X' }, 7 | { 'X', 'O', 'X', 'X' } 8 | }; 9 | Solution solution = new Solution(); 10 | solution.solve(board); 11 | for (char[] row : board) { 12 | System.out.println(row); 13 | } 14 | } 15 | } 16 | 17 | class Solution { 18 | private char[][] board; 19 | private int m; 20 | private int n; 21 | 22 | public void solve(char[][] board) { 23 | m = board.length; 24 | n = board[0].length; 25 | this.board = board; 26 | for (int i = 0; i < m; ++i) { 27 | for (int j = 0; j < n; ++j) { 28 | if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') { 29 | dfs(i, j); 30 | } 31 | } 32 | } 33 | for (int i = 0; i < m; ++i) { 34 | for (int j = 0; j < n; ++j) { 35 | if (board[i][j] == '.') { 36 | board[i][j] = 'O'; 37 | } else if (board[i][j] == 'O') { 38 | board[i][j] = 'X'; 39 | } 40 | } 41 | } 42 | } 43 | 44 | private void dfs(int i, int j) { 45 | board[i][j] = '.'; 46 | int[] dirs = { -1, 0, 1, 0, -1 }; 47 | for (int k = 0; k < 4; ++k) { 48 | int x = i + dirs[k]; 49 | int y = j + dirs[k + 1]; 50 | if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') { 51 | dfs(x, y); 52 | } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Chapter 2/Problem131.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem131 { 4 | public static void main(String[] args) { 5 | String s = "aab"; 6 | Solution solution = new Solution(); 7 | List> result = solution.partition(s); 8 | for (List partition : result) { 9 | System.out.println(partition); 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | private boolean[][] dp; 16 | private List> ans; 17 | private int n; 18 | 19 | public List> partition(String s) { 20 | ans = new ArrayList<>(); 21 | n = s.length(); 22 | dp = new boolean[n][n]; 23 | for (int i = 0; i < n; ++i) { 24 | Arrays.fill(dp[i], true); 25 | } 26 | for (int i = n - 1; i >= 0; --i) { 27 | for (int j = i + 1; j < n; ++j) { 28 | dp[i][j] = s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]; 29 | } 30 | } 31 | dfs(s, 0, new ArrayList<>()); 32 | return ans; 33 | } 34 | 35 | private void dfs(String s, int i, List t) { 36 | if (i == n) { 37 | ans.add(new ArrayList<>(t)); 38 | return; 39 | } 40 | for (int j = i; j < n; ++j) { 41 | if (dp[i][j]) { 42 | t.add(s.substring(i, j + 1)); 43 | dfs(s, j + 1, t); 44 | t.remove(t.size() - 1); 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Chapter 2/Problem132.java: -------------------------------------------------------------------------------- 1 | public class Problem132 { 2 | public static void main(String[] args) { 3 | String s = "aab"; 4 | Solution solution = new Solution(); 5 | int result = solution.minCut(s); 6 | System.out.println("Minimum cuts needed for palindrome partitioning: " + result); 7 | } 8 | } 9 | 10 | class Solution { 11 | public int minCut(String s) { 12 | int n = s.length(); 13 | boolean[][] dp1 = new boolean[n][n]; 14 | for (int i = n - 1; i >= 0; i--) { 15 | for (int j = i; j < n; j++) { 16 | dp1[i][j] = s.charAt(i) == s.charAt(j) && (j - i < 3 || dp1[i + 1][j - 1]); 17 | } 18 | } 19 | int[] dp2 = new int[n]; 20 | for (int i = 0; i < n; i++) { 21 | if (!dp1[0][i]) { 22 | dp2[i] = i; 23 | for (int j = 1; j <= i; j++) { 24 | if (dp1[j][i]) { 25 | dp2[i] = Math.min(dp2[i], dp2[j - 1] + 1); 26 | } 27 | } 28 | } 29 | } 30 | return dp2[n - 1]; 31 | } 32 | } -------------------------------------------------------------------------------- /Chapter 2/Problem133.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem133 { 4 | public static void main(String[] args) { 5 | // Example usage 6 | Node node1 = new Node(1); 7 | Node node2 = new Node(2); 8 | Node node3 = new Node(3); 9 | Node node4 = new Node(4); 10 | 11 | node1.neighbors.add(node2); 12 | node1.neighbors.add(node4); 13 | node2.neighbors.add(node1); 14 | node2.neighbors.add(node3); 15 | node3.neighbors.add(node2); 16 | node3.neighbors.add(node4); 17 | node4.neighbors.add(node1); 18 | node4.neighbors.add(node3); 19 | 20 | Solution solution = new Solution(); 21 | Node clonedGraph = solution.cloneGraph(node1); 22 | 23 | // Print the cloned graph (for testing purposes) 24 | System.out.println(clonedGraph.val); // Should print 1 25 | } 26 | } 27 | 28 | class Node { 29 | public int val; 30 | public List neighbors; 31 | 32 | public Node(int val) { 33 | this.val = val; 34 | this.neighbors = new ArrayList<>(); 35 | } 36 | } 37 | 38 | class Solution { 39 | private Map visited = new HashMap<>(); 40 | 41 | public Node cloneGraph(Node node) { 42 | if (node == null) { 43 | return null; 44 | } 45 | if (visited.containsKey(node)) { 46 | return visited.get(node); 47 | } 48 | Node clone = new Node(node.val); 49 | visited.put(node, clone); 50 | for (Node e : node.neighbors) { 51 | clone.neighbors.add(cloneGraph(e)); 52 | } 53 | return clone; 54 | } 55 | } -------------------------------------------------------------------------------- /Chapter 2/Problem134.java: -------------------------------------------------------------------------------- 1 | public class Problem134 { 2 | public static void main(String[] args) { 3 | int[] gas = { 1, 2, 3, 4, 5 }; 4 | int[] cost = { 3, 4, 5, 1, 2 }; 5 | Solution solution = new Solution(); 6 | System.out.println(solution.canCompleteCircuit(gas, cost)); // Output: 3 7 | } 8 | } 9 | 10 | class Solution { 11 | public int canCompleteCircuit(int[] gas, int[] cost) { 12 | int n = gas.length; 13 | int i = n - 1, j = n - 1; 14 | int cnt = 0, s = 0; 15 | while (cnt < n) { 16 | s += gas[j] - cost[j]; 17 | ++cnt; 18 | j = (j + 1) % n; 19 | while (s < 0 && cnt < n) { 20 | --i; 21 | s += gas[i] - cost[i]; 22 | ++cnt; 23 | } 24 | } 25 | return s < 0 ? -1 : i; 26 | } 27 | } -------------------------------------------------------------------------------- /Chapter 2/Problem135.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem135 { 3 | public static void main(String[] args) { 4 | int[] ratings = { 1, 0, 2 }; 5 | Solution solution = new Solution(); 6 | System.out.println(solution.candy(ratings)); // Output: 5 7 | } 8 | } 9 | 10 | class Solution { 11 | public int candy(int[] ratings) { 12 | int n = ratings.length; 13 | int up = 0; 14 | int down = 0; 15 | int peak = 0; 16 | int candies = 1; 17 | for (int i = 1; i < n; i++) { 18 | if (ratings[i - 1] < ratings[i]) { 19 | up++; 20 | peak = up + 1; 21 | down = 0; 22 | candies += peak; 23 | } else if (ratings[i] == ratings[i - 1]) { 24 | peak = 0; 25 | up = 0; 26 | down = 0; 27 | candies++; 28 | } else { 29 | down++; 30 | up = 0; 31 | candies += down + (peak > down ? 0 : 1); 32 | } 33 | } 34 | return candies; 35 | } 36 | } -------------------------------------------------------------------------------- /Chapter 2/Problem136.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem136 { 3 | public static void main(String[] args) { 4 | int[] nums = { 4, 1, 2, 1, 2 }; 5 | Solution solution = new Solution(); 6 | System.out.println(solution.singleNumber(nums)); // Output: 4 7 | } 8 | } 9 | 10 | class Solution { 11 | public int singleNumber(int[] nums) { 12 | int ans = 0; 13 | for (int v : nums) { 14 | ans ^= v; 15 | } 16 | return ans; 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter 2/Problem137.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem137 { 3 | public static void main(String[] args) { 4 | int[] nums = { 2, 2, 3, 2 }; 5 | Solution solution = new Solution(); 6 | System.out.println(solution.singleNumber(nums)); // Output: 3 7 | } 8 | } 9 | 10 | class Solution { 11 | public int singleNumber(int[] nums) { 12 | int a = 0, b = 0; 13 | for (int c : nums) { 14 | int aa = (~a & b & c) | (a & ~b & ~c); 15 | int bb = ~a & (b ^ c); 16 | a = aa; 17 | b = bb; 18 | } 19 | return b; 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter 2/Problem138.java: -------------------------------------------------------------------------------- 1 | public class Problem138 { 2 | public static void main(String[] args) { 3 | int[] nums = { 2, 2, 3, 2 }; 4 | Solution solution = new Solution(); 5 | System.out.println(solution.singleNumber(nums)); // Output: 3 6 | } 7 | } 8 | 9 | class Solution { 10 | public int singleNumber(int[] nums) { 11 | int result = 0; 12 | for (int num : nums) { 13 | result ^= num; // XOR operation to find the single number 14 | } 15 | return result; 16 | } 17 | 18 | public Node copyRandomList(Node head) { 19 | if (head == null) { 20 | return null; 21 | } 22 | for (Node cur = head; cur != null;) { 23 | Node node = new Node(cur.val, cur.next); 24 | cur.next = node; 25 | cur = node.next; 26 | } 27 | for (Node cur = head; cur != null; cur = cur.next.next) { 28 | if (cur.random != null) { 29 | cur.next.random = cur.random.next; 30 | } 31 | } 32 | Node ans = head.next; 33 | for (Node cur = head; cur != null;) { 34 | Node nxt = cur.next; 35 | if (nxt != null) { 36 | cur.next = nxt.next; 37 | } 38 | cur = nxt; 39 | } 40 | return ans; 41 | } 42 | } 43 | 44 | class Node { 45 | int val; 46 | Node next; 47 | Node random; 48 | 49 | Node(int val) { 50 | this.val = val; 51 | this.next = null; 52 | this.random = null; 53 | } 54 | 55 | Node(int val, Node next) { 56 | this.val = val; 57 | this.next = next; 58 | this.random = null; 59 | } 60 | } -------------------------------------------------------------------------------- /Chapter 2/Problem139.java: -------------------------------------------------------------------------------- 1 | import java.util.HashSet; 2 | import java.util.List; 3 | import java.util.Set; 4 | 5 | class Solution { 6 | public boolean wordBreak(String s, List wordDict) { 7 | Set words = new HashSet<>(wordDict); 8 | int n = s.length(); 9 | boolean[] dp = new boolean[n + 1]; 10 | dp[0] = true; 11 | for (int i = 1; i <= n; ++i) { 12 | for (int j = 0; j < i; ++j) { 13 | if (dp[j] && words.contains(s.substring(j, i))) { 14 | dp[i] = true; 15 | break; 16 | } 17 | } 18 | } 19 | return dp[n]; 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter 2/Problem140.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.util.stream.Collectors; 3 | 4 | public class Problem140 { 5 | public static void main(String[] args) { 6 | Solution solution = new Solution(); 7 | System.out.println(solution.wordBreak("catsanddog", List.of("cat", "cats", "and", "sand", "dog"))); 8 | // Output: ["cats and dog", "cat sand dog"] 9 | } 10 | } 11 | 12 | class Trie { 13 | Trie[] children = new Trie[26]; 14 | boolean isEnd; 15 | 16 | void insert(String word) { 17 | Trie node = this; 18 | for (char c : word.toCharArray()) { 19 | c -= 'a'; 20 | if (node.children[c] == null) { 21 | node.children[c] = new Trie(); 22 | } 23 | node = node.children[c]; 24 | } 25 | node.isEnd = true; 26 | } 27 | 28 | boolean search(String word) { 29 | Trie node = this; 30 | for (char c : word.toCharArray()) { 31 | c -= 'a'; 32 | if (node.children[c] == null) { 33 | return false; 34 | } 35 | node = node.children[c]; 36 | } 37 | return node.isEnd; 38 | } 39 | } 40 | 41 | class Solution { 42 | private Trie trie = new Trie(); 43 | 44 | public List wordBreak(String s, List wordDict) { 45 | for (String w : wordDict) { 46 | trie.insert(w); 47 | } 48 | List> res = dfs(s); 49 | return res.stream().map(e -> String.join(" ", e)).collect(Collectors.toList()); 50 | } 51 | 52 | private List> dfs(String s) { 53 | List> res = new ArrayList<>(); 54 | if ("".equals(s)) { 55 | res.add(new ArrayList<>()); 56 | return res; 57 | } 58 | for (int i = 1; i <= s.length(); ++i) { 59 | if (trie.search(s.substring(0, i))) { 60 | for (List v : dfs(s.substring(i))) { 61 | v.add(0, s.substring(0, i)); 62 | res.add(v); 63 | } 64 | } 65 | } 66 | return res; 67 | } 68 | } -------------------------------------------------------------------------------- /Chapter 2/Problem141.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem141 { 3 | public boolean hasCycle(ListNode head) { 4 | ListNode slow = head; 5 | ListNode fast = head; 6 | while (fast != null && fast.next != null) { 7 | slow = slow.next; 8 | fast = fast.next.next; 9 | if (slow == fast) { 10 | return true; 11 | } 12 | } 13 | return false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chapter 2/Problem142.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem142 { 3 | public ListNode detectCycle(ListNode head) { 4 | ListNode fast = head, slow = head; 5 | while (fast != null && fast.next != null) { 6 | slow = slow.next; 7 | fast = fast.next.next; 8 | if (slow == fast) { 9 | ListNode ans = head; 10 | while (ans != slow) { 11 | ans = ans.next; 12 | slow = slow.next; 13 | } 14 | return ans; 15 | } 16 | } 17 | return null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter 2/Problem143.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem143 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | ListNode head = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4)))); 6 | solution.reorderList(head); 7 | while (head != null) { 8 | System.out.print(head.val + " "); 9 | head = head.next; 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public void reorderList(ListNode head) { 16 | ListNode fast = head, slow = head; 17 | while (fast.next != null && fast.next.next != null) { 18 | slow = slow.next; 19 | fast = fast.next.next; 20 | } 21 | 22 | ListNode cur = slow.next; 23 | slow.next = null; 24 | 25 | ListNode pre = null; 26 | while (cur != null) { 27 | ListNode t = cur.next; 28 | cur.next = pre; 29 | pre = cur; 30 | cur = t; 31 | } 32 | cur = head; 33 | 34 | while (pre != null) { 35 | ListNode t = pre.next; 36 | pre.next = cur.next; 37 | cur.next = pre; 38 | cur = pre.next; 39 | pre = t; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Chapter 2/Problem144.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem144 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | TreeNode root = new TreeNode(1, null, new TreeNode(2, new TreeNode(3), null)); 7 | List result = solution.preorderTraversal(root); 8 | for (int val : result) { 9 | System.out.print(val + " "); 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public List preorderTraversal(TreeNode root) { 16 | List ans = new ArrayList<>(); 17 | while (root != null) { 18 | if (root.left == null) { 19 | ans.add(root.val); 20 | root = root.right; 21 | } else { 22 | TreeNode prev = root.left; 23 | while (prev.right != null && prev.right != root) { 24 | prev = prev.right; 25 | } 26 | if (prev.right == null) { 27 | ans.add(root.val); 28 | prev.right = root; 29 | root = root.left; 30 | } else { 31 | prev.right = null; 32 | root = root.right; 33 | } 34 | } 35 | } 36 | return ans; 37 | } 38 | } -------------------------------------------------------------------------------- /Chapter 2/Problem145.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem145 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | TreeNode root = new TreeNode(1, null, new TreeNode(2, new TreeNode(3), null)); 7 | List result = solution.postorderTraversal(root); 8 | for (int val : result) { 9 | System.out.print(val + " "); 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public List postorderTraversal(TreeNode root) { 16 | LinkedList ans = new LinkedList<>(); 17 | while (root != null) { 18 | if (root.right == null) { 19 | ans.addFirst(root.val); 20 | root = root.left; 21 | } else { 22 | TreeNode next = root.right; 23 | while (next.left != null && next.left != root) { 24 | next = next.left; 25 | } 26 | if (next.left == null) { 27 | ans.addFirst(root.val); 28 | next.left = root; 29 | root = root.right; 30 | } else { 31 | next.left = null; 32 | root = root.left; 33 | } 34 | } 35 | } 36 | return ans; 37 | } 38 | } -------------------------------------------------------------------------------- /Chapter 2/Problem146.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem146 { 4 | public static void main(String[] args) { 5 | LRUCache cache = new LRUCache(2); 6 | cache.put(1, 1); 7 | cache.put(2, 2); 8 | System.out.println(cache.get(1)); // returns 1 9 | cache.put(3, 3); // evicts key 2 10 | System.out.println(cache.get(2)); // returns -1 (not found) 11 | cache.put(4, 4); // evicts key 1 12 | System.out.println(cache.get(1)); // returns -1 (not found) 13 | System.out.println(cache.get(3)); // returns 3 14 | System.out.println(cache.get(4)); // returns 4 15 | } 16 | } 17 | 18 | class Node { 19 | int key; 20 | int val; 21 | Node prev; 22 | Node next; 23 | 24 | Node() { 25 | } 26 | 27 | Node(int key, int val) { 28 | this.key = key; 29 | this.val = val; 30 | } 31 | } 32 | 33 | class LRUCache { 34 | private Map cache = new HashMap<>(); 35 | private Node head = new Node(); 36 | private Node tail = new Node(); 37 | private int capacity; 38 | private int size; 39 | 40 | public LRUCache(int capacity) { 41 | this.capacity = capacity; 42 | head.next = tail; 43 | tail.prev = head; 44 | } 45 | 46 | public int get(int key) { 47 | if (!cache.containsKey(key)) { 48 | return -1; 49 | } 50 | Node node = cache.get(key); 51 | moveToHead(node); 52 | return node.val; 53 | } 54 | 55 | public void put(int key, int value) { 56 | if (cache.containsKey(key)) { 57 | Node node = cache.get(key); 58 | node.val = value; 59 | moveToHead(node); 60 | } else { 61 | Node node = new Node(key, value); 62 | cache.put(key, node); 63 | addToHead(node); 64 | ++size; 65 | if (size > capacity) { 66 | node = removeTail(); 67 | cache.remove(node.key); 68 | --size; 69 | } 70 | } 71 | } 72 | 73 | private void moveToHead(Node node) { 74 | removeNode(node); 75 | addToHead(node); 76 | } 77 | 78 | private void removeNode(Node node) { 79 | node.prev.next = node.next; 80 | node.next.prev = node.prev; 81 | } 82 | 83 | private void addToHead(Node node) { 84 | node.next = head.next; 85 | node.prev = head; 86 | head.next = node; 87 | node.next.prev = node; 88 | } 89 | 90 | private Node removeTail() { 91 | Node node = tail.prev; 92 | removeNode(node); 93 | return node; 94 | } 95 | } -------------------------------------------------------------------------------- /Chapter 2/Problem147.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem147 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | ListNode head = new ListNode(4, new ListNode(2, new ListNode(1, new ListNode(3)))); 6 | ListNode sortedList = solution.insertionSortList(head); 7 | while (sortedList != null) { 8 | System.out.print(sortedList.val + " "); 9 | sortedList = sortedList.next; 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public ListNode insertionSortList(ListNode head) { 16 | if (head == null || head.next == null) { 17 | return head; 18 | } 19 | ListNode dummy = new ListNode(head.val, head); 20 | ListNode pre = dummy, cur = head; 21 | while (cur != null) { 22 | if (pre.val <= cur.val) { 23 | pre = cur; 24 | cur = cur.next; 25 | continue; 26 | } 27 | ListNode p = dummy; 28 | while (p.next.val <= cur.val) { 29 | p = p.next; 30 | } 31 | ListNode t = cur.next; 32 | cur.next = p.next; 33 | p.next = cur; 34 | pre.next = t; 35 | cur = t; 36 | } 37 | return dummy.next; 38 | } 39 | } -------------------------------------------------------------------------------- /Chapter 2/Problem148.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem148 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | ListNode head = new ListNode(4, new ListNode(2, new ListNode(1, new ListNode(3)))); 6 | ListNode sortedList = solution.sortList(head); 7 | while (sortedList != null) { 8 | System.out.print(sortedList.val + " "); 9 | sortedList = sortedList.next; 10 | } 11 | } 12 | } 13 | 14 | class Solution { 15 | public ListNode sortList(ListNode head) { 16 | if (head == null || head.next == null) { 17 | return head; 18 | } 19 | ListNode slow = head, fast = head.next; 20 | while (fast != null && fast.next != null) { 21 | slow = slow.next; 22 | fast = fast.next.next; 23 | } 24 | ListNode t = slow.next; 25 | slow.next = null; 26 | ListNode l1 = sortList(head); 27 | ListNode l2 = sortList(t); 28 | ListNode dummy = new ListNode(); 29 | ListNode cur = dummy; 30 | while (l1 != null && l2 != null) { 31 | if (l1.val <= l2.val) { 32 | cur.next = l1; 33 | l1 = l1.next; 34 | } else { 35 | cur.next = l2; 36 | l2 = l2.next; 37 | } 38 | cur = cur.next; 39 | } 40 | cur.next = l1 == null ? l2 : l1; 41 | return dummy.next; 42 | } 43 | } -------------------------------------------------------------------------------- /Chapter 2/Problem149.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem149 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | int[][] points = { { 1, 1 }, { 2, 2 }, { 3, 3 } }; 7 | System.out.println(solution.maxPoints(points)); // Output: 3 8 | } 9 | } 10 | 11 | class Solution { 12 | public int maxPoints(int[][] points) { 13 | int n = points.length; 14 | int ans = 1; 15 | for (int i = 0; i < n; ++i) { 16 | int x1 = points[i][0], y1 = points[i][1]; 17 | Map cnt = new HashMap<>(); 18 | for (int j = i + 1; j < n; ++j) { 19 | int x2 = points[j][0], y2 = points[j][1]; 20 | int dx = x2 - x1, dy = y2 - y1; 21 | int g = gcd(dx, dy); 22 | String k = (dx / g) + "." + (dy / g); 23 | cnt.put(k, cnt.getOrDefault(k, 0) + 1); 24 | ans = Math.max(ans, cnt.get(k) + 1); 25 | } 26 | } 27 | return ans; 28 | } 29 | 30 | private int gcd(int a, int b) { 31 | return b == 0 ? a : gcd(b, a % b); 32 | } 33 | } -------------------------------------------------------------------------------- /Chapter 2/Problem150.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem150 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | String[] tokens = { "2", "1", "+", "3", "*" }; 7 | System.out.println(solution.evalRPN(tokens)); // Output: 9 8 | } 9 | } 10 | 11 | class Solution { 12 | public int evalRPN(String[] tokens) { 13 | Deque stk = new ArrayDeque<>(); 14 | for (String t : tokens) { 15 | if (t.length() > 1 || Character.isDigit(t.charAt(0))) { 16 | stk.push(Integer.parseInt(t)); 17 | } else { 18 | int y = stk.pop(); 19 | int x = stk.pop(); 20 | switch (t) { 21 | case "+": 22 | stk.push(x + y); 23 | break; 24 | case "-": 25 | stk.push(x - y); 26 | break; 27 | case "*": 28 | stk.push(x * y); 29 | break; 30 | default: 31 | stk.push(x / y); 32 | break; 33 | } 34 | } 35 | } 36 | return stk.pop(); 37 | } 38 | } -------------------------------------------------------------------------------- /Chapter 2/Problem151.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem151 { 4 | public static void main(String[] args) { 5 | Solution solution = new Solution(); 6 | String s = " hello world! "; 7 | String result = solution.reverseWords(s); 8 | System.out.println(result); // Output: "world! hello" 9 | } 10 | } 11 | 12 | class Solution { 13 | public String reverseWords(String s) { 14 | List words = Arrays.asList(s.trim().split("\\s+")); 15 | Collections.reverse(words); 16 | return String.join(" ", words); 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter 2/Problem152.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem152 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 2, 3, -2, 4 }; 6 | int result = solution.maxProduct(nums); 7 | System.out.println(result); // Output: 6 8 | } 9 | } 10 | 11 | class Solution { 12 | public int maxProduct(int[] nums) { 13 | int f = nums[0], g = nums[0], ans = nums[0]; 14 | for (int i = 1; i < nums.length; ++i) { 15 | int ff = f, gg = g; 16 | f = Math.max(nums[i], Math.max(ff * nums[i], gg * nums[i])); 17 | g = Math.min(nums[i], Math.min(ff * nums[i], gg * nums[i])); 18 | ans = Math.max(ans, f); 19 | } 20 | return ans; 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter 2/Problem153.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem153 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 3, 4, 5, 1, 2 }; 6 | int result = solution.findMin(nums); 7 | System.out.println(result); // Output: 1 8 | } 9 | } 10 | 11 | class Solution { 12 | public int findMin(int[] nums) { 13 | int n = nums.length; 14 | if (nums[0] <= nums[n - 1]) { 15 | return nums[0]; 16 | } 17 | int left = 0, right = n - 1; 18 | while (left < right) { 19 | int mid = (left + right) >> 1; 20 | if (nums[0] <= nums[mid]) { 21 | left = mid + 1; 22 | } else { 23 | right = mid; 24 | } 25 | } 26 | return nums[left]; 27 | } 28 | } -------------------------------------------------------------------------------- /Chapter 2/Problem154.java: -------------------------------------------------------------------------------- 1 | 2 | public class Problem154 { 3 | public static void main(String[] args) { 4 | Solution solution = new Solution(); 5 | int[] nums = { 3, 4, 5, 1, 2 }; 6 | int result = solution.findMin(nums); 7 | System.out.println(result); // Output: 1 8 | } 9 | } 10 | 11 | class Solution { 12 | public int findMin(int[] nums) { 13 | int left = 0, right = nums.length - 1; 14 | while (left < right) { 15 | int mid = (left + right) >> 1; 16 | if (nums[mid] > nums[right]) { 17 | left = mid + 1; 18 | } else if (nums[mid] < nums[right]) { 19 | right = mid; 20 | } else { 21 | --right; 22 | } 23 | } 24 | return nums[left]; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter 2/Problem155.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Problem155 { 4 | public static void main(String[] args) { 5 | MinStack minStack = new MinStack(); 6 | minStack.push(-2); 7 | minStack.push(0); 8 | minStack.push(-3); 9 | System.out.println(minStack.getMin()); // Returns -3. 10 | minStack.pop(); 11 | System.out.println(minStack.top()); // Returns 0. 12 | System.out.println(minStack.getMin()); // Returns -2. 13 | } 14 | } 15 | 16 | class MinStack { 17 | private Deque stk1 = new ArrayDeque<>(); 18 | private Deque stk2 = new ArrayDeque<>(); 19 | 20 | public MinStack() { 21 | stk2.push(Integer.MAX_VALUE); 22 | } 23 | 24 | public void push(int val) { 25 | stk1.push(val); 26 | stk2.push(Math.min(val, stk2.peek())); 27 | } 28 | 29 | public void pop() { 30 | stk1.pop(); 31 | stk2.pop(); 32 | } 33 | 34 | public int top() { 35 | return stk1.peek(); 36 | } 37 | 38 | public int getMin() { 39 | return stk2.peek(); 40 | } 41 | } -------------------------------------------------------------------------------- /Chapter 2/Problem156.java: -------------------------------------------------------------------------------- 1 | public class Problem156 { 2 | public static void main(String[] args) { 3 | TreeNode root = new TreeNode(1, new TreeNode(2, new TreeNode(4), new TreeNode(5)), new TreeNode(3)); 4 | Solution solution = new Solution(); 5 | TreeNode newRoot = solution.upsideDownBinaryTree(root); 6 | System.out.println("New Root: " + newRoot.val); 7 | } 8 | } 9 | 10 | class Solution { 11 | public TreeNode upsideDownBinaryTree(TreeNode root) { 12 | if (root == null || root.left == null) { 13 | return root; 14 | } 15 | TreeNode newRoot = upsideDownBinaryTree(root.left); 16 | root.left.right = root; 17 | root.left.left = root.right; 18 | root.left = null; 19 | root.right = null; 20 | return newRoot; 21 | } 22 | } --------------------------------------------------------------------------------