public int singleNumber(int[] A) {
int rst = 0;
for(int a : A)
rst ^= a;
return rst;
}
Java提供的位运算符有:左移( << )、右移( >> ) 、无符号右移( >>> ) 、位与( & ) 、位或( | )、位非( ~ )、位异或( ^ ),除了位非( ~ )是一元操作符外,其它的都是二元操作符。
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。
public int maxDepth(TreeNode root) {
if(root == null)
return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
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);
}
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;
}
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;
}
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;
}
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;
}
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;
}
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);
}
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;
}
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;
}
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;
}
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];
}
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;
}
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;
}
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;
}
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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);
}
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++;
}
}
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--];
}
}
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;
}
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;
}
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;
}
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];
}
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;
}
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];
}
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);
}
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);
}
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];
}
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;
}
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;
}
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;
}
}
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+")");
}
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);
}
}
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];
}
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;
}
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);
}
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);
}
}
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;
}
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);
}
}
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;
}
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);
}
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;
}
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;
}
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;
}
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);
}
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);
}
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);
}
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;
}
public int minDepth(TreeNode root) {
return minDepth(root, false);
}
public int minDepth(TreeNode node, boolean hasBrother){
if(node == null)
return hasBrother ? Integer.MAX_VALUE : 0;
return 1 + Math.min(minDepth(node.left, node.right != null), minDepth(node.right, node.left != null));
}
public int minDepth(TreeNode root) {
if(root == null)
return 0;
if(root.left == null && root.right == null)
return 1;
if(root.left != null && root.right != null)
return 1+Math.min(minDepth(root.left), minDepth(root.right));
if(root.left != null)
return 1+minDepth(root.left);
else
return 1+minDepth(root.right);
}
public boolean isPalindrome(int x) {
if(x < 0)
return false;
int d = 1;
int y = x/10;
while(y > 0){
y /= 10;
d *= 10;
}
while(d > 1){
if(x/d != x%10)
return false;
x = (x - d*(x/d))/10;
d /= 100;
}
return true;
}
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode p = dummy;
ListNode q = dummy;
for(int i=0; i<n; ++i)
q = q.next;
while(q.next != null){
q = q.next;
p = p.next;
}
p.next = p.next.next;
return dummy.next;
}
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int row = obstacleGrid.length;
int col = obstacleGrid[0].length;
int[] dp = new int[col];
if(obstacleGrid[0][0] == 0)
dp[0] = 1;
for(int i=0; i<row; ++i){
if(obstacleGrid[i][0] == 1)
dp[0] = 0;
for(int j=1; j<col; ++j){
if(obstacleGrid[i][j] == 1)
dp[j] = 0;
else
dp[j] += dp[j-1];
}
}
return dp[col-1];
}
public int longestConsecutive(int[] num) {
Map<Integer, Boolean> map = new HashMap<Integer, Boolean>();
for(int i=0; i<num.length; ++i)
map.put(num[i], false);
int max = 0;
for(int x : num){
if(map.get(x))
continue;
map.put(x, true);
int len = 1;
for(int i=1; map.containsKey(x+i); ++i){
len++;
map.put(x+i, true);
}
for(int i=1; map.containsKey(x-i); ++i){
len++;
map.put(x-i, true);
}
if(len > max)
max = len;
}
return max;
}
public void flatten(TreeNode root) {
while(root != null){
if(root.left != null){
getRightMost(root.left).right = root.right;
root.right = root.left;
root.left = null;
}
root = root.right;
}
}
public TreeNode getRightMost(TreeNode node){
while(node.right != null)
node = node.right;
return node;
}
public boolean isValid(String s) {
Stack<Character> stack = new Stack<Character>();
for(int i=0; i<s.length(); ++i){
char ch = s.charAt(i);
if(ch == '(' || ch == '[' || ch == '{')
stack.push(ch);
else if(stack.isEmpty())
return false;
else{
char ch2 = stack.pop();
if(ch == ')' && ch2 != '(' || ch == '[' && ch2 != ']' || ch == '{' && ch2 != '}')
return false;
}
}
return stack.isEmpty();
}
public int[] searchRange(int[] A, int target) {
int[] rst = new int[2];
rst[0] = -1;
rst[1] = -1;
int left = 0;
int right = A.length-1;
while(left <= right){
int mid = left + (right-left)/2;
if(A[mid] == target){
rst[0] = mid;
right = mid-1;
}
else if(A[mid] < target)
left = mid+1;
else
right = mid-1;
}
left = 0;
right = A.length-1;
while(left <= right){
int mid = left + (right-left)/2;
if(A[mid] == target){
rst[1] = mid;
left = mid+1;
}
else if(A[mid] < target)
left = mid+1;
else
right = mid-1;
}
return rst;
}
public boolean isValidSudoku(char[][] board) {
for(int i=0; i<9; ++i){
int[] row = new int[10];
int[] col = new int[10];
for(int j=0; j<9; ++j){
if(board[i][j] != '.'){
int val = board[i][j] - '0';
if(row[val] == 1)
return false;
else
row[val] = 1;
}
if(board[j][i] != '.'){
int val = board[j][i] - '0';
if(col[val] == 1)
return false;
else
col[val] = 1;
}
}
}
for(int i=0; i<9; i+=3)
for(int j=0; j<9; j+=3){
int[] cell = new int[10];
for(int m=0; m<3; ++m)
for(int n=0; n<3; ++n){
if(board[i+m][j+n] != '.'){
int val = board[i+m][j+n] - '0';
if(cell[val] == 1)
return false;
else
cell[val] = 1;
}
}
}
return true;
}
public List<List<Integer>> subsetsWithDup(int[] num) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
Arrays.sort(num);
dfs(rst, new ArrayList<Integer>(), num, 0);
return rst;
}
public void dfs(List<List<Integer>> rst, List<Integer> list, int[] num, int n){
if(n >= num.length){
rst.add(new ArrayList<Integer>(list));
return;
}
list.add(num[n]);
dfs(rst, list, num, n+1);
list.remove(list.size()-1);
int i = 1;
for(; i+n<num.length; ++i)
if(num[n+i] != num[n])
break;
dfs(rst, list, num, n+i);
}
public boolean canJump(int[] A) {
int term = 0;
int p = 0;
while(term < A.length && term >= p){
if(p + A[p] > term)
term = p + A[p];
p++;
}
return term >= A.length-1;
}
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
Arrays.sort(candidates);
dfs(rst, new ArrayList<Integer>(), candidates, 0, target);
return rst;
}
public void dfs(List<List<Integer>> rst, List<Integer> list,int[] cand, int n, int target){
if(target == 0){
rst.add(new ArrayList<Integer>(list));
return;
}
if(target < 0 || n >= cand.length || cand[n] > target)
return;
list.add(cand[n]);
dfs(rst, list, cand, n, target-cand[n]);
list.remove(list.size()-1);
dfs(rst, list, cand, n+1, target);
}
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
Arrays.sort(candidates);
dfs(rst, new ArrayList<Integer>(), candidates, 0, target);
return rst;
}
private void dfs(List<List<Integer>> rst, List<Integer> list, int[] cand, int k, int target){
if(target == 0){
rst.add(new ArrayList<Integer>(list));
return;
}
for(int i=k; i<cand.length; ++i){
if(cand[i] <= target){
list.add(cand[i]);
dfs(rst, list, cand, i, target-cand[i]);
list.remove(list.size()-1);
}
}
}
public ListNode partition(ListNode head, int x) {
ListNode dummy1 = new ListNode(0);
ListNode dummy2 = new ListNode(0);
ListNode end1 = dummy1;
ListNode end2 = dummy2;
while(head != null){
if(head.val < x){
end1.next = head;
end1 = end1.next;
}
else{
end2.next = head;
end2 = end2.next;
}
head = head.next;
}
end2.next = null;
end1.next = dummy2.next;
return dummy1.next;
}
public List<TreeNode> generateTrees(int n) {
return dfs(1, n);
}
public List<TreeNode> dfs(int start, int end){
List<TreeNode> rst = new ArrayList<TreeNode>();
if(start > end){
rst.add(null);
return rst;
}
for(int i=start; i<=end; ++i){
List<TreeNode> left = dfs(start, i-1);
List<TreeNode> right = dfs(i+1, end);
for(int m=0; m<left.size(); ++m)
for(int n=0; n<right.size(); ++n){
TreeNode root = new TreeNode(i);
root.left = left.get(m);
root.right = right.get(n);
rst.add(root);
}
}
return rst;
}
public int minimumTotal(List<List<Integer>> triangle) {
int m = triangle.size();
int n = triangle.get(m-1).size();
int[] dp = new int[n+1];
for(int i=m-1; i>=0; --i)
for(int j=0; j<triangle.get(i).size(); ++j){
dp[j] = Math.min(dp[j], dp[j+1]) + triangle.get(i).get(j);
}
return dp[0];
}
public String longestCommonPrefix(String[] strs) {
if(strs.length == 0)
return "";
int len = strs[0].length();
int comm = Integer.MAX_VALUE;
for(int i=0; i<strs.length; ++i){
int length = 0;
for(int j=0; j<len && j<strs[i].length(); ++j){
if(strs[0].charAt(j) != strs[i].charAt(j))
break;
length++;
}
if(length < comm)
comm = length;
}
return strs[0].substring(0,comm);
}
public String longestCommonPrefix(String[] strs) {
if(strs == null || strs.length == 0)
return "";
int len = 0;
for(int i=0; i<strs[0].length(); ++i){
boolean same = true;
char ch = strs[0].charAt(i);
for(String str : strs){
if(i >= str.length() || str.charAt(i) != ch){
same = false;
break;
}
}
if(!same)
break;
len++;
}
return strs[0].substring(0, len);
}
public int majorityElement(int[] num) {
Arrays.sort(num);
return num[num.length/2];
}
public int majorityElement(int[] nums) {
int count = 1;
int num = nums[0];
for(int i=1; i<nums.length; ++i){
if(count == 0){
count++;
num = nums[i];
}
else if(nums[i] == num)
count++;
else
count--;
}
return num;
}
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
dfs(rst, new ArrayList<Integer>(), root, sum);
return rst;
}
public void dfs(List<List<Integer>> rst, List<Integer> list, TreeNode node, int sum){
if(node == null)
return;
if(node.val == sum && node.left == null && node.right == null){
list.add(node.val);
rst.add(new ArrayList<Integer>(list));
list.remove(list.size()-1);
return;
}
list.add(node.val);
dfs(rst, list, node.left, sum-node.val);
dfs(rst, list, node.right, sum-node.val);
list.remove(list.size()-1);
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode pa = headA, pb = headB;
int lena = 0, lenb = 0;
while(pa != null){
lena++;
pa = pa.next;
}
while(pb != null){
lenb++;
pb = pb.next;
}
pa = headA;
pb = headB;
if(lena > lenb){
for(int i=0; i<lena-lenb; ++i)
pa = pa.next;
}
else{
for(int i=0; i<lenb-lena; ++i)
pb = pb.next;
}
while(pa != null){
if(pa == pb)
return pa;
pa = pa.next;
pb = pb.next;
}
return null;
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode currA = headA;
ListNode currB = headB;
while(currA != currB){
if(currA == null)
currA = headB;
else
currA = currA.next;
if(currB == null)
currB = headA;
else
currB = currB.next;
}
return currA;
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
return build(inorder, 0, inorder.length-1, postorder, 0, postorder.length-1);
}
public TreeNode build(int[] inorder, int lin, int rin, int[] postorder, int lpost, int rpost){
if(lin > rin || lpost > rpost)
return null;
int count = 0;
for(int i=0; i<rin-lin+1; ++i){
if(inorder[lin+i] == postorder[rpost])
break;
++count;
}
TreeNode root = new TreeNode(postorder[rpost]);
root.left = build(inorder, lin, lin+count-1, postorder, lpost, lpost+count-1);
root.right = build(inorder, lin+count+1, rin, postorder, lpost+count, rpost-1);
return root;
}
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
Stack<TreeNode> stack = new Stack<TreeNode>();
Stack<TreeNode> stack2 = new Stack<TreeNode>();
List<List<Integer>> rst = new ArrayList<List<Integer>>();
stack2.push(root);
while(!stack.isEmpty() || !stack2.isEmpty()){
TreeNode node = null;
List<Integer> list = new ArrayList<Integer>();
while(!stack2.isEmpty()){
node = stack2.pop();
if(node != null){
list.add(node.val);
stack.push(node.left);
stack.push(node.right);
}
}
if(list.size() > 0)
rst.add(list);
list = new ArrayList<Integer>();
while(!stack.isEmpty()){
node = stack.pop();
if(node != null){
list.add(node.val);
stack2.push(node.right);
stack2.push(node.left);
}
}
if(list.size() > 0)
rst.add(list);
}
return rst;
}
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
if(root == null)
return rst;
Queue<TreeNode> q = new LinkedList<TreeNode>();
q.offer(root);
int n = 1;
while(!q.isEmpty()){
List<Integer> list = new ArrayList<Integer>();
int count = 0;
for(int i=0; i<n; ++i){
TreeNode node = q.poll();
list.add(node.val);
if(node.left != null){
q.offer(node.left);
++count;
}
if(node.right != null){
q.offer(node.right);
++count;
}
}
n = count;
rst.add(list);
}
for(int i=1; i<rst.size(); i+=2){
Collections.reverse(rst.get(i));
}
return rst;
}
public double pow(double x, int n) {
if(n == 0)
return 1;
double val = pow(x, n/2);
if(n > 0)
return n/2*2 == n ? val*val : val*val*x;
else
return n/2*2 == n ? val*val : val*val/x;
}
public ListNode reverseBetween(ListNode head, int m, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode p = dummy;
ListNode q = head;
for(int i=1; i<m; ++i){
p = p.next;
q = q.next;
}
for(int i=m; i<n; ++i){
ListNode node = q.next;
q.next = q.next.next;
node.next = p.next;
p.next = node;
}
return dummy.next;
}
public List<String[]> solveNQueens(int n) {
List<String[]> rst = new ArrayList<String[]>();
cols = new boolean[n];
maindiag = new boolean[2*n];
antidiag = new boolean[2*n];
dfs(rst, new String[n], 0, n);
return rst;
}
private boolean[] cols;
private boolean[] maindiag;
private boolean[] antidiag;
public void dfs(List<String[]> rst, String[] strs, int row, int n){
if(row == n){
String[] str = new String[n];
System.arraycopy(strs, 0, str, 0, n);
rst.add(str);
return;
}
for(int i=0; i<n; ++i){
if(!cols[i] && !maindiag[row+i] && !antidiag[row-i+n-1]){
char[] chs = new char[n];
Arrays.fill(chs, '.');
chs[i] = 'Q';
cols[i] = true;
maindiag[row+i] = true;
antidiag[row-i+n-1] = true;
strs[row] = String.valueOf(chs);
dfs(rst, strs, row+1, n);
cols[i] = false;
maindiag[row+i] = false;
antidiag[row-i+n-1] = false;
}
}
}
public int maxProduct(int[] A) {
int dppos = 1;
int dpneg = 1;
int max = Integer.MIN_VALUE;
for(int i=0; i<A.length; ++i){
int poscopy = dppos;
dppos = Math.max(Math.max(A[i], dppos*A[i]), dpneg*A[i]);
dpneg = Math.min(Math.min(A[i], poscopy*A[i]), dpneg*A[i]);
max = Math.max(max, dppos);
}
return max;
}
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
if(fast == slow)
break;
}
if(fast == null || fast.next == null)
return null;
slow = head;
while(slow != fast){
slow = slow.next;
fast = fast.next;
}
return fast;
}
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
List<Integer> list = new ArrayList<Integer>();
if(numRows == 0)
return rst;
for(int i=1; i<=numRows; ++i){
for(int j=list.size()-1; j>0; --j)
list.set(j, list.get(j)+list.get(j-1));
list.add(1);
rst.add(new ArrayList<Integer>(list));
}
return rst;
}
public List<Integer> getRow(int rowIndex) {
List<Integer> list = new ArrayList<Integer>();
if(rowIndex < 0)
return list;
for(int i=0; i<=rowIndex; ++i){
for(int j=list.size()-1; j>0; --j)
list.set(j, list.get(j-1)+list.get(j));
list.add(1);
}
return list;
}
public int threeSumClosest(int[] num, int target) {
Arrays.sort(num);
int sum = 0;
int mingap = Integer.MAX_VALUE;
for(int i=0; i<num.length-2; ++i){
int left = i+1;
int right = num.length-1;
while(left < right){
int val = num[i] + num[left] + num[right];
int gap = Math.abs(val - target);
if(gap < mingap){
mingap = gap;
sum = val;
}
if(val > target)
right--;
else
left++;
}
}
return sum;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTree(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1);
}
private TreeNode buildTree(int[] pre, int pl, int pr, int[] ino, int il, int ir){
if(pl > pr)
return null;
TreeNode node = new TreeNode(pre[pl]);
int count = 0;
for(int i=il; i<=ir; ++i){
if(ino[i] == pre[pl])
break;
++count;
}
node.left = buildTree(pre, pl+1, pl+count, ino, il, il+count-1);
node.right = buildTree(pre, pl+count+1, pr, ino, il+count+1, ir);
return node;
}
public int canCompleteCircuit(int[] gas, int[] cost) {
int total = 0;
int sum = 0;
int index = 0;
for(int i=0; i<gas.length; ++i){
total += gas[i]-cost[i];
sum += gas[i]-cost[i];
if(sum < 0){
sum = 0;
index = i+1;
}
}
return total >= 0 ? index : -1;
}
public List<List<String>> partition(String s) {
List<List<String>> rst = new ArrayList<List<String>>();
if(s == null || s.length() == 0)
return rst;
partition(rst, new ArrayList<String>(), s, 0);
return rst;
}
public void partition(List<List<String>> rst, List<String> list, String s, int n){
if(n == s.length()){
rst.add(new ArrayList<String>(list));
return;
}
for(int i=n+1; i<=s.length(); ++i){
String sub = s.substring(n, i);
if(isPalindrome(sub)){
list.add(sub);
partition(rst, list, s, i);
list.remove(list.size()-1);
}
}
}
public boolean isPalindrome(String s){
int i=0;
int j=s.length()-1;
while(i<=j){
if(s.charAt(i++) != s.charAt(j--))
return false;
}
return true;
}
public String countAndSay(int n) {
String rst = new String();
if(n <= 0)
return rst;
rst = "1";
for(int i=1; i<n; ++i){
StringBuilder sb = new StringBuilder();
for(int j=0; j<rst.length(); ++j){
int count = 1;
while(j+1 < rst.length() && rst.charAt(j) == rst.charAt(j+1)){
++j;
++count;
}
sb.append(""+count);
sb.append(rst.charAt(j));
}
rst = sb.toString();
}
return rst;
}
public int minDistance(String word1, String word2) {
int[][] dp = new int[word1.length()+1][word2.length()+1];
dp[0][0] = 0;
for(int i=1; i<=word1.length(); ++i)
dp[i][0] = i;
for(int i=1; i<=word2.length(); ++i)
dp[0][i] = i;
for(int i=1; i<=word1.length(); ++i)
for(int j=1; j<=word2.length(); ++j){
int min = Math.min(dp[i-1][j], dp[i][j-1])+1;
if(word1.charAt(i-1) == word2.charAt(j-1))
dp[i][j] = Math.min(min, dp[i-1][j-1]);
else
dp[i][j] = Math.min(min, dp[i-1][j-1]+1);
}
return dp[word1.length()][word2.length()];
}
public ListNode insertionSortList(ListNode head) {
ListNode dummy = new ListNode(0);
dummy.next = null;
while(head != null){
ListNode curr = dummy;
while(curr.next != null && curr.next.val < head.val)
curr = curr.next;
ListNode temp = curr.next;
ListNode next = head.next;
curr.next = head;
head.next = temp;
head = next;
}
return dummy.next;
}
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
if(nums == null || nums.length == 0)
return rst;
Arrays.sort(nums);
boolean[] used = new boolean[nums.length];
dfs(rst, new ArrayList<Integer>(), used, nums);
return rst;
}
private void dfs(List<List<Integer>> rst, List<Integer> list, boolean[] used, int[] nums){
if(list.size() == nums.length){
rst.add(new ArrayList<Integer>(list));
return;
}
int pre = nums[0]-1;
for(int i=0; i<nums.length; ++i){
if(!used[i] && (i == 0 || nums[i] != pre)){
pre = nums[i];
used[i] = true;
list.add(pre);
dfs(rst, list, used, nums);
list.remove(list.size()-1);
used[i] = false;
}
}
}
public String addBinary(String a, String b) {
StringBuilder sb = new StringBuilder();
int carry = 0;
int ida = a.length()-1;
int idb = b.length()-1;
while(ida >=0 || idb >= 0){
if(ida < 0){
int val = carry + (b.charAt(idb--)-'0');
sb.append(val%2);
carry = val/2;
}
else if(idb < 0){
int val = carry + (a.charAt(ida--)-'0');
sb.append(val%2);
carry = val/2;
}
else{
int val = carry + (b.charAt(idb--)-'0') + (a.charAt(ida--)-'0');
sb.append(val%2);
carry = val/2;
}
}
if(carry > 0)
sb.append(carry);
return sb.reverse().toString();
}
public List<List<Integer>> combinationSum2(int[] num, int target) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
Arrays.sort(num);
comb(rst, new ArrayList<Integer>(), num, 0, target);
return rst;
}
public void comb(List<List<Integer>> rst, List<Integer> list, int[] num, int n, int target){
if(target == 0){
rst.add(new ArrayList<Integer>(list));
return;
}
if(n >= num.length || num[n] > target)
return;
int idx = n;
while(idx+1 < num.length && num[idx+1] == num[n])
++idx;
comb(rst, list, num, idx+1, target);
list.add(num[n]);
comb(rst, list, num, n+1, target-num[n]);
list.remove(list.size()-1);
}
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
if(candidates == null)
return rst;
Arrays.sort(candidates);
dfs(rst, new ArrayList<Integer>(), candidates, target, 0);
return rst;
}
private void dfs(List<List<Integer>> rst, List<Integer> list, int[] nums, int target, int k){
if(target == 0){
rst.add(new ArrayList<Integer>(list));
return;
}
for(int i=k; i<nums.length; ++i){
if(nums[i] > target)
break;
if(i==k || nums[i] != nums[i-1]){
list.add(nums[i]);
dfs(rst, list, nums, target-nums[i], i+1);
list.remove(list.size()-1);
}
}
}
public int jump(int[] A) {
int step = 0;
int max = -1;
int area = 0;
for(int i=0; i<A.length; ++i){
if(i > area){
area = max;
step++;
max = -1;
}
if(A[i]+i > max)
max = A[i] + i;
}
return step;
}
public int jump(int[] nums) {
if(nums == null || nums.length <= 1)
return 0;
int steps = 0;
int fast = 0;
int p = 0;
int q =0;
while(p <= q){
fast = Math.max(fast, p+nums[p]);
if(p == q){
q = fast;
steps++;
if(q >= nums.length-1)
break;
}
p++;
}
return q >= nums.length-1 ? steps : -1;
}
public ListNode deleteDuplicates(ListNode head) {
if(head == null || head.next == null)
return head;
if(head.val != head.next.val){
head.next = deleteDuplicates(head.next);
return head;
}
while(head.next != null && head.val == head.next.val)
head = head.next;
return deleteDuplicates(head.next);
}
public List<List<String>> groupAnagrams(String[] strs) {
Arrays.sort(strs);
Map<String, List<String>> map = new HashMap<String, List<String>>();
for(String str : strs){
String key = getKey(str);
if(!map.containsKey(key)){
map.put(key, new ArrayList<String>());
}
map.get(key).add(str);
}
List<List<String>> rst = new ArrayList<List<String>>();
for(List<String> list : map.values())
rst.add(list);
return rst;
}
private String getKey(String str){
char[] chs = str.toCharArray();
Arrays.sort(chs);
return String.valueOf(chs);
}
public boolean exist(char[][] board, String word) {
int m = board.length;
int n = board[0].length;
boolean[][] used = new boolean[m][n];
for(int i=0; i<m; ++i)
for(int j=0; j<n; ++j)
if(exist(board, used, word, "", i, j))
return true;
return false;
}
private boolean exist(char[][] board, boolean[][] used, String word, String str, int x, int y){
if(str.equals(word))
return true;
if(x<0 || x>=board.length || y<0 || y >= board[0].length ||
used[x][y] || board[x][y] != word.charAt(str.length()))
return false;
used[x][y] = true;
if(exist(board, used, word, str+board[x][y], x-1, y) ||
exist(board, used, word, str+board[x][y], x+1, y) ||
exist(board, used, word, str+board[x][y], x, y-1) ||
exist(board, used, word, str+board[x][y], x, y+1))
return true;
used[x][y] = false;
return false;
}
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null)
return null;
RandomListNode curr = head;
while(curr != null){
RandomListNode next = new RandomListNode(curr.label);
next.next = curr.next;
curr.next = next;
curr = next.next;
}
curr = head;
while(curr != null){
curr.next.random = curr.random == null ? null : curr.random.next;
curr = curr.next.next;
}
curr = head;
RandomListNode newhead = curr.next;
while(curr != null){
RandomListNode nd = curr.next;
curr.next = nd.next;
nd.next = nd.next == null ? null : nd.next.next;
curr = curr.next;
}
return newhead;
}
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
Map<Integer, UndirectedGraphNode> map = new HashMap<Integer, UndirectedGraphNode>();
return cloneNode(node, map);
}
private UndirectedGraphNode cloneNode(UndirectedGraphNode node, Map<Integer, UndirectedGraphNode> map){
if(node == null)
return null;
if(map.containsKey(node.label))
return map.get(node.label);
UndirectedGraphNode cnode = new UndirectedGraphNode(node.label);
map.put(node.label, cnode);
for(UndirectedGraphNode nb : node.neighbors)
cnode.neighbors.add(cloneNode(nb, map));
return cnode;
}
publicboolean isValidBST(TreeNode root){return isValidBST(root,Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);} publicboolean isValidBST(TreeNode p, double min, double max){if(p==null)returntrue; if(p.val<= min || p.val>= max)returnfalse; return isValidBST(p.left, min, p.val)&& isValidBST(p.right, p.val, max);}
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
int carry = 0;
while(l1 != null || l2 != null){
int val = 0;
if(l1 == null){
val = l2.val + carry;
l2 = l2.next;
}
else if(l2 == null){
val = l1.val + carry;
l1 = l1.next;
}
else{
val = l1.val + l2.val + carry;
l1 = l1.next;
l2 = l2.next;
}
curr.next = new ListNode(val % 10);
carry = val / 10;
curr = curr.next;
}
if(carry > 0)
curr.next = new ListNode(carry);
return dummy.next;
}
public int[] twoSum(int[] numbers, int target) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
int[] rst = new int[2];
for(int i=0; i<numbers.length; ++i)
map.put(numbers[i], i); // 如果有重复的话 新index会覆盖原index 这是合理的
for(int i=0; i<numbers.length; ++i)
if(map.containsKey(target-numbers[i]) && map.get(target-numbers[i]) != i){
rst[0] = i+1;
rst[1] = map.get(target-numbers[i])+1;
break;
}
return rst;
}
public boolean wordBreak(String s, Set<String> dict) {
if(s == null || s.length() == 0)
return true;
boolean[] dp = new boolean[s.length()+1];
dp[0] = true;
for(int i=1; i<=s.length(); ++i){
for(int j=0; j<i; ++j)
if(dp[j] && dict.contains(s.substring(j,i))){
dp[i] = true;
break;
}
}
return dp[s.length()];
}
public boolean wordBreak(String s, Set<String> wordDict) {
if(s == null || s.length() == 0)
return true;
boolean[] dp = new boolean[s.length()+1];
dp[0] = true;
for(int i=1; i<=s.length(); ++i){
for(int j=i-1; j>=0; --j){
String str = s.substring(j, i);
if(wordDict.contains(str) && dp[j]){
dp[i] = true;
break;
}
}
}
return dp[s.length()];
}
public List<List<Integer>> threeSum(int[] num) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
if(num.length < 3)
return rst;
Arrays.sort(num);
for(int i=0; i<num.length-2; ++i){
int left = i+1;
int right = num.length-1;
while(left < right){
if(num[i]+num[left]+num[right] < 0)
++left;
else if(num[i]+num[left]+num[right] > 0)
--right;
else{
List<Integer> list = new ArrayList<Integer>();
list.add(num[i]); list.add(num[left]); list.add(num[right]);
rst.add(list);
++left;
--right;
while(left<right && num[left] == num[left-1])
++left;
while(left<right && num[right] == num[right+1])
--right;
}
}
while(i+1 < num.length-2 && num[i] == num[i+1])
++i; // *****************************
}
return rst;
}
public int numDecodings(String s) {
if(s == null || s.length() == 0)
return 0;
int[] dp = new int[s.length()+1];
dp[0] = 1;
dp[1] = s.charAt(0)=='0' ? 0 : 1;
for(int i=2; i<=s.length(); ++i){
if(s.charAt(i-1) == '0'){
if(s.charAt(i-2) == '0' || s.charAt(i-2) > '2')
return 0;
dp[i] = dp[i-2];
}
else{
if(s.charAt(i-2) == '0' || Integer.parseInt(s.substring(i-2, i)) > 26)
dp[i] = dp[i-1];
else
dp[i] = dp[i-1] + dp[i-2];
}
}
return dp[s.length()];
}
public int ladderLength(String start, String end, Set<String> dict) {
int rst = 1;
Set<String> visited = new HashSet<String>();
Queue<String> queue = new LinkedList<String>();
int count = 0;
int num = 1;
queue.offer(start);
visited.add(start);
while(!queue.isEmpty()){
String node = queue.poll();
--num;
if(node.equals(end))
return rst;
char[] chs = node.toCharArray();
for(int i=0; i<chs.length; ++i){
char ch = chs[i];
for(int j=0; j<26; ++j){
chs[i] = (char)('a'+j);
if(chs[i] == ch) continue;
String nb = String.valueOf(chs);
if(!visited.contains(nb) && dict.contains(nb)){
queue.offer(nb);
visited.add(nb);
++count;
}
chs[i] = ch;
}
}
if(num == 0){
num = count;
count = 0;
++rst;
}
}
return 0;
}
public String convertToTitle(int n) {
String rst = "";
while(n > 0){
rst = (char)('A' + (n-1)%26) + rst;
n = (n-1)/26;
}
return rst;
}
public LRUCache(int capacity) {
map = new HashMap<Integer, Node>();
head = new Node(-1, -1);
tail = head;
for(int i=1; i<capacity; ++i){
tail.next = new Node(-1, -1);
tail.next.prev = tail;
tail = tail.next;
}
head.prev = tail;
tail.next = head;
}
public int get(int key) {
if(!map.containsKey(key))
return -1;
detach(map.get(key));
attach(map.get(key));
return map.get(key).value;
}
public void set(int key, int value) {
if(map.containsKey(key)){
map.get(key).value = value;
detach(map.get(key));
attach(map.get(key));
return;
}
Node nd = new Node(key, value);
map.put(key, nd);
attach(nd);
map.remove(tail.key);
detach(tail);
}
private void detach(Node nd){
nd.prev.next = nd.next;
nd.next.prev = nd.prev;
if(nd == tail)
tail = nd.prev;
if(nd == head)
head = nd.next;
}
private void attach(Node nd){
tail.next = nd;
nd.prev = tail;
nd.next = head;
head.prev = nd;
head = nd;
}
private Map<Integer, Node> map;
private Node head;
private Node tail;
class Node{
public int key;
public int value;
public Node prev;
public Node next;
public Node(int key, int value){
this.key = key;
this.value = value;
}
}
private ListNode list;
public TreeNode sortedListToBST(ListNode head) {
int n = 0;
ListNode curr = head;
while(curr != null){
curr = curr.next;
++n;
}
list = head;
return sortedListToBST(0, n-1);
}
private TreeNode sortedListToBST(int start, int end){
if(start > end)
return null;
int mid = start + (end-start)/2;
TreeNode left = sortedListToBST(start, mid-1);
TreeNode root = new TreeNode(list.val);
list = list.next;
root.left = left;
root.right = sortedListToBST(mid+1, end);
return root;
}
public String getPermutation(int n, int k) {
List<Integer> nums = new ArrayList<Integer>();
int fac = 1;
for(int i=1; i<=n; ++i){
nums.add(i);
fac *= i;
}
k--;
String rst = "";
for(int i=0; i<n; i++){
fac /= n-i;
int choosed = k / fac;
rst += nums.get(choosed);
nums.remove(choosed);
k = k % fac;
}
return rst;
}
public int lengthOfLongestSubstring(String s) {
int rst = 0;
Map<Character, Integer> map = new HashMap<Character, Integer>();
int left = -1;
int right = 0;
while(right < s.length()){
char ch = s.charAt(right);
if(!map.containsKey(ch) || map.get(ch) < left){
map.put(ch, right);
if(right-left > rst)
rst = right-left;
}
else{
left = map.get(ch);
map.put(ch, right);
}
++right;
}
return rst;
}
public int candy(int[] ratings) {
int[] candy = new int[ratings.length];
Arrays.fill(candy, 1);
for(int i=1; i<candy.length; ++i)
if(ratings[i] > ratings[i-1] && candy[i] <= candy[i-1])
candy[i] = candy[i-1]+1;
for(int i=candy.length-2; i>=0; --i)
if(ratings[i] > ratings[i+1] && candy[i] <= candy[i+1])
candy[i] = candy[i+1]+1;
int num = 0;
for(int i=0; i<candy.length; i++)
num += candy[i];
return num;
}
public void nextPermutation(int[] nums) {
int index = -1;
for(int i=nums.length-1; i>0; --i)
if(nums[i] > nums[i-1]){
index = i-1;
break;
}
if(index == -1){
Arrays.sort(nums);
return;
}
for(int i=nums.length-1; i>index; --i){
if(nums[i] > nums[index]){
int temp = nums[i];
nums[i] = nums[index];
nums[index] = temp;
break;
}
}
Arrays.sort(nums, index+1, nums.length);
}
public ListNode reverseKGroup(ListNode head, int k) {
if(head == null || head.next == null || k <= 1)
return head;
ListNode curr = head;
int n = 1;
while(n++ < k){
curr = curr.next;
if(curr == null)
return head;
}
curr.next = reverseKGroup(curr.next, k);
ListNode end = curr;
ListNode dummy = new ListNode(0);
dummy.next = head;
while(dummy.next != end){
ListNode temp = curr.next;
curr.next = dummy.next;
dummy.next = dummy.next.next;
curr.next.next = temp;
}
return dummy.next;
}
public int numDistinct(String S, String T) {
int[][] dp = new int[T.length()+1][S.length()+1];
for(int i=0; i<dp[0].length; ++i)
dp[0][i] = 1;
for(int i=1; i<dp.length; ++i)
for(int j=1; j<dp[i].length; ++j){
if(S.charAt(j-1) == T.charAt(i-1))
dp[i][j] = dp[i-1][j-1] + dp[i][j-1];
else
dp[i][j] = dp[i][j-1];
}
return dp[T.length()][S.length()];
}
private TreeNode first, second;
boolean find;
public void recoverTree(TreeNode root) {
first = new TreeNode(Integer.MIN_VALUE);
find = false;
recover(root);
if(first != null && second != null){
int v = first.val;
first.val = second.val;
second.val = v;
}
}
public void recover(TreeNode node){
if(node == null)
return;
recover(node.left);
if(node.val < first.val){
second = node;
find = true;
}
else if(!find){
first = node;
}
recover(node.right);
}
TreeNode first;
TreeNode second;
TreeNode iter;
public void recoverTree(TreeNode root) {
inorder(root);
if(first != null && second != null){
int temp = first.val;
first.val = second.val;
second.val = temp;
}
}
private void inorder(TreeNode node){
if(node == null)
return;
inorder(node.left);
if(iter != null && node.val < iter.val){
if(first == null){
first = iter;
}
second = node;
}
iter = node;
inorder(node.right);
}
public String reverseWords(String s) {
String[] tokens = s.trim().split(" ");
StringBuilder rst = new StringBuilder();
for(int i=tokens.length-1; i>=0; --i){
if(tokens[i] == null || tokens[i].length()==0)
continue;
rst.append(tokens[i]+" ");
}
return rst.toString().trim();
}
public int firstMissingPositive(int[] A) {
for(int i=0; i<A.length;){
if(A[i] < 1 || A[i] > A.length || A[A[i]-1] == A[i]){
++i;
continue;
}
int v = A[A[i]-1];
A[A[i]-1] = A[i];
A[i] = v;
}
for(int i=0; i<A.length; ++i){
if(A[i] != i+1)
return i+1;
}
return A.length+1;
}
public int largestRectangleArea(int[] height) {
int max = 0;
Stack<Integer> stack = new Stack<Integer>();
for(int i=0; i<height.length; ++i){
if(stack.empty() || height[i] > height[stack.peek()]){
stack.push(i);
continue;
}
while(!stack.empty() && height[i] <= height[stack.peek()]){
int ind = stack.pop();
if(stack.empty())
max = Math.max(max, height[ind] * (i-0));
else
max = Math.max(max, height[ind] * (i-stack.peek()-1));
}
stack.push(i);
}
while(!stack.empty()){
int ind = stack.pop();
if(stack.empty())
max = Math.max(max, height[ind] * height.length);
else
max = Math.max(max, height[ind] * (height.length-stack.peek()-1));
}
return max;
}
public int maxProfit(int[] prices) {
if(prices.length < 2)
return 0;
int[] left = new int[prices.length];
int[] right = new int[prices.length];
int min = prices[0];
int p = 0;
for(int i=0; i<prices.length; ++i){
if(prices[i] < min)
min = prices[i];
p = Math.max(p, prices[i]-min);
left[i] = p;
}
int max = prices[prices.length-1];
p = 0;
for(int i=prices.length-1; i>=0; --i){
if(prices[i] > max)
max = prices[i];
p = Math.max(p, max-prices[i]);
right[i] = p;
}
max = 0;
for(int i=0; i<prices.length; ++i)
max = Math.max(max, left[i] + right[i]);
return max;
}
public ListNode rotateRight(ListNode head, int n) {
if(head == null)
return head;
int num = 1;
ListNode curr = head;
while(curr.next != null){
curr = curr.next;
++num;
}
curr.next = head;
for(int i=0; i<num-n%num; ++i)
curr = curr.next;
head = curr.next;
curr.next = null;
return head;
}
public String simplifyPath(String path) {
Stack<String> stack = new Stack<String>();
String[] tokens = path.split("/");
for(int i=0; i<tokens.length; ++i){
if(tokens[i].equals(".") || tokens[i].equals(""))
continue;
if(tokens[i].equals("..")){
if(!stack.empty()) stack.pop();
}
else
stack.push(tokens[i]);
}
StringBuilder sb = new StringBuilder();
while(!stack.empty())
sb.insert(0, "/"+stack.pop());
return sb.length()==0 ? "/" : sb.toString();
}
public List<List<Integer>> fourSum(int[] num, int target) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
if(num.length < 4)
return rst;
Arrays.sort(num);
for(int i=0; i<num.length-3; ++i){
if(i>0 && num[i] == num[i-1])
continue;
for(int j=i+1; j<num.length-2; ++j){
if(j>i+1 && num[j] == num[j-1])
continue;
int left = j+1;
int right = num.length-1;
while(left < right){
if(num[i] + num[j] + num[left] + num[right] == target){
List<Integer> list = new ArrayList<Integer>();
list.add(num[i]); list.add(num[j]);
list.add(num[left]); list.add(num[right]);
rst.add(list);
++left;
while(left < right && num[left] == num[left-1])
++left;
--right;
while(left < right && num[right] == num[right+1])
--right;
}
else if(num[i] + num[j] + num[left] + num[right] < target){
++left;
//while(left < right && num[left] == num[left-1])
// ++left;
}
else{
--right;
//while(left < right && num[right] == num[right+1])
// --right;
}
}
}
}
return rst;
}
public void solveSudoku(char[][] board) {
dfs(board);
}
private boolean dfs(char[][] board){
for(int i=0; i<9; ++i)
for(int j=0; j<9; ++j){
if(board[i][j] != '.')
continue;
for(int x=1; x<10; ++x){
if(isValid(board, i, j, x)){
board[i][j] = (char)('0'+x);
if(dfs(board))
return true;
board[i][j] = '.';
}
}
return false;
}
return true;
}
private boolean isValid(char[][] board, int x, int y, int v){
for(int i=0; i<9; ++i)
if(i!=x && board[i][y]-'0' == v || i!=y && board[x][i]-'0' == v)
return false;
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j){
int row = x/3*3+i;
int col = y/3*3+j;
if(row != x && col != y && board[row][col]-'0' == v)
return false;
}
return true;
}
public String longestPalindrome(String s) {
if(s == null || s.length()==0)
return s;
boolean[][] p = new boolean[s.length()][s.length()];
int maxLen = 1;
int start = 0;
for(int i=0; i<s.length(); ++i){
p[i][i] = true;
for(int j=i-1; j>=0; --j){
p[j][i] = (s.charAt(i)==s.charAt(j)) && (j+1 == i || p[j+1][i-1]);
if(p[j][i] && i-j+1 > maxLen){
maxLen = i-j+1;
start = j;
}
}
}
return s.substring(start, start+maxLen);
}
public ListNode mergeKLists(List<ListNode> lists) {
if(lists == null || lists.size() == 0)
return null;
if(lists.size() == 1)
return lists.get(0);
int mid = lists.size()/2;
List<ListNode> half = new ArrayList<ListNode>();
while(mid-- > 0){
half.add(lists.get(0));
lists.remove(0);
}
ListNode left = mergeKLists(lists);
ListNode right = mergeKLists(half);
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while(left != null && right != null){
if(left.val < right.val){
curr.next = left;
left = left.next;
}
else{
curr.next = right;
right = right.next;
}
curr = curr.next;
}
while(left != null){
curr.next = left;
curr = curr.next;
left = left.next;
}
while(right != null){
curr.next = right;
curr = curr.next;
right = right.next;
}
return dummy.next;
}
public int longestValidParentheses(String s) {
if(s == null || s.length() <= 1)
return 0;
int[] dp = new int[s.length()];
int len = 0;
for(int i=1; i<s.length(); ++i){
if(s.charAt(i) == '(')
continue;
if(s.charAt(i-1) == '('){
dp[i] = i-2 >= 0 ? dp[i-2]+2 : 2;
}
else{
int v = dp[i-1];
if(i-1-v >= 0 && s.charAt(i-1-v) == '('){
dp[i] = i-2-v >= 0 ? v+2+dp[i-2-v] : v+2; // ()(())
}
}
len = Math.max(len, dp[i]);
}
return len;
}
public int maxPathSum(TreeNode root) {
max = Integer.MIN_VALUE;
dfs(root);
return max;
}
private int max;
private int dfs(TreeNode node){
if(node == null)
return 0;
int left = dfs(node.left);
int right = dfs(node.right);
int v = node.val;
if(left > 0)
v += left;
if(right > 0)
v += right;
max = Math.max(v, max);
if(left < 0 && right < 0)
return node.val;
return left>right ? left+node.val : right+node.val;
}
public void reorderList(ListNode head) {
if(head == null || head.next == null || head.next.next == null)
return;
ListNode fast = head;
ListNode slow = head;
while(fast.next != null && fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
ListNode mid = slow.next;
slow.next = null;
if(fast.next != null) fast = fast.next;
while(mid != fast){
slow = fast.next;
fast.next = mid;
mid = mid.next;
fast.next.next = slow;
}
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while(head != null || mid != null){
if(head != null){
curr.next = head;
head = head.next;
curr = curr.next;
}
if(mid != null){
curr.next = mid;
mid = mid.next;
curr = curr.next;
}
}
head = dummy.next;
}
private List<Integer> stack = new ArrayList<Integer>();
private List<Integer> minStack = new ArrayList<Integer>();
public void push(int x) {
stack.add(x);
if(minStack.isEmpty() || x <= minStack.get(minStack.size()-1))
minStack.add(x);
}
public void pop() {
if(stack.isEmpty())
return;
if(stack.get(stack.size()-1).equals(minStack.get(minStack.size()-1)))
minStack.remove(minStack.size()-1);
stack.remove(stack.size()-1);
}
public int top() {
if(stack.isEmpty())
return 0;
return stack.get(stack.size()-1);
}
public int getMin() {
if(minStack.isEmpty())
return 0;
return minStack.get(minStack.size()-1);
}
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<Integer>();
for(String str : tokens){
if(str.equals("+")){
int y = stack.pop();
int x = stack.pop();
stack.push(x+y);
}
else if(str.equals("*")){
int y = stack.pop();
int x = stack.pop();
stack.push(x*y);
}
else if(str.equals("/")){
int y = stack.pop();
int x = stack.pop();
stack.push(x/y);
}
else if(str.equals("-")){
int y = stack.pop();
int x = stack.pop();
stack.push(x-y);
}
else{
stack.push(Integer.parseInt(str));
}
}
return stack.peek();
}
public int minCut(String s) {
if(s == null || s.length() < 2)
return 0;
boolean[][] p = new boolean[s.length()][s.length()];
int[] dp = new int[s.length()];
p[0][0] = true;
for(int i=1; i<s.length(); ++i){
p[i][i] = true;
int minc = dp[i-1]+1;
for(int j=i-1; j>=0; --j){
if((j == i-1 || p[j+1][i-1] )&& s.charAt(i)==s.charAt(j)){
p[j][i] = true;
int cut = j == 0 ? 0 : dp[j-1]+1;
minc = Math.min(minc, cut);
}
}
dp[i] = minc;
}
return dp[s.length()-1];
}
public boolean isMatch(String s, String p) {
return isMatch(s, 0, p, 0);
}
private boolean isMatch(String s, int sl, String p, int pl){
if(pl == p.length())
return sl == s.length();
if(pl == p.length()-1 || p.charAt(pl+1) != '*'){
if(sl == s.length())
return false;
return (s.charAt(sl)==p.charAt(pl) || p.charAt(pl)=='.') ? isMatch(s, sl+1, p, pl+1) : false;
}
else{
for(int i=sl; i<s.length(); ++i){
if(s.charAt(i)!=p.charAt(pl) && p.charAt(pl)!='.')
break;
if(isMatch(s, i+1, p, pl+2))
return true;
}
return isMatch(s, sl, p, pl+2);
}
}
public void solve(char[][] board) {
if(board == null || board.length==0)
return;
Stack<Integer> stackr = new Stack<Integer>();
Stack<Integer> stackc = new Stack<Integer>();
for(int i=0; i<board.length; ++i){
stackr.push(i);
stackc.push(0);
stackr.push(i);
stackc.push(board[0].length-1);
}
for(int i=0; i<board[0].length; ++i){
stackr.push(0);
stackc.push(i);
stackr.push(board.length-1);
stackc.push(i);
}
while(!stackr.isEmpty()){
int r = stackr.pop();
int c = stackc.pop();
if(r<0 || r>=board.length || c<0 || c>=board[0].length || board[r][c] != 'O')
continue;
board[r][c] = 'Y';
stackr.push(r+1); stackc.push(c);
stackr.push(r); stackc.push(c+1);
stackr.push(r-1); stackc.push(c);
stackr.push(r); stackc.push(c-1);
}
for(int i=0; i<board.length; ++i)
for(int j=0; j<board[0].length; ++j)
if(board[i][j] == 'O')
board[i][j] = 'X';
else if(board[i][j] == 'Y')
board[i][j] = 'O';
}
public boolean isMatch(String s, String p) {
if(p == null)
return s == null;
int i = 0;
int j = 0;
int star = -1;
int mark = -1;
while(i < s.length()){
if(j < p.length() && p.charAt(j) == '*'){
star = j++;
mark = i;
}
else if(j < p.length() && (p.charAt(j) == '?' || p.charAt(j) == s.charAt(i))){
++i;
++j;
}
else if(star != -1){
j = star + 1;
i = ++mark;
}
else
return false;
}
while(j < p.length() && p.charAt(j)=='*')
++j;
return j == p.length();
}
public int maxPoints(Point[] points) {
int max = 0;
for(int i=0; i<points.length; ++i){
Map<Double, Integer> map = new HashMap<Double,Integer>();
int infinity = 1;
int same = 0;
int count = 1;
for(int j=i+1; j<points.length; ++j){
if(points[i].x == points[j].x && points[i].y == points[j].y){
++same;
}
else if(points[i].x == points[j].x){
++infinity;
count = Math.max(count, infinity);
}
//java里面Object wrapper的Double类型比较0.0和-0.0是按照位比较,
//符号位的不同在比较时也会被考虑,所以记得把-0.0转换成0.0存储。(但是普通double类型就不会这 样。。。。)
else if(points[i].y == points[j].y){
if(map.containsKey(0.0))
map.put(0.0, map.get(0.0)+1);
else
map.put(0.0, 2);
count = Math.max(count, map.get(0.0));
}
else{
double key = (double)(points[i].y-points[j].y)/(points[i].x-points[j].x);
if(map.containsKey(key))
map.put(key, map.get(key)+1);
else
map.put(key, 2);
count = Math.max(count, map.get(key));
}
}
count += same;
max = Math.max(max, count);
}
return max;
}
public int maximalRectangle(char[][] matrix) {
if(matrix == null || matrix.length == 0)
return 0;
int[][] arr = new int[matrix.length][matrix[0].length];
for(int i=0; i<arr.length; ++i){
arr[i][0] = Integer.parseInt(String.valueOf(matrix[i][0])); parseInt 需要String
for(int j=1; j<arr[0].length; ++j){
arr[i][j] = matrix[i][j] == '1' ? 1+arr[i][j-1] : 0;
}
}
int max = 0;
for(int i=0; i<arr.length; ++i){
for(int j=0; j<arr[0].length; ++j){
int w = arr[i][j];
for(int h=i; h>=0; --h){
if(arr[h][j] < w)
w = arr[h][j];
max = Math.max(max,w*(i-h+1));
}
}
}
return max;
}
public int maximalRectangle(char[][] matrix) {
if(matrix == null)
return 0;
if(matrix.length == 0 || matrix[0].length == 0)
return 0;
int r = matrix.length;
int c = matrix[0].length;
int[] height = new int[c];
int area = 0;
for(int i=0; i<r; ++i){
for(int j=0; j<c; ++j){
height[j] = matrix[i][j] == '1' ? height[j]+1 : 0;
}
area = Math.max(area, largestRectangleArea(height));
}
return area;
}
public int largestRectangleArea(int[] height) {
int max = 0;
Stack<Integer> stack = new Stack<Integer>();
for(int i=0; i<height.length; ++i){
if(stack.empty() || height[i] > height[stack.peek()]){
stack.push(i);
continue;
}
while(!stack.empty() && height[i] <= height[stack.peek()]){
int ind = stack.pop();
if(stack.empty())
max = Math.max(max, height[ind] * (i-0));
else
max = Math.max(max, height[ind] * (i-stack.peek()-1));
}
stack.push(i);
}
while(!stack.empty()){
int ind = stack.pop();
if(stack.empty())
max = Math.max(max, height[ind] * height.length);
else
max = Math.max(max, height[ind] * (height.length-stack.peek()-1));
}
return max;
}
public String multiply(String num1, String num2) {
StringBuilder sb1 = new StringBuilder(num1);
StringBuilder sb2 = new StringBuilder(num2);
sb1.reverse();
sb2.reverse();
int[] num = new int[num1.length()+num2.length()];
for(int i=0; i<sb1.length(); ++i)
for(int j=0; j<sb2.length(); ++j){
num[i+j] += (sb1.charAt(i)-'0')*(sb2.charAt(j)-'0');
}
for(int i=0; i<num.length-1; ++i){
num[i+1] += num[i]/10;
num[i] = num[i]%10;
}
String rst = "";
int i=num.length-1;
while(i>=0 && num[i] == 0)
i--;
while(i >=0){
rst += num[i--];
}
return rst.equals("") ? "0" : rst;
}
public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
List<Interval> rst = new ArrayList<Interval>();
boolean done = false;
for(Interval curr : intervals){
if(done){
rst.add(curr);
}
else if(newInterval.end < curr.start){
rst.add(newInterval);
rst.add(curr);
done = true;
}
else if(newInterval.start > curr.end){
rst.add(curr);
}
else{
newInterval.start = Math.min(newInterval.start, curr.start);
newInterval.end = Math.max(newInterval.end, curr.end);
}
}
if(!done)
rst.add(newInterval);
return rst;
}
public int trailingZeroes(int n) {
int num = 0;
while(n >= 5){
num += n/5;
n /= 5;
}
return num;
}
public int maximumGap(int[] nums) {
if(nums.length <= 1)
return 0;
Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
for(int x : nums){
int key = x%10;
if(!map.containsKey(key))
map.put(key, new ArrayList<Integer>());
map.get(key).add(x);
}
int d = 10;
for(int i=0; i<9; ++i){
Map<Integer, List<Integer>> nmap = new HashMap<Integer, List<Integer>>();
for(List<Integer> list : map.values()){
for(int x : list){
int key = (x/d)%10;
if(!nmap.containsKey(key))
nmap.put(key, new ArrayList<Integer>());
nmap.get(key).add(x);
}
}
map = nmap;
d *= 10;
}
int gap = 0;
int pre = -1;
for(int j=0; j<10; ++j){
List<Integer> list = map.get(j);
if(list == null)
continue;
for(int x : list){
if(pre == -1){
pre = x;
continue;
}
gap = Math.max(gap, x - pre);
pre = x;
}
}
return gap;
}
public int compareVersion(String version1, String version2) {
String[] v1 = version1.split("[.]");
String[] v2 = version2.split("[.]");
int len = Math.max(v1.length, v2.length);
for(int i=0; i<len; ++i){
if(i >= v1.length){
if(Integer.parseInt(v2[i]) != 0)
return -1;
continue;
}
if(i >= v2.length){
if(Integer.parseInt(v1[i]) != 0)
return 1;
continue;
}
if(Integer.parseInt(v1[i]) > Integer.parseInt(v2[i]))
return 1;
if(Integer.parseInt(v1[i]) < Integer.parseInt(v2[i]))
return -1;
}
return 0;
}
public int titleToNumber(String s) {
if(s == null || s.length() == 0)
return 0;
int rst = 0
for(int i=0; i<s.length(); ++i){
char ch = s.charAt(i);
rst = rst*26 + (ch-'A'+1);
}
return rst;
}
public class BSTIterator {
private Stack<TreeNode> stack;
private TreeNode p;
public BSTIterator(TreeNode root) {
p = root;
stack = new Stack<TreeNode>();
while(p != null){
stack.push(p);
p = p.left;
}
}
/** @return whether we have a next smallest number */
public boolean hasNext() {
return !stack.isEmpty();
}
/** @return the next smallest number */
public int next() {
TreeNode next = stack.pop();
p = next.right;
while(p != null){
stack.push(p);
p = p.left;
}
return next.val;
}
}
public int calculateMinimumHP(int[][] dungeon) {
if(dungeon == null || dungeon.length == 0 || dungeon[0].length == 0)
return 0;
int r = dungeon.length;
int c = dungeon[0].length;
int[][] dp = new int[r][c];
dp[r-1][c-1] = Math.max(-dungeon[r-1][c-1]+1, 1);
for(int i=r-2; i>=0; --i){
dp[i][c-1] = Math.max(1, dp[i+1][c-1] - dungeon[i][c-1]);
}
for(int i=c-2; i>=0; --i){
dp[r-1][i] = Math.max(1, dp[r-1][i+1] - dungeon[r-1][i]);
}
for(int i=r-2; i>=0; --i){
for(int j=c-2; j>=0; --j){
dp[i][j] = Math.max(1, Math.min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j]);
}
}
return dp[0][0];
}
public String largestNumber(int[] nums) {
String[] strs = new String[nums.length];
for(int i=0; i<nums.length; ++i)
strs[i] = "" + nums[i];
Arrays.sort(strs, new Comp());
String rst = "";
for(int i=strs.length-1; i>=0; --i)
rst += strs[i];
return rst.charAt(0) == '0' ? "0" : rst;
}
public static class Comp implements Comparator<String>{
public int compare(String a, String b){
String ab = a + b;
String ba = b + a;
return ab.compareTo(ba);
}
}
public String largestNumber(int[] nums) {
Integer[] A = new Integer[nums.length];
for(int i=0; i<nums.length; ++i)
A[i] = nums[i];
Arrays.sort(A, new Comp());
String rst = "";
for(int x : A)
rst = x + rst;
return rst.charAt(0) == '0' ? "0" : rst;
}
public static class Comp implements Comparator<Integer>{
public int compare(Integer a, Integer b){
String sa = String.valueOf(a);
String sb = String.valueOf(b);
return (sa+sb).compareTo(sb+sa);
}
}
public List<String> findRepeatedDnaSequences(String s) {
List<String> list = new ArrayList<String>();
if(s == null || s.length() <= 10)
return list;
Map<String, Integer> map = new HashMap<String, Integer>();
for(int i=0; i<s.length()-9; ++i){
String seq = s.substring(i, i+10);
if(!map.containsKey(seq)){
map.put(seq, 1);
continue;
}
if(map.get(seq) == 1){
list.add(seq);
map.put(seq, 2);
}
}
return list;
}
public List<Integer> rightSideView(TreeNode root) {
List<Integer> rst = new ArrayList<Integer>();
if(root == null)
return rst;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
int num = 1;
while(!queue.isEmpty()){
int count = 0;
rst.add(queue.peek().val);
for(int i=0; i<num; ++i){
TreeNode node = queue.poll();
if(node.right != null){
queue.offer(node.right);
++count;
}
if(node.left != null){
queue.offer(node.left);
++count;
}
}
num = count;
}
return rst;
}
public int numIslands(char[][] grid) {
if(grid == null || grid.length == 0 || grid[0].length == 0)
return 0;
int count = 1;
for(int i=0; i<grid.length; ++i)
for(int j=0; j<grid[0].length; ++j)
if(grid[i][j] == '1')
color(grid, i, j, ++count);
return count-1;
}
private void color(char[][] grid, int r, int c, int cl){
if(r < 0 || r >= grid.length)
return;
if(c < 0 || c >= grid[0].length)
return;
if(grid[r][c] != '1')
return;
grid[r][c] = (char)(cl+'0');
color(grid, r-1, c, cl);
color(grid, r+1, c, cl);
color(grid, r, c-1, cl);
color(grid, r, c+1, cl);
}
public int rangeBitwiseAnd(int m, int n) {
int rst = 0;
int d = 0;
while(m > 0){
if(n == m)
rst += (m&1)<<d;
m >>= 1;
n >>= 1;
++d;
}
return rst;
}
public boolean canFinish(int numCourses, int[][] prerequisites) {
Map<Integer, List<Integer>> nodes = new HashMap<Integer, List<Integer>>();
for(int i=0; i<numCourses; ++i)
nodes.put(i, new ArrayList<Integer>());
for(int i=0; i<prerequisites.length; ++i)
nodes.get(prerequisites[i][0]).add(prerequisites[i][1]);
Set<Integer> visited = new HashSet<Integer>();
Set<Integer> valid = new HashSet<Integer>();
for(int i=0; i<numCourses; ++i){
visited.add(i);
if(!check(i, visited, valid, nodes))
return false;
valid.add(i);
visited.remove(i);
}
return true;
}
private boolean check(int id, Set<Integer> visited, Set<Integer> valid, Map<Integer, List<Integer>> nodes){
if(valid.contains(id))
return true;
for(int next : nodes.get(id)){
if(visited.contains(next))
return false;
visited.add(next);
if(!check(next, visited, valid, nodes))
return false;
valid.add(next);
visited.remove(next);
}
return true;
}
public int minSubArrayLen(int s, int[] nums) {
if(nums.length == 0)
return 0;
int len = 0;
int left = 0;
int right = 0;
int sum = nums[0];
while(right < nums.length){
if(sum >= s){
len = len == 0 ? right-left+1 : Math.min(len, right-left+1);
sum -= nums[left++];
continue;
}
if(right < nums.length-1)
sum += nums[++right];
else
break;
}
return len;
}
public int rob(int[] nums) {
if(nums.length == 0)
return 0;
int[] dp = new int[nums.length+1];
dp[1] = nums[0];
for(int i=2; i<dp.length; ++i){
dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i-1]);
}
return dp[nums.length];
}
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> q = new PriorityQueue<Integer>();
for(int x : nums){
if(q.size() < k){
q.offer(x);
continue;
}
if(x > q.peek()){
q.poll();
q.offer(x);
}
}
return q.peek();
}
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
if(k <= 0 || n <= 0)
return rst;
Set<Integer> set = new HashSet<Integer>();
dfs(rst, new ArrayList<Integer>(), set, 1, k, n);
return rst;
}
<pre name="code" class="java">private void dfs(List<List<Integer>> rst, List<Integer> list, Set<Integer> set, int s, int k, int n){
if(k == 0 && n == 0){
rst.add(new ArrayList<Integer>(list));
return;
}
if(k == 0 || n <= 0)
return;
for(int i=s; i<=9; ++i){
if(!set.contains(i)){
list.add(i);
set.add(i);
dfs(rst, list, set, i+1, k-1, n-i);
set.remove(i);
list.remove(list.size()-1);
}
}
}
public boolean containsNearbyDuplicate(int[] nums, int k) {
if(nums == null || nums.length < 2)
return false;
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i=0; i<nums.length; ++i){
if(map.containsKey(nums[i]) && i-map.get(nums[i]) <= k)
return true;
map.put(nums[i], i);
}
return false;
}
public boolean isAnagram(String s, String t) {
char[] sch = s.toCharArray();
char[] tch = t.toCharArray();
Arrays.sort(sch);
Arrays.sort(tch);
String ns = String.valueOf(sch);
String nt = String.valueOf(tch);
return ns.equals(nt);
}
int rst;
public int kthSmallest(TreeNode root, int k) {
inorder(root, k);
return rst;
}
private int inorder(TreeNode root, int k){
if(root == null)
return 0;
int num = inorder(root.left, k);
if(num >= k)
return k+1;
num++;
if(num == k){
rst = root.val;
return num;
}
return num + inorder(root.right, k-num);
}
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?
- Try to utilize the property of a BST.
- What if you could modify the BST node's structure?
- The optimal runtime complexity is O(height of BST).
public int rob(int[] nums) {
if(nums == null || nums.length == 0)
return 0;
if(nums.length == 1)
return nums[0];
if(nums.length == 2)
return Math.max(nums[0], nums[1]);
int[] dp = new int[nums.length];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for(int i=2; i<nums.length-1; ++i)
dp[i] = Math.max(dp[i-1], nums[i] + dp[i-2]);
int rst = dp[nums.length-2];
if(nums.length == 3)
return Math.max(rst, nums[2]);
dp[1] = nums[1];
dp[2] = Math.max(nums[1], nums[2]);
for(int i=3; i<nums.length; ++i)
dp[i] = Math.max(dp[i-1], nums[i] + dp[i-2]);
return Math.max(rst, dp[nums.length-1]);
}
public String fractionToDecimal(int numerator, int denominator) {
if (numerator == 0) return "0";
if (denominator == 0) return "";
String ans = "";
//如果结果为负数
if ((numerator < 0) ^ (denominator < 0)) {
ans += "-";
}
//下面要把两个数都转为正数,为避免溢出,int转为long
long num = numerator, den = denominator;
num = Math.abs(num);
den = Math.abs(den);
//结果的整数部分
long res = num / den;
ans += String.valueOf(res);
//如果能够整除,返回结果
long rem = (num % den) * 10;
if (rem == 0) return ans;
//结果的小数部分
HashMap<Long, Integer> map = new HashMap<Long, Integer>();
ans += ".";
while (rem != 0) {
//如果前面已经出现过该余数,那么将会开始循环
if (map.containsKey(rem)) {
int beg = map.get(rem); //循环体开始的位置
String part1 = ans.substring(0, beg);
String part2 = ans.substring(beg, ans.length());
ans = part1 + "(" + part2 + ")";
return ans;
}
//继续往下除
map.put(rem, ans.length());
res = rem / den;
ans += String.valueOf(res);
rem = (rem % den) * 10;
}
return ans;
}
public List<Integer> majorityElement(int[] nums) {
List<Integer> rst = new ArrayList<Integer>();
if(nums == null || nums.length == 0)
return rst;
if(nums.length < 2){
rst.add(nums[0]);
return rst;
}
int a = nums[0];
int b = 0;
int ac = 1;
int bc = 0;
for(int i=1; i<nums.length; ++i){
if(nums[i] == a){
ac++;
}
else if(nums[i] == b){
bc++;
}
else if(ac == 0){
ac = 1;
a = nums[i];
}
else if(bc == 0){
bc = 1;
b = nums[i];
}
else{
bc--;
ac--;
}
}
// 最多两个 但不保证有两个
ac = 0;
bc = 0;
for(int i=0; i<nums.length; ++i){
if(nums[i] == a)
ac++;
else if(nums[i] == b)
bc++;
}
if(ac > nums.length/3)
rst.add(a);
if(bc > nums.length/3)
rst.add(b);
return rst;
}
public int reverseBits(int n) {
int rst = 0;
for(int i=0; i<32; ++i){
rst += (n >> i & 1) << 31-i;
}
return rst;
}
public boolean isHappy(int n) {
Set<Integer> set = new HashSet<Integer>();
while(n != 1){
if(set.contains(n))
return false;
set.add(n);
int m = 0;
while(n > 0){
int d = n%10;
m += d*d;
n /= 10;
}
n = m;
}
return true;
}
public ListNode reverseList(ListNode head) {
ListNode dummy = new ListNode(0);
dummy.next = head;
while(head != null && head.next != null){
ListNode node = head.next;
head.next = node.next;
node.next = dummy.next;
dummy.next = node;
}
return dummy.next;
}
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode left = head;
ListNode right = head;
while(right.next != null){
ListNode node = right.next;
right.next = right.next.next;
node.next = left;
left = node;
}
return left;
}
public int hammingWeight(int n) {
int count = 0;
for(int i=0; i<32; ++i){
count += n >> i & 1;
}
return count;
}
public int maxProfit(int k, int[] prices) {
if(prices.length <= 1 || k <= 0)
return 0;
// if (k == 1000000000)
// return 1648961;
int[][] local = new int[prices.length][k+1];
int[][] global = new int[prices.length][k+1];
for(int j=1; j<=k; ++j)
for(int i=1; i<prices.length; ++i){
int diff = prices[i] - prices[i-1];
local[i][j] = Math.max(global[i-1][j-1] + Math.max(diff, 0), local[i-1][j] + diff);
global[i][j] = Math.max(global[i-1][j], local[i][j]);
}
return global[prices.length-1][k];
}
public void rotate(int[] nums, int k) {
k %= nums.length;
if(k <= 0)
return;
int left = 0;
int right = nums.length-k-1;
while(left < right){
swap(nums, left++, right--);
}
left = nums.length-k;
right = nums.length-1;
while(left < right){
swap(nums, left++, right--);
}
left = 0;
right = nums.length-1;
while(left < right){
swap(nums, left++, right--);
}
}
private void swap(int[] nums, int i, int j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public ListNode removeElements(ListNode head, int val) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode curr = dummy;
while(curr.next != null){
if(curr.next.val == val)
curr.next = curr.next.next;
else
curr = curr.next;
}
return dummy.next;
}
public int countPrimes(int n) {
boolean[] isPrime = new boolean[n];
for (int i = 2; i < n; i++)
isPrime[i] = true;
for(int i=2; i*i<n; ++i){
if(!isPrime[i])
continue;
for(int j=i*i; j<n; j+=i)
isPrime[j] = false;
}
int count = 0;
for(int i=2; i<n; ++i)
if(isPrime[i])
++count;
return count;
}
public int countPrimes(int n) {
List<Integer> primes = new ArrayList<Integer>();
for(int i=2; i<n; ++i){
boolean isprime = true;
for(int x : primes){
if(x*x > i)
break;
if(i%x == 0){
isprime = false;
break;
}
}
if(isprime){
primes.add(i);
}
}
return primes.size();
}
public boolean isIsomorphic(String s, String t) {
if(s.length() != t.length())
return false;
Map<Character, Character> map = new HashMap<Character, Character>();
for(int i=0; i<s.length(); ++i){
char key = s.charAt(i);
char val = t.charAt(i);
if(map.containsKey(key)){
if(map.get(key) != val)
return false;
}
else{
if(map.containsValue(val))
return false;
map.put(key, val);
}
}
return true;
}
class TrieNode {
// Initialize your data structure here.
public boolean isLeaf;
public Map<Character, TrieNode> children;
public TrieNode() {
children = new HashMap<Character, TrieNode> ();
}
}
public class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
// Inserts a word into the trie.
public void insert(String word) {
if(word == null || word.length() == 0)
return;
TrieNode node = root;
for(int i=0; i<word.length(); ++i){
char ch = word.charAt(i);
if(node.children.get(ch) == null)
node.children.put(ch, new TrieNode());
node = node.children.get(ch);
}
node.isLeaf = true;
}
// Returns if the word is in the trie.
public boolean search(String word) {
TrieNode node = searchNode(word);
if(node == null || !node.isLeaf)
return false;
return true;
}
// Returns if there is any word in the trie
// that starts with the given prefix.
public boolean startsWith(String prefix) {
TrieNode node = searchNode(prefix);
return node != null;
}
private TrieNode searchNode(String str){
if(str == null || str.length() == 0)
return null;
TrieNode node = root;
for(int i=0; i<str.length(); ++i){
if(node.children.get(str.charAt(i)) == null)
return null;
node = node.children.get(str.charAt(i));
}
return node;
}
}
public int[] findOrder(int numCourses, int[][] prerequisites) {
Map<Integer, Set<Integer>> map = new HashMap<Integer, Set<Integer>>();
Map<Integer, Set<Integer>> connect = new HashMap<Integer, Set<Integer>>();
for(int i=0; i<numCourses; ++i){
map.put(i, new HashSet<Integer>());
connect.put(i, new HashSet<Integer>());
}
for(int i=0; i<prerequisites.length; ++i){
map.get(prerequisites[i][0]).add(prerequisites[i][1]);
connect.get(prerequisites[i][1]).add(prerequisites[i][0]);
}
Queue<Integer> q = new LinkedList<Integer>();
for(int i=0; i<numCourses; ++i)
if(map.get(i).isEmpty())
q.offer(i);
int[] rst = new int[numCourses];
int count = 0;
while(!q.isEmpty()){
int course = q.poll();
rst[count++] = course;
for(int x : connect.get(course)){
map.get(x).remove(course);
if(map.get(x).isEmpty())
q.offer(x);
}
}
if(count < numCourses-1)
return new int[0];
return rst;
}
public class WordDictionary {
private class Node{
public boolean isleaf;
public Map<Character, Node> children;
public Node(){
children = new HashMap<Character, Node>();
}
}
private Node root = new Node();
// Adds a word into the data structure.
public void addWord(String word) {
if(word == null || word.length() == 0)
return;
Node node = root;
for(int i=0; i<word.length(); ++i){
char ch = word.charAt(i);
if(node.children.get(ch) == null)
node.children.put(ch, new Node());
node = node.children.get(ch);
}
node.isleaf = true;
}
// Returns if the word is in the data structure. A word could
// contain the dot character '.' to represent any one letter.
public boolean search(String word) {
if(word == null || word.length() == 0)
return false;
return search(root, word, 0);
}
private boolean search(Node node, String word, int k){
if(k == word.length()){
return node != null && node.isleaf;
}
char ch = word.charAt(k);
if(ch != '.'){
if(node.children.get(ch) == null)
return false;
return search(node.children.get(ch), word, k+1);
}
else{
for(Node child : node.children.values()){
if(search(child, word, k+1))
return true;
}
return false;
}
}
}
public boolean containsDuplicate(int[] nums) {
if(nums == null || nums.length <= 1)
return false;
Set<Integer> set = new HashSet<Integer>();
for(int x : nums){
if(set.contains(x))
return true;
set.add(x);
}
return false;
}
public List<Integer> diffWaysToCompute(String input) {
List<Integer> rst = new ArrayList<Integer>();
if(input == null || input.length() == 0)
return rst;
boolean op = false;
for(int i=1; i<input.length(); ++i){
char ch = input.charAt(i);
if(ch == '-'){
List<Integer> left = diffWaysToCompute(input.substring(0, i));
List<Integer> right = diffWaysToCompute(input.substring(i+1, input.length()));
for(int x : left)
for(int y : right)
rst.add(x - y);
op = true;
}
else if(ch == '+'){
List<Integer> left = diffWaysToCompute(input.substring(0, i));
List<Integer> right = diffWaysToCompute(input.substring(i+1, input.length()));
for(int x : left)
for(int y : right)
rst.add(x + y);
op = true;
}
else if(ch == '*'){
List<Integer> left = diffWaysToCompute(input.substring(0, i));
List<Integer> right = diffWaysToCompute(input.substring(i+1, input.length()));
for(int x : left)
for(int y : right)
rst.add(x * y);
op = true;
}
}
if(!op){
rst.add(Integer.parseInt(input));
}
return rst;
}
public int maximalSquare(char[][] matrix) {
if(matrix == null)
throw new IllegalArgumentException();
if(matrix.length == 0 || matrix[0].length == 0)
return 0;
int m = matrix.length;
int n = matrix[0].length;
int[][] dp = new int[m][n];
int max = 0;
for(int i=0; i<m; ++i){
dp[i][0] = matrix[i][0] - '0';
max = Math.max(max, dp[i][0]);
}
for(int i=0; i<n; ++i){
dp[0][i] = matrix[0][i] - '0';
max = Math.max(max, dp[0][i]);
}
for(int i=1; i<m; ++i)
for(int j=1; j<n; ++j){
if(matrix[i][j] == '1'){
dp[i][j] = Math.min(dp[i-1][j], Math.min(dp[i-1][j-1], dp[i][j-1])) + 1;
max = Math.max(max, dp[i][j]);
}
}
return max*max;
}
public List<Interval> merge(List<Interval> intervals) {
Collections.sort(intervals, new Comp());
List<Interval> rst = new ArrayList<Interval>();
if(intervals == null || intervals.size() == 0)
return intervals;
Interval inter = null;
for(Interval it : intervals){
if(inter == null){
inter = it;
continue;
}
if(inter.end >= it.start){
inter.end = Math.max(inter.end, it.end);
continue;
}
rst.add(inter);
inter = it;
}
rst.add(inter);
return rst;
}
private static class Comp implements Comparator<Interval>{
public int compare(Interval inter1, Interval inter2){
return inter1.start - inter2.start;
}
}
public List<String> binaryTreePaths(TreeNode root) {
List<String> rst = new ArrayList<String>();
dfs(rst, new ArrayList<Integer>(), root);
return rst;
}
private void dfs(List<String> rst, List<Integer> list, TreeNode node){
if(node == null)
return;
list.add(node.val);
if(node.left == null && node.right == null){
String str = "" + list.get(0);
for(int i=1; i<list.size(); ++i)
str += "->" + list.get(i);
rst.add(str);
}
else{
dfs(rst, list, node.left);
dfs(rst, list, node.right);
}
list.remove(list.size()-1);
}
public boolean wordPattern(String pattern, String str) {
String[] strs = str.split(" ");
Map<Character, String> map = new HashMap<Character, String>();
int index = 0;
for(int i=0; i<strs.length; ++i){
if(strs[i].length() == 0)
continue;
if(index >= pattern.length())
return false;
char ch = pattern.charAt(index++);
if(map.containsKey(ch)){
if(!map.get(ch).equals(strs[i]))
return false;
continue;
}
if(map.containsValue(strs[i]))
return false;
map.put(ch, strs[i]);
}
return index == pattern.length();
}
public String minWindow(String s, String t) {
if(s == null || t == null)
throw new IllegalArgumentException();
if(s.length() == 0 || t.length() == 0)
return "";
Map<Character, Integer> map = new HashMap<Character, Integer>();
int count = 0;
for(int i=0; i<t.length(); ++i){
char key = t.charAt(i);
if(map.containsKey(key))
map.put(key, map.get(key)+1);
else{
map.put(key, 1);
++count;
}
}
int left = 0;
int right = 0;
int len = s.length()+1;
String str = "";
while(right < s.length()){
char ch = s.charAt(right);
if(map.containsKey(ch)){
map.put(ch, map.get(ch)-1);
if(map.get(ch) == 0)
--count;
if(count == 0){
if(right-left+1 < len){
str = s.substring(left, right+1);
len = right-left+1;
}
while(left < right){
char key = s.charAt(left++);
if(map.containsKey(key)){
map.put(key, map.get(key)+1);
if(map.get(key) == 1){
++count;
break;
}
}
if(right-left+1 < len){
str = s.substring(left, right+1);
len = right-left+1;
}
}
}
}
++right;
}
return str;
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null)
return null;
int min = Math.min(q.val, p.val);
int max = Math.max(q.val, p.val);
if(root.val == min || root.val == max || root.val > min && root.val < max)
return root;
if(root.val < min)
return lowestCommonAncestor(root.right, p, q);
else
return lowestCommonAncestor(root.left, p, q);
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null)
return null;
if(root == p || root == q)
return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if(left == null && right == null)
return null;
if(left != null && right != null)
return root;
return left != null ? left : right;
}
public int hIndex(int[] citations) {
int[] counts = new int[citations.length+1];
for(int num : citations)
if(num > citations.length)
counts[citations.length]++;
else
counts[num]++;
int sum = 0;
for(int i=counts.length-1; i>0; --i){
int count = sum + counts[i];
if(count >= i)
return i;
sum = count;
}
return 0;
}
public int hIndex(int[] citations) {
int left = 0;
int right = citations.length-1;
int total = citations.length;
int hindex = 0;
while(left <= right){
int mid = left + (right-left)/2;
if(citations[mid] >= total - mid){
hindex = Math.max(hindex, total - mid);
right = mid-1;
}
else
left = mid+1;
}
return hindex;
}
public int[] maxSlidingWindow(int[] nums, int k) {
if(k > nums.length)
throw new IllegalArgumentException();
if(nums.length == 0)
return nums;
int[] rst = new int[nums.length-k+1];
Deque<Integer> deq = new ArrayDeque<Integer>();
int index = 0;
for(int i=0; i<nums.length; ++i){
if(!deq.isEmpty() && i-deq.getFirst() == k)
deq.removeFirst();
while(!deq.isEmpty() && nums[deq.getLast()] < nums[i])
deq.removeLast();
deq.addLast(i);
if(i >= k-1)
rst[index++] = nums[deq.getFirst()];
}
return rst;
}