/src/main/java/com/dzhou/corejava/leetcode/old/LeetCode.java
Java | 6293 lines | 4160 code | 1266 blank | 867 comment | 1795 complexity | 27a97661ff553b8b943a5f23a2267846 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- package com.dzhou.corejava.leetcode.old;
- import com.dzhou.corejava.crackingthecode.LinkedListNode;
- import com.dzhou.corejava.leetcode.ListNode;
- import com.dzhou.corejava.leetcode.TreeLinkNode;
- import com.dzhou.corejava.leetcode.TreeNode;
- import com.dzhou.util.StringUtils;
- import java.util.*;
- /**
- * Created by huizhou on 7/15/14.
- */
- public class LeetCode {
- /**
- * http://www.programcreek.com/2012/12/leetcode-solution-of-two-sum-in-java/
- * https://oj.leetcode.com/submissions/detail/9009004/
- */
- public static int[] twoSum(int[] numbers, int target) {
- int[] result = {-1, -1};
- if (numbers == null)
- return result;
- HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
- for (int i = 0; i < numbers.length; i++) {
- if (map.containsKey(numbers[i])) {
- result[0] = map.get(numbers[i]) + 1;
- result[1] = i + 1;
- break;
- } else {
- map.put(target - numbers[i], i);
- }
- }
- return result;
- }
- /**
- * https://oj.leetcode.com/problems/median-of-two-sorted-arrays/
- * https://oj.leetcode.com/submissions/detail/9009719/
- */
- public static double findMedianSortedArrays(int A[], int B[]) {
- int aLen = A.length;
- int bLen = B.length;
- int len = aLen + bLen;
- if (len % 2 == 0)
- return (kthElement(A, B, len / 2 - 1, 0, aLen - 1, 0, bLen - 1)
- + kthElement(A, B, len / 2, 0, aLen - 1, 0, bLen - 1)) * 0.5;
- else
- return kthElement(A, B, len / 2, 0, aLen - 1, 0, bLen - 1);
- }
- private static int kthElement(int[] A, int[] B, int k, int aStart, int aEnd, int bStart, int bEnd) {
- int aLen = aEnd - aStart + 1;
- int bLen = bEnd - bStart + 1;
- if (aLen <= 0 || A.length <= 0)
- return B[bStart + k];
- if (bLen <= 0 || B.length <= 0)
- return A[aStart + k];
- if (k == 0)
- return Math.min(A[aStart + k], B[bStart + k]);
- int aMid = k * aLen / (aLen + bLen);
- int bMid = k - aMid - 1;
- aMid = aStart + aMid;
- bMid = bStart + bMid;
- if (A[aMid] >= B[bMid]) {
- k = k - (bMid - bStart + 1);
- aEnd = aMid;
- bStart = bMid + 1;
- } else {
- k = k - (aMid - aStart + 1);
- bEnd = bMid;
- aStart = aMid + 1;
- }
- return kthElement(A, B, k, aStart, aEnd, bStart, bEnd);
- }
- /**
- * https://oj.leetcode.com/problems/longest-substring-without-repeating-characters/
- * https://oj.leetcode.com/submissions/detail/9010153/
- */
- public static int lengthOfLongestSubstring(String s) {
- if (s == null)
- return 0;
- if (s.length() <= 1)
- return s.length();
- int longest = 1;
- int i = 0;
- int j = 1;
- for (j = 1; j < s.length(); j++) {
- int index = s.substring(i, j).indexOf(s.charAt(j));
- if (index >= 0) {
- if (j - i > longest)
- longest = j - i;
- i = i + index + 1;
- }
- }
- if (j - i > longest)
- longest = j - i;
- return longest;
- }
- /**
- * https://oj.leetcode.com/problems/add-two-numbers/
- * https://oj.leetcode.com/submissions/detail/9011366/
- */
- public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
- ListNode sentinel = new ListNode(0);
- ListNode p = sentinel;
- int carry = 0;
- while (l1 != null || l2 != null) {
- if (l1 != null) {
- carry += l1.val;
- l1 = l1.next;
- }
- if (l2 != null) {
- carry += l2.val;
- l2 = l2.next;
- }
- ListNode n = new ListNode(carry % 10);
- p.next = n;
- p = n;
- carry /= 10;
- }
- if (carry == 1) {
- p.next = new ListNode(carry);
- }
- return sentinel.next;
- }
- /**
- * https://oj.leetcode.com/problems/longest-palindromic-substring/
- * https://oj.leetcode.com/submissions/detail/9012368/
- */
- public static String longestPalindrome(String s) {
- if (s == null)
- return null;
- if (s.length() == 1)
- return s;
- String longest = s.substring(0, 1);
- for (int i = 0; i <= s.length() - 2; i++) {
- String pStr = expend(s, i, i);
- String qStr = expend(s, i, i + 1);
- if (pStr.length() > longest.length())
- longest = pStr;
- if (qStr.length() > longest.length())
- longest = qStr;
- }
- return longest;
- }
- private static String expend(String s, int i, int j) {
- if (s == null || i < 0 || i > s.length() - 1 || j < 0 || j > s.length() - 1 || i > j || s.charAt(i) != s.charAt(j))
- return "";
- while (i >= 0 && j < s.length() && s.charAt(i) == s.charAt(j)) {
- i--;
- j++;
- }
- return s.substring(i + 1, j);
- }
- public static Set<String> longestPalindromSubStrings1(String s) {
- Set<String> results = new HashSet<String>();
- if (s.isEmpty())
- return null;
- if (s.length() == 1) {
- results.add(s);
- return results;
- }
- int longest = 1;
- for (int i = 0; i < s.length(); i++) {
- String l = expend(s, i, i);
- if (l.length() == longest) {
- results.add(l);
- } else if (l.length() > longest) {
- results.clear();
- results.add(l);
- longest = l.length();
- }
- l = expend(s, i, i + 1);
- if (l.length() == longest) {
- results.add(l);
- } else if (l.length() > longest) {
- results.clear();
- results.add(l);
- longest = l.length();
- }
- }
- return results;
- }
- /**
- * https://oj.leetcode.com/problems/reverse-integer/
- * https://oj.leetcode.com/submissions/detail/9012870/
- */
- public static int reverse(int x) {
- int sign = 1;
- if (x < 0) {
- sign = -1;
- x = x * (-1);
- }
- int result = 0;
- while (x > 0) {
- result = 10 * result + x % 10;
- x /= 10;
- }
- return sign * result;
- }
- /**
- * http://www.programcreek.com/2012/12/leetcode-string-to-integer-atoi/
- * https://oj.leetcode.com/submissions/detail/9014031/
- */
- public static int atoi(String str) {
- if (str == null || str.trim().length() == 0)
- return 0;
- str = str.trim();
- int sign = 1;
- int i = 0;
- if (str.charAt(0) == '+') {
- i++;
- }
- if (str.charAt(0) == '-') {
- sign = -1;
- i++;
- }
- double result = 0.0;
- while (i < str.length() && str.charAt(i) >= '0' && str.charAt(i) <= '9') {
- result = 10.0 * result + (str.charAt(i) - '0');
- i++;
- }
- result = sign * result;
- if (result >= Integer.MAX_VALUE)
- return Integer.MAX_VALUE;
- if (result <= Integer.MIN_VALUE)
- return Integer.MIN_VALUE;
- return (int) result;
- }
- /**
- * https://oj.leetcode.com/problems/palindrome-number/
- * https://oj.leetcode.com/submissions/detail/9014691/
- */
- public static boolean isPalindrome(int x) {
- if (x < 0)
- return false;
- if (x < 10)
- return true;
- int div = 10;
- while (x / div >= 10)
- div *= 10;
- while (div >= 10) {
- int left = x / div;
- int right = x % 10;
- if (left != right)
- return false;
- x = (x % div) / 10;
- div /= 100;
- }
- return true;
- }
- /**
- * https://oj.leetcode.com/problems/regular-expression-matching/
- * https://oj.leetcode.com/submissions/detail/9016055/
- */
- public static boolean isMatch(String s, String p) {
- if (s == null)
- return p == null;
- if (p == null)
- return s == null;
- if (p.length() == 0)
- return s.length() == 0;
- if (p.length() == 1 || p.charAt(1) != '*') {
- if (s.length() < 1 || (p.charAt(0) != '.' && p.charAt(0) != s.charAt(0)))
- return false;
- return isMatch(s.substring(1), p.substring(1));
- } else {
- int i = -1;
- while (i < s.length() && (i < 0 || p.charAt(0) == '.' || p.charAt(0) == s.charAt(i))) {
- if (isMatch(s.substring(i + 1), p.substring(2)))
- return true;
- i++;
- }
- return false;
- }
- }
- /**
- * https://oj.leetcode.com/problems/longest-common-prefix/
- * https://oj.leetcode.com/submissions/detail/9113380/
- */
- public static String longestCommonPrefix(String[] strs) {
- if (strs.length == 0)
- return "";
- String s = strs[0];
- int lo = 0, hi = s.length() - 1;
- while (lo <= hi) {
- int mid = lo + (hi - lo) / 2;
- if (isCommonPrefix(s.substring(lo, hi + 1), strs, lo))
- break;
- else if (isCommonPrefix(s.substring(lo, mid + 1), strs, lo))
- lo = mid + 1;
- else
- hi = mid - 1;
- }
- if (hi >= 0)
- return s.substring(0, hi + 1);
- else
- return "";
- }
- private static boolean isCommonPrefix(String s, String[] strs, int start) {
- for (String str : strs) {
- if (str.substring(start).indexOf(s) != 0)
- return false;
- }
- return true;
- }
- /**
- * https://oj.leetcode.com/problems/3sum/
- * https://oj.leetcode.com/submissions/detail/9259432/
- */
- public static List<List<Integer>> threeSum(int[] num) {
- Set<List<Integer>> set = new HashSet<List<Integer>>();
- Arrays.sort(num);
- for (int i = 0; i <= num.length - 3; i++) {
- int j = i + 1, k = num.length - 1;
- while (j < k) {
- int sum = num[i] + num[j] + num[k];
- if (sum < 0) {
- j++;
- } else if (sum > 0) {
- k--;
- } else {
- List<Integer> r = new ArrayList<Integer>();
- r.add(num[i]);
- r.add(num[j]);
- r.add(num[k]);
- set.add(r);
- j++;
- k--;
- }
- }
- }
- List<List<Integer>> result = new ArrayList<List<Integer>>();
- for (List<Integer> s : set) {
- result.add(s);
- }
- return result;
- }
- /**
- * https://oj.leetcode.com/problems/3sum-closest/
- * https://oj.leetcode.com/submissions/detail/9260441/
- */
- public static int threeSumClosest(int[] num, int target) {
- Arrays.sort(num);
- int min = Integer.MAX_VALUE;
- int result = 0;
- for (int i = 0; i <= num.length - 3; i++) {
- int j = i + 1;
- int k = num.length - 1;
- while (j < k) {
- int sum = num[i] + num[j] + num[k];
- int diff = Math.abs(sum - target);
- if (diff < min) {
- min = diff;
- result = sum;
- }
- if (sum == target) {
- return sum;
- } else if (sum < target) {
- j++;
- } else {
- k--;
- }
- }
- }
- return result;
- }
- /**
- * https://oj.leetcode.com/problems/swap-nodes-in-pairs/
- * https://oj.leetcode.com/submissions/detail/9273396/
- */
- public ListNode swapPairs(ListNode head) {
- if (head == null)
- return head;
- ListNode p = head;
- while (p != null) {
- ListNode q = p.next;
- if (q != null) {
- int temp = p.val;
- p.val = q.val;
- q.val = temp;
- p = q.next;
- } else {
- break;
- }
- }
- return head;
- }
- /**
- * https://oj.leetcode.com/problems/4sum/
- * https://oj.leetcode.com/problems/4sum/
- */
- public static List<List<Integer>> fourSum(int[] num, int target) {
- Set<List<Integer>> set = new HashSet<List<Integer>>();
- Arrays.sort(num);
- for (int i = 0; i <= num.length - 4; i++) {
- for (int j = i + 1; j <= num.length - 3; j++) {
- int m = j + 1;
- int n = num.length - 1;
- while (m < n) {
- int sum = num[i] + num[j] + num[m] + num[n];
- if (sum == target) {
- List<Integer> l = new ArrayList<Integer>();
- l.add(num[i]);
- l.add(num[j]);
- l.add(num[m]);
- l.add(num[n]);
- set.add(l);
- m++;
- n--;
- } else if (sum < target) {
- m++;
- } else {
- n--;
- }
- }
- }
- }
- List<List<Integer>> result = new ArrayList<List<Integer>>();
- for (List<Integer> s : set) {
- result.add(s);
- }
- return result;
- }
- /**
- * https://oj.leetcode.com/problems/remove-nth-node-from-end-of-list/
- * https://oj.leetcode.com/submissions/detail/9265681/
- */
- public ListNode removeNthFromEnd(ListNode head, int n) {
- if (head == null)
- return head;
- if (n <= 0)
- return head;
- ListNode p = head;
- ListNode q = head;
- int count = 0;
- for (int i = 0; i <= n - 1 && q != null; i++) {
- q = q.next;
- count++;
- }
- if (count < n)
- return head;
- else {
- if (q == null)
- return head.next;
- else {
- while (q.next != null) {
- p = p.next;
- q = q.next;
- }
- if (p.next != null)
- p.next = p.next.next;
- }
- }
- return head;
- }
- /**
- * https://oj.leetcode.com/problems/valid-parentheses/
- * https://oj.leetcode.com/submissions/detail/9269784/
- */
- public boolean isValid(String s) {
- Stack<Character> stack = new Stack<Character>();
- for (int i = 0; i < s.length(); i++) {
- char c = s.charAt(i);
- if (c == '{' || c == '(' || c == '[')
- stack.push(c);
- else if (c == '}' && (stack.isEmpty() || stack.pop() != '{')) {
- return false;
- } else if (c == ')' && (stack.isEmpty() || stack.pop() != '(')) {
- return false;
- } else if (c == ']' && (stack.isEmpty() || stack.pop() != '[')) {
- return false;
- }
- }
- return stack.isEmpty();
- }
- /**
- * https://oj.leetcode.com/problems/generate-parentheses/
- * https://oj.leetcode.com/submissions/detail/9270187/
- */
- public static List<String> generateParenthesis(int n) {
- List<String> parenthesis = new ArrayList<String>();
- if (n == 0) {
- parenthesis.add("");
- return parenthesis;
- }
- generateParenthesisHelper(parenthesis, n, 0, 0, "");
- return parenthesis;
- }
- private static void generateParenthesisHelper(List<String> parenthesis, int n, int left, int right, String s) {
- if (left == n) {
- for (int i = 0; i < n - right; i++)
- s += ")";
- parenthesis.add(s);
- } else if (left > right) {
- generateParenthesisHelper(parenthesis, n, left + 1, right, s + "(");
- generateParenthesisHelper(parenthesis, n, left, right + 1, s + ")");
- } else if (left == right) {
- generateParenthesisHelper(parenthesis, n, left + 1, right, s + "(");
- }
- }
- /**
- * https://oj.leetcode.com/problems/merge-k-sorted-lists/
- * https://oj.leetcode.com/submissions/detail/9271178/
- */
- public ListNode mergeKLists(List<ListNode> lists) {
- if (lists == null)
- return null;
- PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
- for (ListNode node : lists) {
- while (node != null) {
- pq.add(node.val);
- node = node.next;
- }
- }
- ListNode res = new ListNode(0);
- ListNode tail = res;
- while (!pq.isEmpty()) {
- tail.next = new ListNode(pq.poll());
- tail = tail.next;
- }
- return res.next;
- }
- /**
- * https://oj.leetcode.com/problems/reverse-nodes-in-k-group/
- * https://oj.leetcode.com/submissions/detail/9355999/
- */
- public ListNode reverseKGroup(ListNode head, int k) {
- if (head == null || k <= 1)
- return head;
- int count = 0;
- ListNode p = head;
- while (count < k && p != null) {
- count++;
- p = p.next;
- }
- if (count < k)
- return head;
- p = head;
- ListNode q = head;
- ListNode r = null;
- for (int i = 0; i < k; i++) {
- p = p.next;
- q.next = r;
- r = q;
- q = p;
- }
- head.next = reverseKGroup(p, k);
- return r;
- }
- /**
- * https://oj.leetcode.com/problems/remove-duplicates-from-sorted-array/
- * https://oj.leetcode.com/submissions/detail/9356997/
- */
- public static int removeDuplicates(int[] A) {
- if (A.length <= 1)
- return A.length;
- int k = 0;
- for (int i = 1; i < A.length; i++) {
- if (A[i] != A[k])
- A[++k] = A[i];
- }
- return k + 1;
- }
- /**
- * https://oj.leetcode.com/problems/remove-duplicates-from-sorted-array-ii/
- * https://oj.leetcode.com/submissions/detail/10762488/
- *
- */
- public static int removeDuplicates2(int[] A) {
- if (A.length <= 2)
- return A.length;
- int k = 1;
- for (int i = 2; i < A.length; i++) {
- if (!(A[i] == A[k] && A[i] == A[k-1]))
- A[++k] = A[i];
- }
- return k + 1;
- }
- /**
- * https://oj.leetcode.com/problems/remove-element/
- * https://oj.leetcode.com/submissions/detail/9357121/
- */
- public int removeElement(int[] A, int elem) {
- int i = 0, j = 0;
- while (j < A.length) {
- if (A[j] != elem) {
- A[i] = A[j];
- i++;
- }
- j++;
- }
- return i;
- }
- /**
- * https://oj.leetcode.com/problems/implement-strstr/
- * https://oj.leetcode.com/submissions/
- */
- public static String strStr(String haystack, String needle) {
- if (haystack == null || needle == null)
- return null;
- int haystackLen = haystack.length();
- int needleLen = needle.length();
- if (haystackLen < needleLen)
- return null;
- if (needleLen == 0)
- return haystack;
- for (int i = 0; i <= haystackLen - needleLen; i++) {
- int j = 0;
- while (j < needleLen && i + j < haystackLen
- && needle.charAt(j) == haystack.charAt(i + j))
- j++;
- if (j == needleLen)
- return haystack.substring(i);
- }
- return null;
- }
- public static String strStr2(String haystack, String needle) {
- int needleLen = needle.length();
- int haystackLen = haystack.length();
- if (needleLen == haystackLen && needleLen == 0)
- return "";
- if (needleLen == 0)
- return haystack;
- for (int i = 0; i < haystackLen; i++) {
- // make sure in boundary of needle
- if (haystackLen - i + 1 < needleLen)
- return null;
- int k = i;
- int j = 0;
- while (j < needleLen && k < haystackLen && needle.charAt(j) == haystack.charAt(k)) {
- j++;
- k++;
- if (j == needleLen)
- return haystack.substring(i);
- }
- }
- return null;
- }
- /**
- * https://oj.leetcode.com/problems/divide-two-integers/
- * https://oj.leetcode.com/submissions/detail/9400097/
- */
- public static int divide(int dividend, int divisor) {
- int result = 0;
- int sign = 1;
- long lDividend = dividend;
- long lDivisor = divisor;
- if (dividend == 0)
- return 0;
- if (divisor == 1)
- return dividend;
- if (dividend < 0) {
- sign = 0 - sign;
- lDividend = 0 - lDividend;
- }
- if (divisor < 0) {
- sign = 0 - sign;
- lDivisor = 0 - lDivisor;
- }
- while (lDividend >= lDivisor) {
- long mDivisor = lDivisor;
- int factor = 0;
- while (mDivisor <= lDividend && mDivisor > 0) {
- mDivisor = mDivisor << 1;
- factor++;
- }
- factor--;
- result += (1 << factor);
- lDividend -= (lDivisor << factor);
- }
- if (sign == -1)
- result = 0 - result;
- return result;
- }
- private static void permute(Set<String> result, String[] L, String p, int count, int total) {
- if (count == total)
- result.add(p);
- if (L == null)
- return;
- int l = L.length;
- if (l == 0)
- return;
- else {
- for (int i = 0; i < l; i++) {
- String w = L[i];
- String[] temp = new String[l - 1];
- for (int j = 0; j < i; j++)
- temp[j] = L[j];
- for (int j = i; j < l - 1; j++)
- temp[j] = L[j + 1];
- permute(result, temp, p + w, count + 1, total);
- }
- }
- }
- /**
- * https://oj.leetcode.com/problems/substring-with-concatenation-of-all-words/
- * https://oj.leetcode.com/submissions/detail/9464973/
- */
- public static List<Integer> findSubstring(String S, String[] L) {
- List<Integer> result = new ArrayList<Integer>();
- if (S == null || L == null) return result;
- int n = L.length;
- if (n == 0) return result;
- int m = L[0].length();
- int l = S.length();
- Map<String, Integer> countMap = new HashMap<String, Integer>();
- for (String w : L) {
- Integer count = countMap.get(w);
- if (count == null)
- countMap.put(w, 1);
- else
- countMap.put(w, count + 1);
- }
- for (int i = 0; i <= l - n * m; i++) {
- Map<String, Integer> temp = new HashMap<String, Integer>(countMap);
- boolean isSubStr = true;
- for (int j = 0; j < n; j++) {
- String w = S.substring(i + j * m, i + (j + 1) * m);
- Integer count = temp.get(w);
- if (count == null || count == 0) {
- isSubStr = false;
- break;
- } else {
- count--;
- temp.put(w, count);
- }
- }
- if (isSubStr)
- result.add(i);
- }
- return result;
- }
- /**
- * https://oj.leetcode.com/problems/next-permutation/
- * https://oj.leetcode.com/submissions/detail/9469583/
- */
- public static void nextPermutation(int[] num) {
- if (num == null) return;
- int len = num.length;
- if (len <= 1) return;
- for (int i = len - 2; i >= 0; i--) {
- int min = findMin(num, i, len - 1);
- if (i < min) {
- exch(num, i, min);
- sort(num, i + 1, len - 1);
- return;
- }
- }
- sort(num, 0, len - 1);
- }
- private static int findMin(int[] num, int start, int end) {
- if (start == end)
- return start;
- int min = start;
- int i = start;
- while (i <= end && num[i] <= num[start])
- i++;
- if (i <= end)
- min = i;
- for (i = min + 1; i <= end; i++) {
- if (num[i] <= num[min] && num[i] > num[start])
- min = i;
- }
- return min;
- }
- private static void exch(int[] a, int i, int j) {
- int swap = a[i];
- a[i] = a[j];
- a[j] = swap;
- }
- private static void sort(int[] num, int start, int end) {
- if (start == end) return;
- for (int i = start + 1; i <= end; i++) {
- for (int j = i; j > start && num[j] < num[j - 1]; j--) {
- exch(num, j - 1, j);
- }
- }
- }
- /**
- * https://oj.leetcode.com/problems/longest-valid-parentheses/
- * https://oj.leetcode.com/submissions/detail/9511539/
- */
- public static int longestValidParentheses1(String s) {
- int res = 0;
- if (s == null || s.length() == 0)
- return 0;
- int left = 0, right = 0;
- for (int i = 0; i <= s.length() - 1; i++) {
- if (s.charAt(i) == '(') {
- left++;
- } else if (s.charAt(i) == ')') {
- right++;
- if (right == left) {
- if (2 * left > res) {
- res = 2 * left;
- }
- } else if (right > left) {
- left = 0;
- right = 0;
- }
- }
- }
- left = 0;
- right = 0;
- for (int i = s.length() - 1; i >= 0; i--) {
- if (s.charAt(i) == ')') {
- right++;
- } else if (s.charAt(i) == '(') {
- left++;
- if (left == right) {
- if (2 * left > res) {
- res = 2 * left;
- }
- } else if (left > right) {
- left = 0;
- right = 0;
- }
- }
- }
- return res;
- }
- /**
- * http://www.darrensunny.me/leetcode-longest-valid-parentheses/
- *
- * @param s
- * @return
- */
- public static int longestValidParentheses(String s) {
- if (s == null || s.length() == 0)
- return 0;
- int longestLength = 0; // Length of the longest valid parentheses
- int start = 0; // The start index of the possibly longest valid parentheses
- Stack<Integer> stack = new Stack<Integer>();
- // One-pass scan
- for (int i = 0; i < s.length(); i++) {
- if (s.charAt(i) == '(') { // Opening parenthesis
- stack.push(i); // Push its index
- } else { // Closing parenthesis
- if (stack.empty()) { // No opening parenthesis to match
- start = i + 1; // i+1 is the start of next possibly LVP
- } else {
- stack.pop(); // The index of the opening parenthesis matched by s[i]
- if (stack.empty()) // s[start...i] is matched
- longestLength = Math.max(longestLength, i - start + 1);
- else // s[stack.peek()] is unmatched; s[stack.peek()+1...i] is matched
- longestLength = Math.max(longestLength, i - stack.peek());
- }
- }
- }
- return longestLength;
- }
- /**
- * https://oj.leetcode.com/problems/search-in-rotated-sorted-array/
- * http://www.darrensunny.me/leetcode-search-in-rotated-sorted-array/
- * http://www.darrensunny.me/leetcode-search-in-rotated-sorted-array-ii/
- * https://oj.leetcode.com/submissions/detail/9551838/
- * https://oj.leetcode.com/submissions/detail/9552605/
- */
- public int search1(int[] A, int target) {
- if (A == null || A.length == 0) return -1;
- return searchHelper(A, target, 0, A.length - 1);
- }
- private int searchHelper(int[] A, int target, int start, int end) {
- if (start > end)
- return -1;
- int mid = start + (end - start) / 2;
- if (A[mid] == target)
- return mid;
- else if (target > A[mid]) {
- if (A[end] >= A[mid] && target > A[end])
- return searchHelper(A, target, start, mid - 1);
- else
- return searchHelper(A, target, mid + 1, end);
- } else {
- if (A[start] <= A[mid] && target < A[start])
- return searchHelper(A, target, mid + 1, end);
- else
- return searchHelper(A, target, start, mid - 1);
- }
- }
- public int search(int[] A, int target) {
- if (A == null || A.length == 0) return -1;
- int left = 0, right = A.length - 1;
- while (left <= right) {
- int mid = (left + right) / 2;
- if (A[mid] == target)
- return mid;
- else if (A[mid] > A[left]) {
- if (target >= A[left] && target < A[mid])
- right = mid - 1;
- else
- left = mid + 1;
- } else if (A[mid] < A[left]) {
- if (target > A[mid] && target <= A[right])
- left = mid + 1;
- else
- right = mid - 1;
- } else {
- left++;
- }
- }
- return -1;
- }
- /**
- * https://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/
- * https://oj.leetcode.com/submissions/detail/10902114/
- * @param A
- * @param target
- * @return
- */
- //Allow duplicated
- public boolean search2(int[] A, int target) {
- if (A == null || A.length == 0) return false;
- int left = 0, right = A.length - 1;
- while (left <= right) {
- int mid = (left + right) / 2;
- if (A[mid] == target)
- return true;
- else if (A[mid] > A[left]) {
- if (target >= A[left] && target < A[mid])
- right = mid - 1;
- else
- left = mid + 1;
- } else if (A[mid] < A[left]) {
- if (target > A[mid] && target <= A[right])
- left = mid + 1;
- else
- right = mid - 1;
- } else {
- left++;
- }
- }
- return false;
- }
- /**
- * https://oj.leetcode.com/problems/search-for-a-range/
- * http://www.darrensunny.me/leetcode-search-for-a-range/
- * https://oj.leetcode.com/submissions/detail/9556992/
- */
- public static int[] searchRange(int[] A, int target) {
- if (A == null || A.length == 0)
- return new int[]{-1, -1};
- int left = 0, right = A.length - 1;
- //Find left matching index
- while (left < right) {
- if (A[left] > target || A[right] < target)
- return new int[]{-1, -1};
- int mid = (left + right) / 2;
- if (A[mid] < target)
- left = mid + 1;
- else
- right = mid;
- }
- if (A[left] != target)
- return new int[]{-1, -1};
- int index1 = left;
- right = A.length - 1;
- while (left < right) {
- int mid = (left + right + 1) / 2;
- if (A[mid] > target)
- right = mid - 1;
- else
- left = mid;
- }
- return new int[]{index1, right};
- }
- /**
- * https://oj.leetcode.com/problems/search-insert-position/
- * http://www.programcreek.com/2013/01/leetcode-search-insert-position/
- * https://oj.leetcode.com/submissions/detail/9557823/
- */
- public int searchInsert(int[] A, int target) {
- if (A == null || A.length == 0) return 0;
- int left = 0, right = A.length - 1;
- while (left <= right) {
- if (target < A[left]) return left;
- if (target > A[right]) return right + 1;
- int mid = (left + right) / 2;
- if (A[mid] == target) return mid;
- else if (A[mid] < target) left = mid + 1;
- else right = mid - 1;
- }
- return left;
- }
- /**
- * https://oj.leetcode.com/problems/valid-sudoku/
- * https://oj.leetcode.com/submissions/detail/9559909/
- */
- public static boolean isValidSudoku(char[][] board) {
- for (int i = 0; i < 9; i++) {
- char[] row = board[i];
- if (!isValidSudoku(row))
- return false;
- }
- char[] column = new char[9];
- for (int i = 0; i < 9; i++) {
- for (int j = 0; j < 9; j++)
- column[j] = board[j][i];
- if (!isValidSudoku(column))
- return false;
- }
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- char[] box = new char[9];
- for (int m = 0; m < 3; m++) {
- int ii = i * 3 + m;
- for (int n = 0; n < 3; n++) {
- int jj = j * 3 + n;
- box[m * 3 + n] = board[ii][jj];
- }
- }
- if (!isValidSudoku(box))
- return false;
- }
- }
- return true;
- }
- private static boolean isValidSudoku(char[] c) {
- Map<Character, Integer> map = new HashMap<Character, Integer>();
- for (int i = 0; i < c.length; i++) {
- if (c[i] == '.')
- continue;
- else {
- if (c[i] >= '1' && c[i] <= '9' && map.get(c[i]) == null)
- map.put(c[i], 1);
- else
- return false;
- }
- }
- return true;
- }
- /**
- * https://oj.leetcode.com/problems/sudoku-solver/
- * http://rleetcode.blogspot.com/2014/01/sudoku-solver-java.html
- * https://oj.leetcode.com/submissions/detail/9560489/
- */
- public void solveSudoku(char[][] board) {
- if (board == null || board.length == 0) {
- return;
- }
- solved(board);
- }
- private boolean solved(char[][] board) {
- for (int i = 0; i < board.length; i++) {
- for (int j = 0; j < board[0].length; j++) {
- if (board[i][j] == '.') {
- for (char num = '1'; num <= '9'; num++) {
- if (isValid(board, i, j, num)) {
- // no conflict
- board[i][j] = num;
- if (solved(board)) {
- return true;
- } else {
- board[i][j] = '.';
- }
- }
- }
- // if no proper number found, return false
- return false;
- }
- }
- }
- return true;
- }
- private boolean isValid(char[][] board, int i, int j, char c) {
- // check column
- for (int row = 0; row < 9; row++) {
- if (board[row][j] == c) {
- return false;
- }
- }
- // check row
- for (int col = 0; col < 9; col++) {
- if (board[i][col] == c) {
- return false;
- }
- }
- // check block
- for (int row = i / 3 * 3; row < i / 3 * 3 + 3; row++) {
- for (int col = j / 3 * 3; col < j / 3 * 3 + 3; col++) {
- if (board[row][col] == c) {
- return false;
- }
- }
- }
- return true;
- }
- /**
- * https://oj.leetcode.com/problems/count-and-say/
- * https://oj.leetcode.com/submissions/detail/9651625/
- */
- public String countAndSay(int n) {
- if (n <= 0) return null;
- if (n == 1) return "1";
- StringBuilder sb = new StringBuilder("1");
- for (int i = 2; i <= n; i++) {
- String s = sb.toString();
- sb = new StringBuilder();
- int count = 1, j = 1;
- for (j = 1; j < s.length(); j++) {
- if (s.charAt(j) == s.charAt(j - 1)) {
- count++;
- } else {
- sb.append(count).append(s.charAt(j - 1));
- count = 1;
- }
- }
- sb.append(count).append(s.charAt(j - 1));
- }
- return sb.toString();
- }
- /**
- * https://oj.leetcode.com/problems/combination-sum/
- * http://www.darrensunny.me/leetcode-combination-sum/
- * https://oj.leetcode.com/submissions/detail/9655670/
- */
- public static List<List<Integer>> combinationSum(int[] candidates, int target) {
- List<List<Integer>> r = new ArrayList<List<Integer>>();
- if (candidates == null || candidates.length == 0)
- return r;
- Arrays.sort(candidates);
- int N = 0;
- while (N <= candidates.length - 1 && candidates[N] <= target)
- N++;
- return combinationSum(candidates, N, target);
- }
- private static List<List<Integer>> combinationSum(int[] c, int N, int target) {
- List<List<Integer>> r = new ArrayList<List<Integer>>();
- if (N == 0) {
- } else if (N == 1) {
- if (target % c[0] == 0) {
- List<Integer> l = new ArrayList<Integer>();
- for (int n = 0; n < target / c[0]; n++)
- l.add(c[0]);
- r.add(l);
- }
- } else {
- int d = c[N - 1];
- if (d <= target) {
- for (int n = 0; n <= target / d; n++) {
- int newTarget = target - n * d;
- if (newTarget > 0) {
- List<List<Integer>> l = combinationSum(c, N - 1, newTarget);
- for (List<Integer> b : l) {
- for (int j = 0; j < n; j++)
- b.add(d);
- r.add(b);
- }
- } else {
- List<Integer> l = new ArrayList<Integer>();
- for (int m = 0; m < n; m++) {
- l.add(d);
- }
- r.add(l);
- }
- }
- } else {
- r = combinationSum(c, N - 1, target);
- }
- }
- return r;
- }
- /**
- * https://oj.leetcode.com/problems/combination-sum-ii/
- * https://oj.leetcode.com/submissions/detail/9701592/
- */
- public static List<List<Integer>> combinationSum2(int[] num, int target) {
- List<List<Integer>> result = new ArrayList<List<Integer>>();
- if (num == null || num.length == 0)
- return result;
- Arrays.sort(num); // Sort the candidate in non-descending order
- ArrayList<Integer> current = new ArrayList<Integer>();
- recursiveAppend(num, target, 0, current, result);
- return result;
- }
- private static void recursiveAppend(int[] num, int target, int startIndex,
- List<Integer> current, List<List<Integer>> result) {
- if (target < 0)
- return;
- if (target == 0) { // The current array is an solution
- result.add(new ArrayList<Integer>(current));
- return;
- }
- for (int i = startIndex; i < num.length; i++) {
- if (num[i] > target) // No need to try the remaining candidates
- break;
- // Add candidate[i] to the current array
- ArrayList<Integer> copy = new ArrayList(current);
- copy.add(num[i]);
- while (i <= num.length - 2 && num[i + 1] == num[i])
- i++;
- // Recursively append the current array to compose a solution
- recursiveAppend(num, target - num[i], i + 1, copy, result);
- }
- }
- /**
- * https://oj.leetcode.com/problems/first-missing-positive/
- * https://oj.leetcode.com/submissions/detail/9702757/
- */
- public int firstMissingPositive(int[] A) {
- if (A == null || A.length == 0) return 1;
- HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
- for (int i = 0; i < A.length; i++)
- map.put(A[i], 1);
- int missing = 1;
- while (map.get(missing) != null) missing++;
- return missing;
- }
- /**
- * https://oj.leetcode.com/problems/trapping-rain-water/
- * https://oj.leetcode.com/submissions/detail/9704165/
- */
- public int trap(int[] A) {
- if (A == null || A.length <= 2)
- return 0;
- int result = 0;
- int N = A.length;
- HashMap<Integer, LeftAndRight> map = new HashMap<Integer, LeftAndRight>();
- map.put(1, new LeftAndRight(A[0], 0));
- for (int i = 2; i <= N - 2; i++) {
- int left = map.get(i - 1).left;
- int a = Math.max(left, A[i - 1]);
- map.put(i, new LeftAndRight(a, 0));
- }
- LeftAndRight l = map.get(N - 2);
- l.right = A[N - 1];
- map.put(N - 2, l);
- for (int i = A.length - 3; i >= 1; i--) {
- int right = map.get(i + 1).right;
- int b = Math.max(A[i + 1], right);
- LeftAndRight r = map.get(i);
- r.right = b;
- map.put(i, r);
- }
- for (int i = 1; i <= N - 2; i++) {
- LeftAndRight m = map.get(i);
- int k = Math.min(m.left, m.right);
- if (k > A[i]) result += (k - A[i]);
- }
- return result;
- }
- private class LeftAndRight {
- int left;
- int right;
- LeftAndRight(int left, int right) {
- this.left = left;
- this.right = right;
- }
- }
- /**
- * https://oj.leetcode.com/problems/multiply-strings/
- * http://www.darrensunny.me/leetcode-multiply-strings/
- * https://oj.leetcode.com/submissions/detail/9825634/
- */
- public String multiply1(String num1, String num2) {
- if (num1 == null || num1.length() == 0 ||
- num2 == null || num2.length() == 0)
- return "";
- if (num1.equals("0") || num2.equals("0")) // Either one is 0
- return "0";
- int m = num1.length(), n = num2.length();
- // Multiply single digit of each number and add up products at each position
- int[] prods = new int[m + n];
- for (int i = n - 1; i >= 0; i--)
- for (int j = m - 1; j >= 0; j--)
- prods[i + j + 1] += (num2.charAt(i) - '0') * (num1.charAt(j) - '0');
- // Keep a single digit at each position and add carry to a higher position
- StringBuilder result = new StringBuilder();
- for (int i = n + m - 1; i >= 0; i--) {
- result.insert(0, prods[i] % 10);
- if (i > 0)
- prods[i - 1] += prods[i] / 10; // Carry
- }
- // Get rid of one leaing "0" (if any)
- if (result.charAt(0) == '0')
- result.deleteCharAt(0);
- return result.toString();
- }
- public static String multiply(String num1, String num2) {
- if (num1 == null && num2 == null) return null;
- if (num1 != null && num2 == null) return num1;
- if (num1 == null && num2 != null) return num2;
- if (num1.equals("0") || num2.equals("0")) return "0";
- int N1 = num1.length();
- int N2 = num2.length();
- String result = "";
- if (N1 > N2) {
- for (int i = 0; i < N2; i++) {
- String s = "";
- int c = num2.charAt(i) - '0';
- for (int j = 0; j < c; j++) {
- s = add(s, num1);
- }
- for (int j = 0; j < (N2 - 1 - i); j++)
- s += "0";
- result = add(result, s);
- }
- } else {
- for (int i = 0; i < N1; i++) {
- String s = "";
- int c = num1.charAt(i) - '0';
- for (int j = 0; j < c; j++) {
- s = add(s, num2);
- }
- for (int j = 0; j < (N1 - 1 - i); j++)
- s += "0";
- result = add(result, s);
- }
- }
- return result;
- }
- private static String add(String num1, String num2) {
- if (num1 == null && num2 == null) return null;
- if (num1 != null && (num2 == null || num2.length() == 0 || num2.equals("0"))) return num1;
- if ((num1 == null || num1.length() == 0 || num1.equals("0")) && num2 != null) return num2;
- Stack<Character> s1 = new Stack<Character>();
- Stack<Character> s2 = new Stack<Character>();
- Stack<Character> s3 = new Stack<Character>();
- for (int i = 0; i < num1.length(); i++)
- s1.push(num1.charAt(i));
- for (int i = 0; i < num2.length(); i++)
- s2.push(num2.charAt(i));
- int carryOver = 0;
- while (!s1.isEmpty() || !s2.isEmpty()) {
- Character c1 = null;
- Character c2 = null;
- if (!s1.isEmpty())
- c1 = s1.pop();
- if (!s2.isEmpty())
- c2 = s2.pop();
- if (c1 != null)
- carryOver += c1 - '0';
- if (c2 != null)
- carryOver += c2 - '0';
- s3.push(toCharacter(carryOver % 10));
- carryOver /= 10;
- }
- if (carryOver == 1)
- s3.push(toCharacter(carryOver));
- StringBuilder sb = new StringBuilder();
- while (!s3.isEmpty())
- sb.append(s3.pop());
- return sb.toString();
- }
- private static Character toCharacter(int c) {
- if (c == 0) return '0';
- else if (c == 1) return '1';
- else if (c == 2) return '2';
- else if (c == 3) return '3';
- else if (c == 4) return '4';
- else if (c == 5) return '5';
- else if (c == 6) return '6';
- else if (c == 7) return '7';
- else if (c == 8) return '8';
- else if (c == 9) return '9';
- else return null;
- }
- /**
- * https://oj.leetcode.com/problems/wildcard-matching/
- * http://www.darrensunny.me/leetcode-wildcard-matching-2/
- * http://www.programering.com/a/MTN0kzMwATU.html isMatch4 (working one)
- * https://oj.leetcode.com/submissions/detail/9830224/
- */
- public static boolean isMatch2(String s, String p) {
- if (s == null) return p == null;
- if (p == null) return s == null;
- if (p.length() == 0) return s.length() == 0;
- if (p.equals("*")) return true;
- if (s.length() == 0) return p.length() == 0;
- char c = p.charAt(p.length() - 1);
- if (c != '?' && c != '*' && c != s.charAt(s.length() - 1)) return false;
- if (p.charAt(0) == '?') return isMatch2(s.substring(1), p.substring(1));
- if (p.charAt(0) == '*') {
- int j = 0;
- while (j < p.length() && p.charAt(j) == '*')
- j++;
- if (j >= p.length())
- return true;
- int i = 0;
- while (i < s.length()) {
- if (isMatch2(s.substring(i), p.substring(j)))
- return true;
- i++;
- }
- return false;
- }
- return s.charAt(0) == p.charAt(0) && isMatch2(s.substring(1), p.substring(1));
- }
- public static boolean isMatch3(String s, String p) {
- if (s == null || p == null)
- return false;
- int m = s.length(), n = p.length();
- boolean[] match = new boolean[m + 1]; // Used for dynamic programming
- match[0] = true;
- // After each round, the information whether p[0...i] matches s[0...m-1]
- // is updated in match[1...m]
- for (int i = 0; i < n; i++) {
- if (p.charAt(i) != '*') { // Not wildcard
- for (int j = m; j > 0; j--) // Update match backwards
- match[j] = match[j - 1] &&
- (p.charAt(i) == '?' || s.charAt(j - 1) == p.charAt(i));
- } else { // Wildcard
- int j = 0;
- // Find the minimum j with p[0...i-1] matching s[0...j]
- while (j <= m && !match[j])
- j++;
- // Since p[i] is '*' that matches any sequence, p[0...i] matches with
- // s[0...j+1], s[0...j+2] ...
- for (; j <= m; j++)
- match[j] = true;
- }
- match[0] = match[0] && p.charAt(i) == '*';
- }
- return match[m];
- }
- public static boolean isMatch4(String s, String p) {
- if (s == null || p == null) return false;
- if (s.equals(p)) return true;
- int m = s.length();
- int n = p.length();
- int posS = 0;
- int posP = 0;
- int posStar = -1;
- int posOfS = -1;
- //if posS == posP || posP == '?', ++posS and ++posP.
- //posOfS, posStar, record the positon of '*' in s and p, ++posP and go on.
- //if not match, go back to star, ++posOfS
- while (posS < m) {
- if (posP < n && (s.charAt(posS) == p.charAt(posP) || p.charAt(posP) == '?')) {
- ++posS;
- ++posP;
- } else if (posP < n && p.charAt(po…
Large files files are truncated, but you can click here to view the full file