Leetcode 經典題目題解
public int singleNumber(int[] A) {
int rst = 0;
for(int a : A)
rst ^= a;
return rst;
}
note:
Java提供的位運算子有:左移( << )、右移( >> ) 、無符號右移( >>> ) 、位與( & ) 、位或( | )、位非( ~ )、位異或( ^ ),除了位非( ~ )是一元操作符外,其它的都是二元操作符。 正數左移一位相當於乘2,右移一位相當於除2
5換算成二進位制: 0000 0000 0000 0000 0000 0000 0000 0101
5右移3位後結果為0,0的二進位制為: 0000 0000 0000 0000 0000 0000 0000 0000 // (用0進行補位)
-5換算成二進位制: 1111 1111 1111 1111 1111 1111 1111 1011
-5右移3位後結果為-1,-1的二進位制為: 1111 1111 1111 1111 1111 1111 1111 1111 // (用1進行補位)
-5無符號右移3位後的結果 536870911 換算成二進位制: 0001 1111 1111 1111 1111 1111 1111 1111 // (用0進行補位)
現在想知道,-5在計算機中如何表示?
在計算機中,負數以其正值的補碼形式表達。
原碼:一個整數,按照絕對值大小轉換成的二進位制數,稱為原碼。
比如 00000000 00000000 00000000 00000101 是 5的 原碼。
反碼:將二進位制數按位取反,所得的新二進位制數稱為原二進位制數的反碼。
取反操作指:原為1,得0;原為0,得1。(1變0; 0變1)
比如:將00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。
稱:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反碼。
反碼是相互的,所以也可稱:
11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互為反碼。
補碼:反碼加1稱為補碼。
也就是說,要得到一個數的補碼,先得到反碼,然後將反碼加上1,所得數稱為補碼。
比如:00000000 00000000 00000000 00000101 的反碼是:11111111 11111111 11111111 11111010。
那麼,補碼為:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
所以,-5 在計算機中表達為:11111111 11111111 11111111 11111011。轉換為十六進位制:0xFFFFFFFB。
hint: 遞迴 code:
public int maxDepth(TreeNode root) { if(root == null) return 0; return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; }
Same Tree hint: 遞迴 code:
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null)
return true;
if(p == null || q == null)
return false;
if(p.val != q.val )
return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
Reverse Integer hint: StringBuilder 或 整數位數操作 code:
public int reverse(int x) {
int rst = 0;
while(x != 0){
if(Math.abs(rst) > 214748364) // 處理溢位 !! 214748364 9 這個本身反過來也是溢位的 也就是說最後一位只能是1
return 0;
rst = rst*10 + x%10;
x /= 10;
}
return rst;
}
public int reverse(int x) {
int y = Math.abs(x);
StringBuilder sb = new StringBuilder(y+"");
sb.reverse();
try{
y = Integer.parseInt(sb.toString());
}catch(NumberFormatException ex){
return 0;
}
return x < 0 ? -y : y;
}
Best Time to Buy and Sell Stock II hint: 觀察,求序列遞增的增量 code:
public int maxProfit(int[] prices) {
int sum = 0;
if(prices.length <= 1)
return sum;
for(int i=1; i<prices.length; ++i){
if(prices[i] > prices[i-1])
sum += prices[i] - prices[i-1];
}
return sum;
}
Linked List Cycle hint: 雙指標 一個走兩步 一個走一步, 如果快指標能追上慢指標 則存在cycle correctness: 分case證明, 走兩步的指標一定能與走一步的指標在某處相遇 且不超過一輪 或者可以思考 每一步快指標會追上一步,距離是逐一遞減,因此兩者距離必定經過0 即相遇點 如果快指標一次走三步,四步, 情況會怎樣? code:
public boolean hasCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow)
return true;
}
return false;
}
Binary Tree Preorder Traversal hint: use stack for the non-recursion solution code:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> rst = new ArrayList<Integer>();
if(root == null)
return rst;
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
while(!stack.isEmpty()){
root = stack.pop();
rst.add(root.val);
if(root.right != null)
stack.push(root.right);
if(root.left != null)
stack.push(root.left);
}
return rst;
}
Binary Tree Inorder Traversal hint: 難點在於如何處理輸出順序:對於每一個棧頂的節點 先將其和其所有left-most節點壓入棧 直到棧頂節點left child為空, 輸出該節點val。 再壓入其右節點 進行下一輪迴圈, 注意此時指標目標
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> rst = new ArrayList<Integer>();
if(root == null)
return rst;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode curr = root;
while(!stack.isEmpty() || curr != null){
while(curr != null){
stack.push(curr);
curr = curr.left;
}
curr = stack.pop();
rst.add(curr.val);
curr = curr.right;
}
return rst;
}
Populating Next Right Pointers in Each Node hint: 觀察結構 遞迴解決
public void connect(TreeLinkNode root) {
if(root == null || root.left == null || root.right == null)
return;
root.left.next = root.right;
if(root.next != null)
root.right.next = root.next.left;
connect(root.right);
connect(root.left);
}
Remove Duplicates from Sorted List hint: list操作
public ListNode deleteDuplicates(ListNode head) {
if(head == null)
return head;
ListNode curr = head;
while(curr.next != null){
if(curr.val == curr.next.val)
curr.next = curr.next.next;
else
curr = curr.next;
}
return head;
}
Search Insert Position hint: linear array search 秒殺
public int searchInsert(int[] A, int target) {
for(int i=0; i<A.length; ++i){
if(A[i] == target || A[i] > target)
return i;
}
return A.length;
}
binary search:
public int searchInsert(int[] nums, int target) {
int left = 0;
int right = nums.length-1;
int rst = 0;
while(left <= right){
if(left == right){
rst = target <= nums[left] ? left : left+1;
break;
}
int mid = left + (right-left)/2;
if(nums[mid] == target){
rst = mid;
break;
}
else if(nums[mid] > target){
right = mid;
}
else
left = mid+1;
}
return rst;
}
Climbing Stairs hint: 一維DP
public int climbStairs(int n) {
int[] dp = new int[n+1];
dp[0] = 1;
dp[1] = 1;
for(int i=2; i<=n; ++i){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
Maximum Subarray hint: O(n) 陣列線性掃描
public int maxSubArray(int[] A) {
int max = Integer.MIN_VALUE;
int sum = 0;
for(int i=0; i<A.length; i++){
sum += A[i];
if(sum > max)
max = sum;
if(sum < 0)
sum = 0;
}
return max;
}
dp:
public int maxSubArray(int[] A) {
int[] dp = new int[A.length];
dp[0] = A[0];
for(int i=1; i<A.length; ++i){
if(dp[i-1] < 0)
dp[i] = A[i];
else
dp[i] = A[i] + dp[i-1];
}
int max = Integer.MIN_VALUE;
for(int i=0; i<dp.length; ++i)
if(dp[i] > max)
max = dp[i];
return max;
}
Roman to Integer
public int romanToInt(String s) {
int rst = 0;
for(int i=0; i<s.length(); i++){
if(i>0 && charToNum(s.charAt(i)) > charToNum(s.charAt(i-1)))
rst += (charToNum(s.charAt(i)) - 2*charToNum(s.charAt(i-1)));
else
rst += charToNum(s.charAt(i));
}
return rst;
}
private int charToNum(char c){
switch(c){
case 'I': return 1;
case 'V': return 5;
case 'X': return 10;
case 'L': return 50;
case 'C': return 100;
case 'D': return 500;
case 'M': return 1000;
default: return 0;
}
}
N-Queens II
hint: cols[i] 記錄第i行的queen放在了第幾列。
public int totalNQueens(int n) {
int[] cols = new int[n];
return dfs(cols, n, 0);
}
public int dfs(int[] cols, int n, int row){
if(row == n){
return 1;
}
int num = 0;
for(int i=0; i<n; ++i){
boolean used = false;
for(int j=0; j<row; ++j)
if(cols[j] == i || cols[j] + j == i + row || cols[j] - j == i - row){
used = true;
break;
}
if(!used){
cols[row] = i;
num += dfs(cols, n, row+1);
}
}
return num;
}
public int totalNQueens(int n) {
int[] used = new int[n];
int[] ang = new int[2*n];
int[] anti = new int[2*n];
return dfs(used, ang, anti, n, 0);
}
private int dfs(int[] used, int[] ang, int[] anti, int n, int k){
if(k == n)
return 1;
int count = 0;
for(int i=0; i<n; ++i){
if(used[i] == 0 && ang[i+k] == 0 && anti[i-k+n] == 0){
used[i] = 1;
ang[i+k] = 1;
anti[i-k+n] = 1;
count += dfs(used, ang, anti, n, k+1);
used[i] = 0;
ang[i+k] = 0;
anti[i-k+n] = 0;
}
}
return count;
}
Single Number II hint: 因為題目已經說了,除了一個數字以外,其他的都出現了3次,如果我們把那個特殊的數剔除,並把剩下的數於每一位來加和的話,每一位上1出現的次數必然都是3的倍數。所以,解法就在這裡,將每一位數字分解到32個bit上,統計每一個bit上1出現的次數。最後對於每一個bit上1出現的個數對3取模,剩下的就是結果。
public int singleNumber(int[] A) {
int[] bits = new int[32];
int rst = 0;
for(int i=31; i>=0; --i){
for(int j=0; j<A.length; j++)
bits[i] += (A[j]>>i)&1;
bits[i] %= 3;
rst = (rst<<1)+bits[i];
}
return rst;
}
Integer to Roman
public String intToRoman(int num) {
String[] roman = {"I", "V", "X", "L", "C", "D", "M"};
String rst = "";
int level = 1000;
for(int i=6; i>=0; i-=2){
int digit = num/level;
if(digit != 0){
if(digit <= 3){
for(int j=0; j<digit; ++j)
rst += roman[i];
}
else if(digit == 4){
rst += roman[i];
rst += roman[i+1];
}
else if(digit == 5)
rst += roman[i+1];
else if(digit <= 8){
rst += roman[i+1];
for(int j=0; j<digit-5; ++j)
rst += roman[i];
}
else if(digit == 9){
rst += roman[i];
rst += roman[i+2];
}
}
num %= level;
level /= 10;
}
return rst;
}
Merge Two Sorted Lists
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode rst = new ListNode(0);
ListNode curr = rst;
while(l1 != null && l2 != null){
if(l1.val < l2.val){
curr.next= l1;
curr = curr.next;
l1 = l1.next;
}
else{
curr.next = l2;
curr = curr.next;
l2 = l2.next;
}
}
while(l1 != null){
curr.next = l1;
curr = curr.next;
l1 = l1.next;
}
while(l2 != null){
curr.next = l2;
curr = curr.next;
l2 = l2.next;
}
return rst.next;
}
遞迴解法
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null && l2 == null)
return null;
else if(l1 == null || l2 == null)
return (l1!=null ? l1 : l2);
ListNode head;
if(l1.val < l2.val){
head = l1;
head.next = mergeTwoLists(l1.next, l2);
}
else{
head = l2;
head.next = mergeTwoLists(l1, l2.next);
}
return head;
}
Remove Element hint: 雙指標操作
public int removeElement(int[] nums, int val) {
if(nums == null || nums.length == 0)
return 0;
int p = 0;
for(int i=0; i<nums.length; ++i){
if(nums[i] != val){
nums[p++] = nums[i];
}
}
return p;
}
Convert Sorted Array to Binary Search Tree hint: 遞迴
public TreeNode sortedArrayToBST(int[] num) {
if(num.length < 1)
return null;
return bst(num, 0, num.length-1);
}
public TreeNode bst(int[] num, int start, int end){
if(start > end)
return null;
int mid = start + (end-start)/2; // 防止溢位
TreeNode node = new TreeNode(num[mid]);
node.left = bst(num, start, mid-1);
node.right = bst(num, mid+1, end);
return node;
}
Balanced Binary Tree hint: 設個外部變數, 通過計算高度遍歷tree
public boolean isBalanced(TreeNode root) {
return height(root) != -1;
}
public int height(TreeNode node){
if(node == null)
return 0;
int lefth = height(node.left);
int righth = height(node.right);
if(lefth < 0 || righth < 0 || Math.abs(lefth-righth) > 1)
return -1;
return Math.max(lefth, righth) + 1;
}
Remove Duplicates from Sorted Array hint: 雙指標掃陣列
public int removeDuplicates(int[] A) {
if(A.length <= 1)
return A.length;
int index = 0;
for(int i=1; i<A.length; ++i){
if(A[i] == A[index])
continue;
A[++index] = A[i];
}
return index+1;
}
Swap Nodes in Pairs
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode prev = dummy;
ListNode curr = head;
while(curr != null && curr.next != null){
prev.next = curr.next;
curr.next = curr.next.next;
prev.next.next = curr;
prev = curr;
curr = curr.next;
}
return dummy.next;
}
Symmetric Tree note: 兩種解法 iterative method:
public boolean isSymmetric(TreeNode root) {
if(root == null)
return true;
Queue<TreeNode> qleft = new LinkedList<TreeNode>();
Queue<TreeNode> qright = new LinkedList<TreeNode>();
qleft.offer(root.left);
qright.offer(root.right);
while(!qleft.isEmpty() && !qright.isEmpty()){
TreeNode left = qleft.poll();
TreeNode right = qright.poll();
if(left == null && right == null)
continue;
if(left == null || right == null || right.val != left.val)
return false;
qleft.offer(left.left);
qright.offer(right.right);
qleft.offer(left.right);
qright.offer(right.left);
}
return true;
}
recursion method:
public boolean isSymmetric(TreeNode root) {
if(root == null)
return true;
return isMirror(root.left, root.right);
}
private boolean isMirror(TreeNode left, TreeNode right){
if(left == null && right == null)
return true;
if(left == null || right == null || left.val != right.val)
return false;
return isMirror(left.right, right.left) && isMirror(left.left, right.right);
}
Sort Colors hint: 陣列三指標操作
public void sortColors(int[] A) {
int left = 0;
int curr = 0;
int right = A.length - 1;
while(curr <= right){
if(A[curr] == 0){
A[curr] = A[left];
A[left++] = 0;
}
else if(A[curr] == 2){
A[curr] = A[right];
A[right--] = 2;
}
else{
++curr;
}
if(curr < left)
curr++;
}
}
Merge Sorted Array hint: 從後往前 從大到小填空
public void merge(int A[], int m, int B[], int n) {
int inda = m - 1;
int indb = n - 1;
for(int i=m+n-1; i>=0; --i){
if(inda < 0)
A[i] = B[indb--];
else if(indb < 0)
A[i] = A[inda--];
else if(A[inda] > B[indb])
A[i] = A[inda--];
else
A[i] = B[indb--];
}
}
Gray Code recursive:
public List<Integer> grayCode(int n) {
List<Integer> rst = new ArrayList<Integer>();
if(n == 0){
rst.add(0);
return rst;
}
List<Integer> list = grayCode(n-1);
for(int i=0; i<list.size(); ++i){
rst.add((list.get(i)<<1) + i%2);
rst.add((list.get(i)<<1) + (i+1)%2);
}
return rst;
}
Iterative: n=k時的Gray Code,相當於n=k-1時的Gray Code的逆序 加上 1<<k
public List<Integer> grayCode(int n) {
List<Integer> rst = new ArrayList<Integer>();
rst.add(0);
for(int i=0; i<n; ++i)
for(int j=rst.size()-1; j>=0; --j){
rst.add(rst.get(j) + (1<<i));
}
return rst;
}
Plus One
public int[] plusOne(int[] digits) {
int add = 1;
for(int i=digits.length-1; i>=0; --i){
int sum = digits[i] + add;
digits[i] = sum%10;
add = sum/10;
}
int[] rst = digits;
if(add == 1){
rst = new int[digits.length+1];
rst[0] = 1;
for(int i=1; i<rst.length; ++i)
rst[i] = digits[i-1];
}
return rst;
}
Unique Paths hint: DP 二維:
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for(int i=0; i<m; ++i)
dp[i][0] = 1;
for(int i=0; i<n; ++i)
dp[0][i] = 1;
for(int i=1; i<m; ++i)
for(int j=1; j<n; ++j){
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
return dp[m-1][n-1];
}
一維:
public int uniquePaths(int m, int n) {
int[] dp = new int[m];
dp[0] = 1;
for(int i=0; i<n; ++i)
for(int j=1; j<m; ++j){
dp[j] = dp[j] + dp[j-1];
}
return dp[m-1];
}
Unique Binary Search Trees
public int numTrees(int n) {
if(n <= 1)
return 1;
int rst = 0;
for(int i=0; i<n; ++i){
rst += numTrees(i) * numTrees(n-i-1);
}
return rst;
}
dp
public int numTrees(int n) {
if(n <= 1)
return n;
int[] dp = new int[n+1];
dp[0] = 1;
dp[1] = 1;
for(int i=2; i<=n; ++i){
for(int j=0; j<i; j++)
dp[i] += dp[j]*dp[i-j-1];
}
return dp[n];
}
Find Minimum in Rotated Sorted Array
public int findMin(int[] num) {
return getMin(num, 0, num.length-1);
}
public int getMin(int[] num, int left, int right){
if(left == right || num[left] < num[right])
return num[left];
int mid = left + (right-left)/2;
if(num[right] < num[mid])
return getMin(num, mid+1, right);
else
return getMin(num, left, mid);
}
Find Minimum in Rotated Sorted Array II
public int findMin(int[] nums) {
if(nums == null || nums.length == 0)
return -1;
return findMin(nums, 0, nums.length-1);
}
private int findMin(int[] nums, int left, int right){
if(left == right || nums[left] < nums[right])
return nums[left];
int mid = left + (right - left)/2;
if(nums[mid] < nums[right]){
return findMin(nums, left, mid);
}
else if(nums[mid] > nums[right]){
return findMin(nums, mid+1, right);
}
else
return findMin(nums, left, right-1);
}
Iterative solution:
public int findMin(int[] nums) {
int left = 0;
int right = nums.length-1;
while(left <= right){
if(left == right || nums[left] < nums[right])
return nums[left];
if(nums[left] == nums[right]){
right--;
continue;
}
int mid = left + (right-left)/2;
if(nums[mid] > nums[right])
left = mid + 1;
else
right = mid;
}
return nums[left];
}
Find Peak Element Given an input array where
num[i] ≠ num[i+1]
, find
a peak element and return its index.public int findPeakElement(int[] nums) {
if(nums == null || nums.length <= 1)
return 0;
int left = 0;
int right = nums.length-1;
while(left + 1 < right){
int mid = left + (right-left)/2;
if(nums[mid] > nums[mid-1] && nums[mid] > nums[mid+1])
return mid;
if(nums[mid] < nums[mid-1])
right = mid;
else
left = mid;
}
return nums[left] > nums[right] ? left : right;
}
Container With Most Water
public int maxArea(int[] height) {
if(height.length <= 1)
return 0;
int left = 0;
int right = height.length-1;
int max = 0;
while(left < right){
int val = Math.min(height[left], height[right]) * (right - left);
if(val > max)
max = val;
if(height[left] < height[right])
left++;
else
right--;
}
return max;
}
Rotate Image
public void rotate(int[][] matrix) {
int row = matrix.length;
int col = matrix[0].length;
for(int i=0; i<row-1; ++i)
for(int j=i; j<col; ++j){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
for(int i=0; i<row; ++i)
for(int j=0; j<col/2; ++j){
int temp = matrix[i][j];
matrix[i][j] = matrix[i][col-1-j];
matrix[i][col-1-j] = temp;
}
}
Generate Parentheses
public List<String> generateParenthesis(int n) {
List<String> rst = new ArrayList<String>();
dfs(rst, n, n, "");
return rst;
}
public void dfs(List<String> list, int l, int r, String str){
if(l == 0){
while(r-- > 0)
str += ")";
list.add(str);
return;
}
dfs(list, l-1, r, str+"(");
if(l < r)
dfs(list, l, r-1, str+")");
}
Permutations
public List<List<Integer>> permute(int[] num) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
dfs(rst, num, new ArrayList<Integer>());
return rst;
}
public void dfs(List<List<Integer>> rst, int[] num, List<Integer> list){
if(list.size() == num.length){
rst.add(new ArrayList<Integer>(list));
return;
}
for(int i=0; i<num.length; ++i)
if(!list.contains(num[i])){
list.add(num[i]);
dfs(rst, num, list);
list.remove(list.size()-1);
}
}
Minimum Path Sum
public int minPathSum(int[][] grid) {
int n = grid[0].length;
int[] dp = new int[n];
dp[0] = grid[0][0];
for(int i=1; i<n; ++i)
dp[i] = grid[0][i] + dp[i-1];
for(int i=1; i<grid.length; ++i){
dp[0] += grid[i][0];
for(int j=1; j<n; ++j)
dp[j] = Math.min(dp[j], dp[j-1]) + grid[i][j];
}
return dp[n-1];
}
Search a 2D Matrix
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0)
return false;
int m = matrix.length;
int n = matrix[0].length;
int left = 0;
int right = m*n-1;
while(left <= right){
int mid = left + (right-left)/2;
if(matrix[mid/n][mid%n] == target)
return true;
else if(matrix[mid/n][mid%n] < target)
left = mid+1;
else
right = mid-1;
}
return false;
}
Path Sum
public boolean hasPathSum(TreeNode root, int sum) {
if(root == null)
return false;
if(root.left == null && root.right == null)
return sum == root.val;
return hasPathSum(root.left, sum-root.val) || hasPathSum(root.right, sum-root.val);
}
Combinations
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
if(n == 0 || n < k)
return rst;
dfs(rst, new ArrayList<Integer>(), n, 1, k);
return rst;
}
private void dfs(List<List<Integer>> rst, List<Integer> list, int n, int p, int k){
if(k == 0){
rst.add(new ArrayList<Integer>(list));
return;
}
for(int i=p; i<=n; ++i){
list.add(i);
dfs(rst, list, n, i+1, k-1);
list.remove(list.size()-1);
}
}
Binary Tree Postorder Traversal
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> rst = new ArrayList<Integer>();
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode nd = stack.pop();
if(nd == null)
continue;
rst.add(0, nd.val);
stack.push(nd.left);
stack.push(nd.right);
}
return rst;
}
Search in Rotated Sorted Array
public int search(int[] A, int target) {
return binarySearch(A, target, 0, A.length-1);
}
public int binarySearch(int[] A, int target, int left, int right){
if(left > right)
return -1;
int mid = left + (right-left)/2;
if(A[mid] == target)
return mid;
if(A[left] < A[right]){
if(A[mid] > target)
return binarySearch(A, target, left, mid);
else
return binarySearch(A, target, mid+1, right);
}
else if(A[mid] < A[right]){
if(target > A[mid] && target <= A[right])
return binarySearch(A, target, mid+1, right);
else
return binarySearch(A, target, left, mid);
}
else{
if(target >= A[left] && target < A[mid])
return binarySearch(A, target, left, mid);
else
return binarySearch(A, target, mid+1, right);
}
}
Search in Rotated Sorted Array II
public boolean search(int[] A, int target) {
int left = 0;
int right = A.length - 1;
while(left <= right){
int mid = left + (right-left)/2;
if(A[mid] == target)
return true;
if(A[left] < A[right]){
if(A[mid] > target)
right = mid;
else
left = mid+1;
}
else if(A[mid] == A[left] && A[mid] == A[right])
left++;
else{
if(A[mid] >= A[left]){
if(A[mid] > target && A[left] <= target)
right = mid;
else
left = mid+1;
}
else{
if(A[mid] < target && A[right] >= target)
left = mid+1;
else
right = mid;
}
}
}
return false;
}
Populating Next Right Pointers in Each Node II
public void connect(TreeLinkNode root) {
if(root == null || root.left == null && root.right == null)
return;
if(root.left != null)
root.left.next = root.right == null ? getNode(root.next) : root.right;
if(root.right != null)
root.right.next = getNode(root.next);
connect(root.right);
connect(root.left);
}
public TreeLinkNode getNode(TreeLinkNode node){
if(node == null)
return null;
if(node.left != null)
return node.left;
if(node.right != null)
return node.right;
return getNode(node.next);
}
Binary Tree Level Order Traversal II
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
if(root == null)
return rst;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
List<Integer> list = new ArrayList<Integer>();
queue.offer(root);
int count = 0;
int num = 1;
while(!queue.isEmpty()){
TreeNode node = queue.poll();
num--;
list.add(node.val);
if(node.left != null){
queue.offer(node.left);
count++;
}
if(node.right != null){
queue.offer(node.right);
count++;
}
if(num == 0){
rst.add(0, new ArrayList(list));
list.clear();
num = count;
count = 0;
}
}
return rst;
}
Set Matrix Zeroes
public void setZeroes(int[][] matrix) {
int row = matrix.length;
int col = matrix[0].length;
boolean rowZero = false;
boolean colZero = false;
for(int i=0; i<col; ++i)
if(matrix[0][i] == 0)
rowZero = true;
for(int i=0; i<row; ++i)
if(matrix[i][0] == 0)
colZero = true;
for(int i=1; i<row; ++i)
for(int j=1; j<col; ++j)
if(matrix[i][j] == 0){
matrix[i][0] = 0;
matrix[0][j] = 0;
}
for(int i=1; i<row; ++i)
for(int j=1; j<col; ++j)
if(matrix[i][0] == 0 || matrix[0][j] == 0)
matrix[i][j] = 0;
if(rowZero)
for(int i=0; i<col; ++i)
matrix[0][i] = 0;
if(colZero)
for(int i=0; i<row; ++i)
matrix[i][0] = 0;
}
Remove Duplicates from Sorted Array II
public int removeDuplicates(int[] nums) {
if(nums == null || nums.length == 0)
return 0;
int left = 0;
int right = 1;
int count = 0;
while(right < nums.length){
if(nums[right] == nums[left]){
++count;
if(count < 2){
nums[++left] = nums[right++];
} else{
right++;
}
}
else{
count = 0;
nums[++left] = nums[right++];
}
}
return left + 1;
}
public int removeDuplicates(int[] A) {
if(A.length <= 2)
return A.length;
int p = 2;
for(int i=2; i<A.length; ++i){
if(A[i] != A[p-2])
A[p++] = A[i];
}
return p;
}
Subsets bit operation methods 請見解答pdf
public List<List<Integer>> subsets(int[] S) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
Arrays.sort(S);
dfs(rst, new ArrayList<Integer>(), S, 0);
return rst;
}
public void dfs(List<List<Integer>> rst, List<Integer> list, int[] S, int n){
if(n >= S.length){
rst.add(new ArrayList<Integer>(list));
return;
}
dfs(rst, list, S, n+1);
list.add(S[n]);
dfs(rst, list, S, n+1);
list.remove(list.size()-1);
}
Binary Tree Level Order Traversal
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
print(rst, root, 1);
return rst;
}
public void print(List<List<Integer>> rst, TreeNode node, int level){
if(node == null)
return;
if(rst.size() < level){
List<Integer> list = new ArrayList<Integer>();
list.add(node.val);
rst.add(list);
}
else
rst.get(level-1).add(node.val);
print(rst, node.left, level+1);
print(rst, node.right, level+1);
}
Sum Root to Leaf Numbers
private int sum;
public int sumNumbers(TreeNode root) {
sum = 0;
dfs(root, 0);
return sum;
}
public void dfs(TreeNode node, int num){
if(node == null)
return;
if(node.left == null && node.right == null){
sum += num*10 + node.val;
}
dfs(node.left, 10*num + node.val);
dfs(node.right, 10*num + node.val);
}
Trapping Rain Water two pointers, value copy when traversal
public int trap(int[] A) {
int left = 0;
int right = A.length-1;
int sum = 0;
while(right-left > 1){
if(A[left] < A[right]){
sum += A[left+1]<A[left] ? A[left]-A[left+1] : 0;
A[left+1] = Math.max(A[left], A[left+1]);
left++;
}
else{
sum += A[right-1]<A[right] ? A[right]-A[right-1] : 0;
A[right-1] = Math.max(A[right], A[right-1]);
right--;
}
}
return sum;
}
public int trap(int[] height) {
if(height == null || height.length <= 2)
return 0;
int rst = 0;
int left= 0;
int right = height.length-1;
int h = Math.min(height[left], height[right]);
while(left < right){
if(height[left] < height[right]){
rst += h > height[left] ? h - height[left] : 0;
if(height[++left] > h)
h = Math.min(height[left], height[right]);
}
else{
rst += h > height[right] ? h - height[right] : 0;
if(height[--right] > h)
h = Math.min(height[left], height[right]);
}
}
return rst;
}