+ * Given an array of integers, find two numbers such that they add up to a specific target number.
+ * The function twoSum should return indices of the two numbers such that they add up to the target,
+ * where index1 must be less than index2. Please note that your returned answers (both index1 and index2)
+ * are not zero-based.
+ * You may assume that each input would have exactly one solution.
+ *
+ * Input: numbers={2, 7, 11, 15}, target=9
+ * Output: index1=1, index2=2
+ *
+ * 题目大意
+ * 给定一个整数数组,找出其中两个数满足相加等于你指定的目标数字。
+ * 要求:这个函数twoSum必须要返回能够相加等于目标数字的两个数的索引,且index1必须要小于index2。
+ * 请注意一点,你返回的结果(包括index1和index2)都不是基于0开始的。你可以假设每一个输入肯定只有一个结果。
+ *
+ * 解题思路
+ * 创建一个辅助类数组,对辅助类进行排序,使用两个指针,开始时分别指向数组的两端,看这两个下标对应的值是否
+ * 等于目标值,如果等于就从辅助类中找出记录的下标,构造好返回结果,返回。如果大于就让右边的下标向左移,
+ * 进入下一次匹配,如果小于就让左边的下标向右移动,进入下一次匹配,直到所有的数据都处理完
+ *
+ *
+ * @param nums
+ * @param target
+ * @return
+ */
+
+ public int[] twoSum(int[] nums, int target) {
+ int[] result = {0, 0};
+
+ // 因为无素可能会重复,用于记录元素出现的下标
+ Map
+ * Given an array of integers, find two numbers such that they add up to a specific target number.
+ * The function twoSum should return indices of the two numbers such that they add up to the target,
+ * where index1 must be less than index2. Please note that your returned answers (both index1 and index2)
+ * are not zero-based.
+ * You may assume that each input would have exactly one solution.
+ *
+ * Input: numbers={2, 7, 11, 15}, target=9
+ * Output: index1=1, index2=2
+ *
+ * 题目大意
+ * 给定一个整数数组,找出其中两个数满足相加等于你指定的目标数字。
+ * 要求:这个函数twoSum必须要返回能够相加等于目标数字的两个数的索引,且index1必须要小于index2。
+ * 请注意一点,你返回的结果(包括index1和index2)都不是基于0开始的。你可以假设每一个输入肯定只有一个结果。
+ *
+ * 解题思路
+ * 创建一个辅助类数组,对辅助类进行排序,使用两个指针,开始时分别指向数组的两端,看这两个下标对应的值是否
+ * 等于目标值,如果等于就从辅助类中找出记录的下标,构造好返回结果,返回。如果大于就让右边的下标向左移,
+ * 进入下一次匹配,如果小于就让左边的下标向右移动,进入下一次匹配,直到所有的数据都处理完
+ *
+ *
+ * @param nums
+ * @param target
+ * @return
+ */
+
+ public int[] twoSum(int[] nums, int target) {
+ int[] result = {0, 0};
+
+ Node[] tmp = new Node[nums.length];
+ for (int i = 0; i < nums.length; i++) {
+ tmp[i] = new Node(nums[i], i);
+ }
+
+ // 先排序,然后左右夹逼,排序O(n log n),左右夹逼O(n),最终O(n log n)。但是注
+ // 意,这题需要返回的是下标,而不是数字本身,因此这个方法不好。
+ Arrays.sort(tmp);
+
+ int lo = 0;
+ int hi = nums.length - 1;
+
+
+ while (lo < hi) {
+ if (tmp[lo].val + tmp[hi].val == target) {
+
+ if (tmp[lo].idx > tmp[hi].idx) {
+ result[0] = tmp[hi].idx + 1;
+ result[1] = tmp[lo].idx + 1;
+ } else {
+ result[0] = tmp[lo].idx + 1;
+ result[1] = tmp[hi].idx + 1;
+ }
+ break;
+ } else if (tmp[lo].val + tmp[hi].val > target) {
+ hi--;
+ } else {
+ lo++;
+ }
+ }
+ return result;
+ }
+}
diff --git a/[0002][Add Two Numbers]/[0002][Add Two Numbers].iml b/[0002][Add Two Numbers]/[0002][Add Two Numbers].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0002][Add Two Numbers]/[0002][Add Two Numbers].iml
@@ -0,0 +1,13 @@
+
++ * ԭ + * You are given two linked lists representing two non-negative numbers. + * The digits are stored in reverse order and each of their nodes contain + * a single digit. Add the two numbers and return it as a linked list. + * Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) + * Output: 7 -> 0 -> 8 + * + * Ŀ + * ǸÿһڵһλǷ洢ģ + * һʾλһʾλӺͣʽء + * + * ˼· + * ӵһʼӣٳ10̣ΪһλӵĽλ + * ͬʱ¼ΪλĽһֱֱеĽ㶼ꡣ + *+ * + * @param l1 һ + * @param l2 ڶ + * @return + */ + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + + if (l1 == null) { + return l2; + } + + if (l2 == null) { + return l1; + } + + ListNode p1 = l1; + ListNode p2 = l2; + // ͷ + ListNode root = new ListNode(0); + ListNode r = root; + root.next = l1; + + // ʼλ + int carry = 0; + int sum; + while (p1 != null && p2 != null) { + sum = p1.val + p2.val + carry; + // λĽ + p1.val = sum % 10; + // νλ + carry = sum / 10; + + r.next = p1; + // ָһӵĽ + r = p1; + p1 = p1.next; + p2 = p2.next; + + } + + if (p1 == null) { + r.next = p2; + } else { + r.next = p1; + } + + // һӻнλ + if (carry == 1) { + // ʼʱr.nextǵһҪӵĽ + while (r.next != null && carry != 0) { + sum = r.next.val + carry; + r.next.val = sum % 10; + carry = sum / 10; + r = r.next; + } + + // ˻нλҪһµĽ + if (carry == 1) { + r.next = new ListNode(1); + } + } + + return root.next; + } +} diff --git a/[0003][Longest Substring Without Repeating Characters]/[0003][Longest Substring Without Repeating Characters].iml b/[0003][Longest Substring Without Repeating Characters]/[0003][Longest Substring Without Repeating Characters].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0003][Longest Substring Without Repeating Characters]/[0003][Longest Substring Without Repeating Characters].iml @@ -0,0 +1,13 @@ + +
+ * Given a string, find the length of the longest substring without repeating characters. + * For example, the longest substring without repeating letters for "abcabcbb" is "abc", + * which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1. + * + * Ŀ⣺ + * һַַеظӴ + * + * ˼· + * start¼Ŀʼλ + * ַǰַӿʼλstartʼѾֹʱӴʼλ+1mapеhashֵΪǰλá + * + * ԴеUTF-8ַ + *+ * + * @param s + * @return + */ + public int lengthOfLongestSubstring(String s) { + // ַ벻Ϸ + if (s == null) { + return 0; + } + + // ǰĿʼλ + int start = 0; + // + int result = 0; + // ʱǣ¼һηʵַλ + Map
+ * There are two sorted arrays nums1 and nums2 of size m and n respectively. + * Find the median of the two sorted arrays. The overall run time complexity + * should be O(log (m+n)). + * + * Ŀ⣺ + * 飬λʱ临ӶΪO(log(m+n)) + * + * ˼· + * ݹ + *+ * + * @param nums1 + * @param nums2 + * @return + */ + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + int total = nums1.length + nums2.length; + if (total % 2 != 0) { + return findKth(nums1, 0, nums2, 0, total / 2 + 1); + } else { + return (findKth(nums1, 0, nums2, 0, total / 2) + + findKth(nums1, 0, nums2, 0, total / 2 + 1) + ) / 2.0; + } + } + + /** + * ҵkԪأk=1, 2, 3, ... + * + * @param nums1 1 + * @param start1 ʼλ1 + * @param nums2 2 + * @param start2 ʼλ2 + * @param k Ҫҵλλ + * @return + */ + public int findKth(int[] nums1, final int start1, + int[] nums2, final int start2, + final int k) { + // ҪҳСķǰ + if (nums1.length - start1 > nums2.length - start2) { + return findKth(nums2, start2, nums1, start1, k); + } + + // ԪصѾﵽĩβ + if (nums1.length == start1) { + return nums2[start2 + k - 1]; + } + + // һбȽС + if (k == 1) { + return Math.min(nums1[start1], nums2[start2]); + } + + + // num1, nums2иһ൱ÿζҪ1/4 + int half = Math.min(k / 2, nums1.length - start1); + // nums2пҵλ + int ia = half + start1; + // nums2пҵλ + int ib = k - half + start2; + + // nums1[start, ..., ia-1, ia, ..., nums1.length] + // nums2[start, ..., ib-1, ib, ..., nums2.length] + // ˵nums1[start, ..., ia-1]ˣҪҵֵnums1[ia, ..., nums1.length] + // nums2[start, ..., ib-1, ib, ..., nums2.length] + if (nums1[ia - 1] < nums2[ib - 1]) { + // k - (ia - start1) = k - (half + start1 - start1) = k - half + return findKth(nums1, ia, nums2, start2, k - (ia - start1)); + } + + // ˵nums2[start, ..., ib-1]ˣҪҵֵnums2[ib, ..., nums2.length] + // nums1[start, ..., ia-1, ia, ..., nums1.length] + else if (nums1[ia - 1] > nums2[ib - 1]) { + // k - (ib - start2) = k - (k - half + start2 - start2) + return findKth(nums1, start1, nums2, ib, half); + } + // ֵ˵ҵˣ + else { + return nums1[ia - 1]; + } + } +} diff --git a/[0004][Median of Two Sorted Arrays]/src/Solution2.java b/[0004][Median of Two Sorted Arrays]/src/Solution2.java new file mode 100644 index 0000000..601e821 --- /dev/null +++ b/[0004][Median of Two Sorted Arrays]/src/Solution2.java @@ -0,0 +1,79 @@ +/** + * Author: + * Date: 2015-06-17 + * Time: 20:54 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + /** + *
+ * There are two sorted arrays nums1 and nums2 of size m and n respectively. + * Find the median of the two sorted arrays. The overall run time complexity + * should be O(log (m+n)). + * + * Ŀ⣺ + * 飬λʱ临ӶΪO(log(m+n)) + * + * ˼· + * ݹ + *+ * + * @param nums1 + * @param nums2 + * @return + */ + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + + if (nums1 == null) { + nums1 = new int[0]; + } + + if (nums2 == null) { + nums2 = new int[0]; + } + + int len1 = nums1.length; + int len2 = nums2.length; + + if (len1 < len2) { + // ȷһȵڶ鳤ȴ + return findMedianSortedArrays(nums2, nums1); + } + + // С鳤Ϊ0ͷǰһλ + if (len2 == 0) { + return (nums1[(len1 - 1) / 2] + nums1[len1 / 2]) / 2.0; + } + + + int lo = 0; + int hi = len2 * 2; + int mid1; + int mid2; + double l1; + double l2; + double r1; + double r2; + + while (lo <= hi) { + mid2 = (lo + hi) / 2; + mid1 = len1 + len2 - mid2; + + l1 = (mid1 == 0) ? Integer.MIN_VALUE : nums1[(mid1 - 1) / 2]; + l2 = (mid2 == 0) ? Integer.MIN_VALUE : nums2[(mid2 - 1) / 2]; + + r1 = (mid1 == len1 * 2) ? Integer.MAX_VALUE : nums1[mid1 / 2]; + r2 = (mid2 == len2 * 2) ? Integer.MAX_VALUE : nums2[mid2 / 2]; + + if (l1 > r2) { + lo = mid2 + 1; + } else if (l2 > r1) { + hi = mid2 - 1; + } else { + return (Math.max(l1, l2) + Math.min(r1, r2)) / 2; + } + } + + return -1; + } +} diff --git a/[0005][Longest Palindromic Substring Total]/[0005][Longest Palindromic Substring Total].iml b/[0005][Longest Palindromic Substring Total]/[0005][Longest Palindromic Substring Total].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0005][Longest Palindromic Substring Total]/[0005][Longest Palindromic Substring Total].iml @@ -0,0 +1,13 @@ + +
+ * Given a string S, find the longest palindromic substring in S. + * You may assume that the maximum length of S is 1000, and there + * exists one unique longest palindromic substring. + * + * Ŀ⣺ + * һַSҳĻӴԼַ1000 + * ҴΨһӴ + * + * ˼· + * ̬滮 + * dp[ i ][ j ]ֵΪtrueʾַs± i j ַɵӴǻĴôƳ + * dp[ i ][ j ] = dp[ i + 1][ j - 1] && s[ i ] == s[ j ] + * һҪi+1, j -1п i + 1 = j -1, i +1 = (j - 1) -1 + * ҪϵĹʽ + * + * a. i + 1 = j -1ijΪ1ʱdp[ i ][ i ] = true; + * b. i +1 = (j - 1) -1ijΪ2ʱdp[ i ][ i + 1] = (s[ i ] == s[ i + 1]) + * + * ϷͿдˡҪעǶ̬滮ҪO(n^2)Ŀռ䡣 + *+ * + * @param s + * @return + */ + public String longestPalindrome(String s) { + + if (s == null || s.length() < 2) { + return s; + } + + int maxLength = 0; + String longest = null; + + int length = s.length(); + boolean[][] table = new boolean[length][length]; + + // ַǻ + for (int i = 0; i < length; i++) { + table[i][i] = true; + longest = s.substring(i, i + 1); + maxLength = 1; + } + + // жַǷǻ + for (int i = 0; i < length - 1; i++) { + if (s.charAt(i) == s.charAt(i + 1)) { + table[i][i + 1] = true; + longest = s.substring(i, i + 2); + maxLength = 2; + } + } + + + // ȴ2ӴǷǻĴ + for (int len = 3; len <= length; len++) { + for (int i = 0, j; (j = i + len - 1) <= length - 1; i++) { + if (s.charAt(i) == s.charAt(j)) { + table[i][j] = table[i + 1][j - 1]; + if (table[i][j] && maxLength < len) { + longest = s.substring(i, j + 1); + maxLength = len; + } + } else { + table[i][j] = false; + } + } + } + + return longest; + } + + +} diff --git a/[0006][Zig Zag Conversion]/[0006][Zig Zag Conversion].iml b/[0006][Zig Zag Conversion]/[0006][Zig Zag Conversion].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0006][Zig Zag Conversion]/[0006][Zig Zag Conversion].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * The string PAYPALISHIRING is written in a zigzag pattern on a given number + * of rows like this: (you may want to display this pattern in a fixed font for + * better legibility) + * P A H N + * APLSIIG + * Y I R + * And then read line by line: PAHNAPLSIIGYIR + * Write the code that will take a string and make this conversion given a number of rows: + * string convert(string text, int nRows); + * convert(PAYPALISHIRING,3) should return PAHNAPLSIIGYIR. + * Ŀ + * һַַָZ + * + * ˼· + * ַһһά飬ټÿַһάеλã + * ٶһάеַнղؽ + *+ * + * @param s + * @param nRows + * @return + */ + public String convert(String s, int nRows) { + + if (s == null || s.length() <= nRows || nRows == 1) { + return s; + } + + int index = s.length(); + int rowLength = 0; // еijȣַ + + int slash = nRows - 2; // һб߳ȥβռõ + + while (index > 0) { + // εһ + index -= nRows; + rowLength++; + + // бŵ + for (int i = 0; i < slash && index > 0; i++) { + rowLength++; + index--; + } + } + + char[] result = new char[nRows * rowLength]; // 飬һڱ滻з + for (int i = 0; i < result.length; i++) { // ʼΪո + result[i] = ' '; + } + + int curColumn = 0; // ǰ + index = 0; + while (index < s.length()) { + // + for (int i = 0; i < nRows && index < s.length(); i++) { + result[rowLength * i + curColumn] = s.charAt(index); + index++; + } + curColumn++; + // б + for (int i = nRows - 2; i > 0 && index < s.length(); i--) { + result[rowLength * i + curColumn] = s.charAt(index); + curColumn++; + index++; + } + } + + // ַнղ + index = 0; + while (index < s.length() && result[index] != ' ') { // ҵһǿոַλ + index++; + } + int next = index + 1; + while (index < s.length()) { + while (next < result.length && result[next] == ' ') { // ҲǿոԪ + next++; + } + result[index] = result[next]; + index++; + next++; + } + return new String(result, 0, index); + } +} diff --git a/[0007][Reverse Integer]/[0007][Reverse Integer].iml b/[0007][Reverse Integer]/[0007][Reverse Integer].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0007][Reverse Integer]/[0007][Reverse Integer].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Implement atoi to convert a string to an integer. + * Hint: Carefully consider all possible input cases. If you want a challenge, + * please do not see below and ask yourself what are the possible input cases. + * Notes: It is intended for this problem to be specified vaguely (ie, no given + * input specs). You are responsible to gather all the input requirements up front. + * + * Ŀ + * ʵһatoiַת + * Ҫ㣺е + * + * ˼· + * ǰַ+-ûУֲ֣ܱʾС + * ͷضӦССֵ + *+ * + * @param str + * @return + */ + public int atoi(String str) { + + if (str == null || str.length() == 0) { +// throw new NumberFormatException("Invalid input string: " + str); + return 0; + } + + // ַԿոʼ + int start = 0; //ӿʼҵһǿո + boolean positive = true; // ǷΪĬΪtrue + + if (str.charAt(start) == ' ') { + while (str.charAt(start) == ' ') { + start++; + if (start >= str.length()) { // ȫǿո +// throw new NumberFormatException("Invalid input string: " + str); + return 0; + } + } + } + + if (str.charAt(start) == '-') { // һǿհַ- + positive = false; + start++; + } else if (str.charAt(start) == '+') {// һǿհַ+ + start++; + } else if (str.charAt(start) >= '0' && str.charAt(start) <= '9') { // һǿհַ + return cal(str, start, true); + } else { // ׳쳣 +// throw new NumberFormatException("Invalid input string: " + str); + return 0; + } + + + if (start >= str.length()) { // һǿհַ+-Ҳһַ +// throw new NumberFormatException("Invalid input string: " + str); + return 0; + } + + if (str.charAt(start) > '9' || str.charAt(start) < '0') { // +-ӵIJ +// throw new NumberFormatException("Invalid input string: " + str); + return 0; + } else { + return cal(str, start, positive); + } + } + + private int cal(String str, int start, boolean positive) { + + long result = 0; + while (start < str.length() && str.charAt(start) >= '0' && str.charAt(start) <= '9') { + result = result * 10 + (str.charAt(start) - '0'); + + if (positive) { // + if (result > Integer.MAX_VALUE) { +// throw new NumberFormatException("Invalid input string: " + str); + return Integer.MAX_VALUE; + } + + } else { + if (-result < Integer.MIN_VALUE) { +// throw new NumberFormatException("Invalid input string: " + str); + return Integer.MIN_VALUE; + } + } + + start++; + } + + if (positive) { + return (int) result; + } else { + return (int) -result; + } + } +} diff --git a/[0009][Palindrome Number]/[0009][Palindrome Number].iml b/[0009][Palindrome Number]/[0009][Palindrome Number].iml new file mode 100644 index 0000000..73f33e3 --- /dev/null +++ b/[0009][Palindrome Number]/[0009][Palindrome Number].iml @@ -0,0 +1,23 @@ + +
+ * ԭ + * Determine whether an integer is a palindrome. Do this without extra space. + * + * Ŀ + * жһǷǻطҪʹöĿռ䡣 + * + * ˼· + * Ϊ˲ʹöĿռ䣬οĽЩⷨisPalindromeûʹö + * ȴʹ˷ãһĵĿռ ûдﵽĿҪǼٵʵ֣ + * ԱȻһĿռʵ֡ + * ȣǻ֣ζֽת123321任˵ǻ֡ + *+ * + * @param x + * @return + */ + public boolean isPalindrome(int x) { + + // ǻ + if (x < 0) { + return false; + } + + // תֵΪ˲ʹlong + long reverse = 0; + int tmp = x; + + // תֵ + while (tmp != 0) { + reverse = reverse * 10 + tmp % 10; + tmp /= 10; + } + + // жǷǻ + return x == reverse; + } +} diff --git a/[0010][Regular Expression Matching]/[0010][Regular Expression Matching].iml b/[0010][Regular Expression Matching]/[0010][Regular Expression Matching].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0010][Regular Expression Matching]/[0010][Regular Expression Matching].iml @@ -0,0 +1,13 @@ + +
+ * Implement regular expression matching with support for '.' and '*'.
+ * '.' Matches any single character.
+ * '*' Matches zero or more of the preceding element.
+ *
+ * The matching should cover the entire input string (not partial).
+ *
+ * The function prototype should be:
+ * bool isMatch(const char *s, const char *p)
+ * Some examples:
+ * isMatch("aa","a") false
+ * isMatch("aa","aa") true
+ * isMatch("aaa","aa") false
+ * isMatch("aa", "a*") true
+ * isMatch("aa", ".*") true
+ * isMatch("ab", ".*") true
+ * isMatch("aab", "c*a*b") true
+ *
+ * Ŀ⣺
+ * ʵһʽƥ㷨.ƥһַ*ƥ0߶ǰַ
+ *
+ * Կ˼·
+ * ע
+ *
+ *
+ *
+ * @param s
+ * @param p
+ * @return
+ */
+ public boolean isMatch(String s, String p) {
+ boolean[] match = new boolean[s.length() + 1];
+ Arrays.fill(match, false);
+ match[s.length()] = true;
+ for (int i = p.length() - 1; i >= 0; i--) {
+ if (p.charAt(i) == '*') {
+ for (int j = s.length() - 1; j >= 0; j--) {
+ match[j] = match[j] || match[j + 1]
+ && (p.charAt(i - 1) == '.' || s.charAt(j) == p.charAt(i - 1));
+ }
+ i--;
+ } else {
+ for (int j = 0; j < s.length(); j++) {
+ match[j] = match[j + 1]
+ && (p.charAt(i) == '.' || p.charAt(i) == s.charAt(j));
+ }
+
+ match[s.length()] = false;
+ }
+ }
+ return match[0];
+ }
+
+ // ĴʱȽϳ
+ public boolean isMatch2(String s, String p) {
+ // 붼Ϊnull
+ if (s == null && p == null) {
+ return true;
+ }
+ // һΪnull
+ else if (s == null || p == null) {
+ return false;
+ }
+
+ return isMatch(s, 0, p, 0);
+ }
+
+ /**
+ * ʽƥ
+ *
+ * @param s ƥ䴮
+ * @param sIdx ǰƥλ
+ * @param p ģʽ
+ * @param pIdx ģʽƥλ
+ * @return ƥ
+ */
+ public boolean isMatch(String s, int sIdx, String p, int pIdx) {
+ // ͬʱԵĩβ
+ if (s.length() == sIdx && p.length() == pIdx) {
+ return true;
+ }
+ // ƥ䴮ûеĩβģʽѾĩβ
+ else if (s.length() != sIdx && p.length() == pIdx) {
+ return false;
+ }
+ //
+ else {
+ // ǰƥһַ*
+ if (pIdx < p.length() - 1 && p.charAt(pIdx + 1) == '*') {
+ // ƥ䴮δҵǰַƥ䣨ַȻ.ţ
+ if (sIdx < s.length() && (s.charAt(sIdx) == p.charAt(pIdx) || p.charAt(pIdx) == '.')) {
+ return isMatch(s, sIdx + 1, p, pIdx + 2) // ƥ䴮ǰƶһַֻƥһΣ
+ || isMatch(s, sIdx + 1, p, pIdx) // ƥ䴮ǰƶһַһƥͬģģʽ
+ || isMatch(s, sIdx, p, pIdx + 2); // ƥģʽ
+ } else {
+ // *
+ return isMatch(s, sIdx, p, pIdx + 2);
+ }
+ }
+
+ // ƥһַ
+ if (sIdx < s.length() && (s.charAt(sIdx) == p.charAt(pIdx) || p.charAt(pIdx) == '.')) {
+ return isMatch(s, sIdx + 1, p, pIdx + 1);
+ }
+ }
+
+ return false;
+ }
+
+}
diff --git a/[0011][Container With Most Water]/[0011][Container With Most Water].iml b/[0011][Container With Most Water]/[0011][Container With Most Water].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0011][Container With Most Water]/[0011][Container With Most Water].iml
@@ -0,0 +1,13 @@
+
++ * Given n non-negative integers a1, a2, ..., an, where each represents + * a point at coordinate (i, ai). n vertical lines are drawn such that + * the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, + * which together with x-axis forms a container, such that the container + * contains the most water. + * + * Note: You may not slant the container. + * + * Ŀ⣺ + * ȻԼXṹɵˮ + * + * ˼· + * ʹ̰㷨 + * 1.ȼҵȡݻΪ i, j (ٶi < j) + * ôõݻ C = min( ai , aj ) * ( j- i) + * + * 2.ǿôһʣ + * : j Ҷûһߣ k |( j < k && ak > aj) + * ô ak > aj min(ai, aj, ak) =min(ai, aj) + * i, kɵݻC' = min(ai, aj) * (k - i) > C + * CֵìܣԵ֤jĺ߲бߵߣ + * + * :ͬiҲбߵߣ˵ʲôأ + * Ŀǰõĺѡ Ϊ x, yߣx< y)ôܹõ + * ݻµ߱Ȼ[x, y]ڲ ax' >= ax , ay' >= ay; + * + * 3.Ǵͷм俿£ͬʱºѡֵʱȴ + * x, yнСı߿ʼ + *+ * + * @param height + * @return + */ + public int maxArea(int[] height) { + + // У + if (height == null || height.length < 2) { + return 0; + } + + + // ¼Ľ + int result = 0; + + // ߵ + int left = 0; + // ұߵ + int right = height.length - 1; + + while (left < right) { + // 㵱ǰֵ + result = Math.max(result, Math.min(height[left], height[right]) * (right - left)); + // ұ߸ + if (height[left] < height[right]) { + int k = left; + // [left, right - 1]Уңҵһ߶ȱheight[left]ߵλ + while (k < right && height[k] <= height[left]) { + k++; + } + + // [left, right - 1]У¼һԭheight[left]ߵλ + left = k; + } + // ߵ߸ + else { + int k = right; + // [left + 1, right]Уңҵһ߶ȱheight[right]ߵλ + while (k > left && height[k] <= height[right]) { + k--; + } + + // [left, right - 1]У¼һԭheight[right]ߵλ + right = k; + } + } + + return result; + } +} diff --git a/[0011][Container With Most Water]/src/Solution2.java b/[0011][Container With Most Water]/src/Solution2.java new file mode 100644 index 0000000..556a26a --- /dev/null +++ b/[0011][Container With Most Water]/src/Solution2.java @@ -0,0 +1,74 @@ +/** + * Author: + * Date: 2015-06-30 + * Time: 07:25 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + /** + *
+ * Given n non-negative integers a1, a2, ..., an, where each represents + * a point at coordinate (i, ai). n vertical lines are drawn such that + * the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, + * which together with x-axis forms a container, such that the container + * contains the most water. + * + * Note: You may not slant the container. + * + * Ŀ⣺ + * ȻԼXṹɵˮ + * + * ˼· + * ʹ̰㷨 + * 1.ȼҵȡݻΪ i, j (ٶi+ * + * @param height + * @return + */ + public int maxArea(int[] height) { + + // У + if (height == null || height.length < 2) { + return 0; + } + + + // ¼Ľ + int result = 0; + + // ߵ + int left = 0; + // ұߵ + int right = height.length - 1; + + while (left < right) { + // 㵱ǰֵ + result = Math.max(result, Math.min(height[left], height[right]) * (right - left)); + // ұ߸ + if (height[left] < height[right]) { + left++; + } + // ߵ߸ + else { + right--; + } + } + + return result; + } +} diff --git a/[0012][Integer To Roman]/[0012][Integer To Roman].iml b/[0012][Integer To Roman]/[0012][Integer To Roman].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0012][Integer To Roman]/[0012][Integer To Roman].iml @@ -0,0 +1,13 @@ + +aj) + * ô ak > aj min(ai, aj, ak) =min(ai, aj) + * i, kɵݻC' = min(ai, aj) * (k - i) > C + * CֵìܣԵ֤jĺ߲бߵߣ + * + * :ͬiҲбߵߣ˵ʲôأ + * Ŀǰõĺѡ Ϊ x, yߣx< y)ôܹõ + * ݻµ߱Ȼ[x, y]ڲ ax' >= ax , ay' >= ay; + * + * 3.Ǵͷм俿£ͬʱºѡֵʱȴ + * x, yнСı߿ʼ + *
+ * Given an integer, convert it to a roman numeral. + * + * Input is guaranteed to be within the range from 1 to 3999. + * + * ֵıʾ + * λ + * (I, 1) (II, 2) (III, 3) (IV, 4) (V, 5) (VI, 6) (VII, 7) (VIII, 8) (IX, 9) + * + * ʮλ + * (X, 10) (XI, 11) (XII, 12) (XIII, 13) (XIV, 14) (XV, 15) (XVI, 16) + * (XVII, 17) (XVIII, 18) (XIX, 19) (XX, 20) (XXI, 21) (XXII, 22) + * (XXIX, 29) (XXX, 30) (XXXIV, 34) (XXXV, 35) (XXXIX, 39) (XL, 40) + * (L, 50) (LI, 51) (LV, 55) (LX, 60) (LXV, 65) (LXXX, 80) (XC, 90) + * (XCIII, 93) (XCV, 95) (XCVIII, 98) (XCIX, 99) + * + * λ + * (C, 100) (CC, 200) (CCC, 300) (CD, 400) (D, 500) (DC, 600) (DCC, 700) + * (DCCC, 800) (CM, 900) (CMXCIX, 999) + * + * ǧλ + * (M, 1000) (MC, 1100) (MCD, 1400) (MD, 1500) (MDC, 1600) (MDCLXVI, 1666) + * (MDCCCLXXXVIII, 1888) (MDCCCXCIX, 1899) (MCM, 1900) (MCMLXXVI, 1976) + * (MCMLXXXIV, 1984) (MCMXC, 1990) (MM, 2000) (MMMCMXCIX, 3999) + * + * Ŀ⣺ + * һ֣תһ֣[1, 3999]֮ + * + *+ * + * @param num + * @return + */ + public String intToRoman(int num) { + + final int[] radix = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; + final String[] symbol = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; + String roman = ""; + for (int i = 0; num > 0; ++i) { + int count = num / radix[i]; + num %= radix[i]; + for (; count > 0; --count) { + roman += symbol[i]; + } + } + return roman; + } +} diff --git a/[0013][Roman To Integer]/[0013][Roman To Integer].iml b/[0013][Roman To Integer]/[0013][Roman To Integer].iml new file mode 100644 index 0000000..73f33e3 --- /dev/null +++ b/[0013][Roman To Integer]/[0013][Roman To Integer].iml @@ -0,0 +1,23 @@ + +
+ * 原题 + * Given a roman numeral, convert it to an integer. + * Input is guaranteed to be within the range from 1 to 3999. + * + * 题目大意 + * 给定一个罗马数字,将其转换成对应的整数。 + * 输入的数字在1-3999之间。 + * + * 解题思路 + * 从前往后扫描,用一个临时变量记录分段数字。 + * 如果当前比前一个大,说明这一段的值应该是当前这个值减去上一个值。比如IV = 5 – 1;否 + * 则,将当前值加入到结果中,然后开始下一段记录。比如VI = 5 + 1, II=1+1 + *+ * + * @param s + * @return + */ + public int romanToInt(String s) { + + int result = 0; + + for (int i = 0; i < s.length(); i++) { + // 当前的值比前一个值大,说明[i-1, i]组成一个值,并且值是s[i-1]-s[i] + if (i > 0 && charToInt(s.charAt(i)) > charToInt(s.charAt(i - 1))) { + // 要减去两倍之前前值才能回到真实值 + result += charToInt(s.charAt(i)) - 2 * charToInt(s.charAt(i - 1)); + } else { + result += charToInt(s.charAt(i)); + } + } + + return result; + } + + private int charToInt(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; + } + } +} diff --git a/[0013][Roman To Integer]/src/Solution2.java b/[0013][Roman To Integer]/src/Solution2.java new file mode 100644 index 0000000..9d08f55 --- /dev/null +++ b/[0013][Roman To Integer]/src/Solution2.java @@ -0,0 +1,98 @@ +/** + * Author: 王俊超 + * Date: 2015-03-01 + * Time: 16:09 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + /** + *
+ * 原题 + * Given a roman numeral, convert it to an integer. + * Input is guaranteed to be within the range from 1 to 3999. + * + * 题目大意 + * 给定一个罗马数字,将其转换成对应的整数。 + * 输入的数字在1-3999之间。 + * + * 解题思路 + * 根据罗马数字与整数数字对应关系进行加法操作,如果前一个数字比后一个大就相减,否则进行相加。 + *+ * + * @param s + * @return + */ + public int romanToInt(String s) { + + int result = 0; + int prev = 0; // 记录前一个数字的值 + + for (int i = s.length() - 1; i > -1; i--) { + switch (s.charAt(i)) { + case 'I': // 1 + if (1 < prev) { + result -= 1; + } else { + result += 1; + + } + prev = 1; + break; + + case 'V': // 5 + + if (5 < prev) { + result -= 5; + } else { + result += 5; + } + + prev = 5; + + break; + case 'X': // 10 + if (10 < prev) { + result -= 10; + } else { + result += 10; + } + + prev = 10; + break; + case 'L': // 50 + if (50 < prev) { + result -= 50; + } else { + result += 50; + } + + prev = 50; + break; + case 'C': // 100 + if (100 < prev) { + result -= 100; + } else { + result += 100; + } + + prev = 100; + break; + case 'D': // 500 + if (500 < prev) { + result -= 500; + } else { + result += 500; + } + + prev = 500; + break; + case 'M': // 1000 + result += 1000; + prev = 1000; + break; + } + } + + return result; + } +} diff --git a/[0014][Longest Common Prefix]/[0014][Longest Common Prefix].iml b/[0014][Longest Common Prefix]/[0014][Longest Common Prefix].iml new file mode 100644 index 0000000..73f33e3 --- /dev/null +++ b/[0014][Longest Common Prefix]/[0014][Longest Common Prefix].iml @@ -0,0 +1,23 @@ + +
+ * ԭ + * Write a function to find the longest common prefix string amongst an array of strings. + * + * Ŀ + * дһҳһִеĹǰ + * + * ˼· + * һҳСַȻַַҳ̵ǰ + *+ * + * @param strs + * @return + */ + public String longestCommonPrefix(String[] strs) { + if (strs == null) { + return null; + } + + if (strs.length == 0) { + return ""; + } + + // ¼̵ַij + int min = Integer.MAX_VALUE; + + // Ҷַij + String result = ""; + for (String str : strs) { + + if (str == null || str.length() == 0) { + return ""; + } + + if (min > str.length()) { + min = str.length(); + result = str; + } + } + + for (String s : strs) { + for (int i = 0; i < result.length(); i++) { + if (result.charAt(i) != s.charAt(i)) { + result = result.substring(0, i); + } + } + } + + return result; + } +} diff --git a/[0014][Longest Common Prefix]/src/Solution2.java b/[0014][Longest Common Prefix]/src/Solution2.java new file mode 100644 index 0000000..17eb282 --- /dev/null +++ b/[0014][Longest Common Prefix]/src/Solution2.java @@ -0,0 +1,65 @@ +/** + * Author: + * Date: 2015-08-21 + * Time: 16:19 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + /** + *
+ * ԭ + * Write a function to find the longest common prefix string amongst an array of strings. + * + * Ŀ + * дһҳһִеĹǰ + * + * ˼· + * һҳСַȻַַҳ̵ǰ + *+ * + * @param strs + * @return + */ + public String longestCommonPrefix(String[] strs) { + if (strs == null) { + return null; + } + + if (strs.length == 0) { + return ""; + } + + // ¼̵ַij + int min = Integer.MAX_VALUE; + + // Ҷַij + for (String str : strs) { + + if (str == null) { + return null; + } + + if (min > str.length()) { + min = str.length(); + } + } + + int i; // ¼ǰַ + boolean flag; + for (i = 0; i < min; i++) { + flag = true; + for (int j = 1; j < strs.length; j++) { + if (strs[0].charAt(i) != strs[j].charAt(i)) { + flag = false; + break; + } + } + + if (!flag) { + break; + } + } + + return strs[0].substring(0, i); + } +} diff --git a/[0015][3 Sum]/[0015][3 Sum].iml b/[0015][3 Sum]/[0015][3 Sum].iml new file mode 100644 index 0000000..ec1ca74 --- /dev/null +++ b/[0015][3 Sum]/[0015][3 Sum].iml @@ -0,0 +1,33 @@ + +
+ * Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0?
+ * Find all unique triplets in the array which gives the sum of zero.
+ *
+ * Note:
+ * Elements in a triplet (a,b,c) must be in non-descending order. (ie, a b c)
+ * The solution set must not contain duplicate triplets.
+ *
+ * For example, given array S = {-1 0 1 2 -1 -4},
+ * A solution set is:
+ * (-1, 0, 1)
+ * (-1, -1, 2)
+ *
+ * Ŀ⣺
+ *
+ *
+ *
+ * @param nums
+ * @return
+ */
+ public List
+ * Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0?
+ * Find all unique triplets in the array which gives the sum of zero.
+ *
+ * Note:
+ * Elements in a triplet (a,b,c) must be in non-descending order. (ie, a b c)
+ * The solution set must not contain duplicate triplets.
+ *
+ * For example, given array S = {-1 0 1 2 -1 -4},
+ * A solution set is:
+ * (-1, 0, 1)
+ * (-1, -1, 2)
+ *
+ * Ŀ⣺
+ * һnԪص飬ǷabcԪأʹõa+b+c=0ҳзԪ
+ *
+ * ע⣺
+ * - ԪеԪرǷǵݼ
+ * - ܰظԪ
+ *
+ * ˼·
+ * 2sum Ļ3sum⣬3sumĿtargetÿδѡһk
+ * ʣµĿtarget-k2sum⡣ҪעиСtrickǴѡ
+ * iʱֻҪֵдӵi+1һΧ2sum⡣
+ *
+ * ѡһ͵ڶΪA[],ܹnԪA1A2....AnȻѡA1ʱ
+ * [A2~An]Ŀλtarget-A12sum⣬Ҫ֤ǵѡA2ʱֻҪ
+ * [A3~An]мĿλtarget-A22sum⣬[A1,A3~An]У֤£
+ * [A1,A3~An]Ŀλtarget-A22sumУA1 + m = target-A2mΪA3~An
+ * ijA2 + m = target-A1պǡ[A3~An],Ŀλtarget-A12sum⡱
+ * һ⡣൱ڶ3sumA1+A2+m = targetظˡΪ˱ظ㣬
+ * [A1A3~An]УA1ȥĿtarget-A22sum⡣
+ *
+ * ڱҪӽ⣬ֻҪ浱ǰԼǰĿľ룬µĽӽ½⡣
+ * 㷨ӶΪOn^2;
+ *
+ *
+ * @param nums
+ * @return
+ */
+ public List
+ * Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0?
+ * Find all unique triplets in the array which gives the sum of zero.
+ *
+ * Note:
+ * Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
+ * The solution set must not contain duplicate triplets.
+ *
+ * For example, given array S = {-1 0 1 2 -1 -4},
+ * A solution set is:
+ * (-1, 0, 1)
+ * (-1, -1, 2)
+ *
+ * 题目大意:
+ *
+ *
+ *
+ * @param nums
+ * @return
+ */
+ public List
+ * Given an array S of n integers, find three integers in S such that the sum is
+ * closest to a given number, target. Return the sum of the three integers. You
+ * may assume that each input would have exactly one solution.
+ *
+ * For example,
+ * given array S = {-1 2 1 -4}, and target = 1.
+ * The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
+ *
+ * Ŀ⣺
+ * nSҵSеӶʹ֮ӽ
+ * ܺ͡Լÿ뽫һȷеĽ
+ *
+ * ˼·
+ * 3sum
+ *
+ *
+ * @param nums
+ * @param target
+ * @return
+ */
+ public int threeSumClosest(int[] nums, int target) {
+
+ // ¼СIJֵ
+ long minDiff = Long.MAX_VALUE;
+ // ¼СֵӦͺ
+ long result = 0;
+ // ÿõIJֵ
+ long diff;
+ // ÿõĺ
+ long sum;
+
+ // ȶ
+ Arrays.sort(nums);
+
+
+ // iʾȡiΪ
+ for (int i = 0; i < nums.length - 2; ) {
+ // ڶܵʼλ
+ int j = i + 1;
+ // ǽλ
+ int k = nums.length - 1;
+
+ while (j < k) {
+ // ǰĺ
+ sum = nums[j] + nums[k] + nums[i];
+ // ǰĿ֮IJֵ
+ diff = Math.abs(target - sum);
+
+ // ֵΪ0ֱӷ
+ if (diff == 0) {
+ return (int) sum;
+ }
+
+ // ǰIJֵ֮ǰ¼IJֵС
+ if (diff < minDiff) {
+ // СIJֵ
+ minDiff = diff;
+ // СֵӦĺ
+ result = sum;
+
+ // ϵһԪشʱЧ
+ }
+
+ // ʹtarget
+ if (sum > target) {
+ do {
+ k--; // ҵֵͬ
+ } while (j < k && nums[k] == nums[k + 1]);
+ }
+ // Сtarget
+ else {
+ do {
+ j++;
+ } while (j < k && nums[j - 1] == nums[j]);
+ }
+ }
+
+ do {
+ i++;
+ } while (i < nums.length - 2 && nums[i - 1] == nums[i]);
+ }
+
+ return (int) result;
+ }
+}
diff --git a/[0016][3 Sum Closest]/src/Solution2.java b/[0016][3 Sum Closest]/src/Solution2.java
new file mode 100644
index 0000000..1ed9f61
--- /dev/null
+++ b/[0016][3 Sum Closest]/src/Solution2.java
@@ -0,0 +1,89 @@
+import java.util.Arrays;
+
+/**
+ * Author:
+ * Date: 2015-06-21
+ * Time: 09:29
+ * Declaration: All Rights Reserved !!!
+ */
+public class Solution2 {
+ /**
+ *
+ * Given an array S of n integers, find three integers in S such that the sum is
+ * closest to a given number, target. Return the sum of the three integers. You
+ * may assume that each input would have exactly one solution.
+ *
+ * For example,
+ * given array S = {-1 2 1 -4}, and target = 1.
+ * The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
+ *
+ * Ŀ⣺
+ * nSҵSеӶʹ֮ӽ
+ * ܺ͡Լÿ뽫һȷеĽ
+ *
+ * ˼·
+ * 3sum
+ *
+ *
+ * @param nums
+ * @param target
+ * @return
+ */
+ public int threeSumClosest(int[] nums, int target) {
+
+ // ¼СIJֵ
+ long minDiff = Long.MAX_VALUE;
+ // ¼СֵӦͺ
+ long result = 0;
+ // ÿõIJֵ
+ long diff;
+ // ÿõĺ
+ long sum;
+
+ // ȶ
+ Arrays.sort(nums);
+
+
+ // iʾȡiΪ
+ for (int i = 0; i < nums.length - 2; i++) {
+ // ڶܵʼλ
+ int j = i + 1;
+ // ǽλ
+ int k = nums.length - 1;
+
+ while (j < k) {
+ // ǰĺ
+ sum = nums[j] + nums[k] + nums[i];
+ // ǰĿ֮IJֵ
+ diff = Math.abs(target - sum);
+
+ // ֵΪ0ֱӷ
+ if (diff == 0) {
+ return (int) sum;
+ }
+
+ // ǰIJֵ֮ǰ¼IJֵС
+ if (diff < minDiff) {
+ // СIJֵ
+ minDiff = diff;
+ // СֵӦĺ
+ result = sum;
+
+ // ϵһԪشʱЧ
+ }
+
+
+ // ʹtarget
+ if (sum > target) {
+ k--;
+ }
+ // Сtarget
+ else {
+ j++;
+ }
+ }
+ }
+
+ return (int) result;
+ }
+}
diff --git a/[0017][Letter Combinations Of A Phone Number/[0017][Letter Combinations Of A Phone Number.iml b/[0017][Letter Combinations Of A Phone Number/[0017][Letter Combinations Of A Phone Number.iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0017][Letter Combinations Of A Phone Number/[0017][Letter Combinations Of A Phone Number.iml
@@ -0,0 +1,13 @@
+
++ * ԭ + * Given a digit string, return all possible letter combinations that the number could represent. + * A mapping of digit to letters (just like on the telephone buttons) is given below. + * + * Input:Digit string "23" + * Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. + * + * Note: Although the above answer is in lexicographical order, your answer + * could be in any order you want. + * + * Ŀ + * һִַϣֵַӳͼʾ + * ע⣺ Ľַ˳еģκ˳ؽ + * + * ˼· + * һ鱣ֵֺӳϵִ룬ҵӦַϽ + *+ * + * @param digits + * @return + */ + public List
+ * ԭ + * Given a digit string, return all possible letter combinations that the number could represent. + * A mapping of digit to letters (just like on the telephone buttons) is given below. + * + * Input:Digit string "23" + * Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. + * + * Note: Although the above answer is in lexicographical order, your answer + * could be in any order you want. + * + * Ŀ + * һִַϣֵַӳͼʾ + * ע⣺ Ľַ˳еģκ˳ؽ + * + * ˼· + * һ鱣ֵֺӳϵִ룬ҵӦַϽ + *+ * + * @param digits + * @return + */ + public List
+ * ԭ
+ * Given an array S of n integers, are there elements a, b, c, and d in S
+ * such that a + b + c + d = target? Find all unique quadruplets in the array
+ * which gives the sum of target.
+ * Note:
+ * Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a b c d)
+ * The solution set must not contain duplicate quadruplets.
+ *
+ * For example, given array S = {1 0 -1 0 -2 2}, and target = 0.
+ *
+ * A solution set is:
+ * (-1, 0, 0, 1)
+ * (-2, -1, 1, 2)
+ * (-2, 0, 0, 2)
+ *
+ * Ŀ
+ * һ飬ҳa + b + c + d = targetΨһ⡣
+ *
+ * ˼·
+ * ȷadadͬʱظʹáȻȷbcͬҲ
+ * ͬʱظʹáҳĽ⣬ͬʱԱ֤ⲻظ
+ *
+ *
+ * @param num
+ * @param target
+ * @return
+ */
+ public List+ * ԭ + * Given a linked list, remove the nth node from the end of list and return its head. + * For example, + * + * Given linked list: 1->2->3->4->5, and n = 2. + * After removing the second node from the end, the linked list becomes 1->2->3->5. + * + * Note: + * Given n will always be valid. + * Try to do this in one pass. + * + * Ŀ + * ɾĵڣθ㣬ע⣺ģζǺϷһαɲ + * + * ˼· + * һָҵNڵ㣬Ȼһָָͷ㣬Ȼָһߣ + * ֱǰһֱָĩβһָǵN+1㣬ɾNͿˡ + *+ * + * @param head + * @param n + * @return + */ + public ListNode removeNthFromEnd(ListNode head, int n) { + ListNode pa = head; + ListNode pb = head; + + // ҵn + for (int i = 0; i < n && pa != null; i++) { + pa = pa.next; + } + + + // ˵Ҫɾһڵ + if (pa == null) { + head = head.next; + return head; + } + + // pbpan-1 + // pa.nextΪnullpbڵn+1λ + while (pa.next != null) { + pa = pa.next; + pb = pb.next; + } + + pb.next = pb.next.next; + + return head; + } +} diff --git a/[0020][Valid Parentheses]/[0020][Valid Parentheses].iml b/[0020][Valid Parentheses]/[0020][Valid Parentheses].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0020][Valid Parentheses]/[0020][Valid Parentheses].iml @@ -0,0 +1,13 @@ + +
+ * ԭ
+ * Given a string containing just the characters (, ), {, }, [ and ],
+ * determine if the input string is valid.
+ * The brackets must close in the correct order, () and ()[]{} are all valid
+ * but (] and ([)] are not.
+ *
+ * Ŀ
+ * һֻ(, ), {, }, [ ͡]ַ֤ǷЧġ
+ * űԣҪȷ˳
+ *
+ * ˼·
+ * һջŴдžջžջԪؿǷһţ
+ * ɾ͵Ҵһţƥֱӷؽ
+ *
+ *
+ * @param s
+ * @return
+ */
+ public boolean isValid(String s) {
+ Deque
+ * ԭ
+ * Given a string containing just the characters (, ), {, }, [ and ],
+ * determine if the input string is valid.
+ * The brackets must close in the correct order, () and ()[]{} are all valid
+ * but (] and ([)] are not.
+ *
+ * Ŀ
+ * һֻ(, ), {, }, [ ͡]ַ֤ǷЧġ
+ * űԣҪȷ˳
+ *
+ * ˼·
+ * һջŴдžջžջԪؿǷһţ
+ * ɾ͵Ҵһţƥֱӷؽ
+ *
+ *
+ * @param s
+ * @return
+ */
+ public boolean isValid(String s) {
+ Deque+ * ԭ + * Merge two sorted linked lists and return it as a new list. + * The new list should be made by splicing together the nodes of the first two lists. + * + * Ŀ + * ϲһµбµĽԭȵɣ + * ҲDzܺϲܰ´Ľ㡣 + * + * ˼· + * ʹͷrootиһͷ㣬ʹָͷ㣬 + * СĽֵĽժӵrootĩβͬʱժͷƶһ㣬 + * һֱԭһΪգٽʣµĽӵrootĩβ + * rootһ㣬Ϊµͷ + *+ * + * @param l1 + * @param l2 + * @return + */ + public ListNode mergeTwoLists(ListNode l1, ListNode l2) { + + // һͷ㣬Ҫɾ + ListNode head = new ListNode(0); + ListNode tail = head; + + while (l1 != null && l2 != null) { + if (l1.val <= l2.val) { + tail.next = l1; + l1 = l1.next; + } else { + tail.next = l2; + l2 = l2.next; + } + + // ƶµβ + tail = tail.next; + } + + tail.next = (l1 != null ? l1 : l2); + + // headһڵǵһݽ + return head.next; + } +} diff --git a/[0022][Generate Parentheses]/[0022][Generate Parentheses].iml b/[0022][Generate Parentheses]/[0022][Generate Parentheses].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0022][Generate Parentheses]/[0022][Generate Parentheses].iml @@ -0,0 +1,13 @@ + +
+ * Given n pairs of parentheses, write a function to generate all combinations + * of well-formed parentheses. + * + * For example, given n = 3, a solution set is: + * "((()))", "(()())", "(())()", "()(())", "()()()" + * + * Ŀ⣺ + * nţȷ + * + * ˼· + * õݹ + *+ * + * @param n + * @return + */ + public List
+ * Merge k sorted linked lists and return it as one sorted list. + * Analyze and describe its complexity. + * + * Ŀ⣺ + * ϲkźõĵĵ + * + * ˼· + * ʹһСвȽkĵһѣȡеСأΪСԪأ + * ԪصһѣȡСģβֱΪ + *+ * + * @param lists + * @return + */ + public ListNode mergeKLists(ListNode[] lists) { + + // ΪջûԪ + if (lists == null || lists.length < 1) { + return null; + } + + // ֻһԪ + if (lists.length == 1) { + return lists[0]; + } + + // һСѣʹһڲΪȽ + PriorityQueue
+ * Merge k sorted linked lists and return it as one sorted list. + * Analyze and describe its complexity. + * + * Ŀ⣺ + * ϲkźõĵĵ + * + * ˼· + * ʹһСвȽkĵһѣȡеСأΪСԪأ + * ԪصһѣȡСģβֱΪ + *+ * + * @param lists + * @return + */ + public ListNode mergeKLists(ListNode[] lists) { + + // ΪջûԪ + if (lists == null || lists.length < 1) { + return null; + } + + // ֻһԪ + if (lists.length == 1) { + return lists[0]; + } + + // һСѣʹһڲΪȽ + MinHeap
+ * ԭ + * Given a linked list, swap every two adjacent nodes and return its head. + * For example, + * Given 1->2->3->4, you should return the list as 2->1->4->3. + * Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. + * + * Ŀ + * һɶԽڵĽ㡣㷨Ӧռ䣬ܸĽֵֻܽ㡣 + * + * ˼· + * ʹһͷrootҪнÿλýн + * ҰѽĽӵrootϣֱеĽ㶼ꡣ + *+ * + * @param head + * @return + */ + public ListNode swapPairs(ListNode head) { + // ͷ + ListNode node = new ListNode(0); + node.next = head; + + // pָµβ㣬pָõĽ㣬ӵͷΪѾ + ListNode p = node; + ListNode tmp; + + // ÿв + while (p.next != null && p.next.next != null) { + // ¼һҪдλ + tmp = p.next.next; + // 㽻 + p.next.next = tmp.next; + tmp.next = p.next; + p.next = tmp; + // ָµβ + p = tmp.next; + } + + head = node.next; + node.next = null; + + return head; + } +} diff --git a/[0025][Reverse Nodes In K-Group]/[0025][Reverse Nodes In K-Group].iml b/[0025][Reverse Nodes In K-Group]/[0025][Reverse Nodes In K-Group].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0025][Reverse Nodes In K-Group]/[0025][Reverse Nodes In K-Group].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Given a sorted array, remove the duplicates in place such that each element + * appear only once and return the new length. + * Do not allocate extra space for another array, you must do this in place + * with constant memory. + * For example, + * Given input array nums = [1,1,2], + * Your function should return length = 2, with the first two elements of nums + * being 1 and 2 respectively. It doesnt matter what you leave beyond the new length. + * + * Ŀ + * һ飬еظԪȥֻͬһҷµԪظ + * Ҫһµڳʱڽ + * + * ˼· + * ӵڶԪؿʼΪǰԪأǰԪǰһԪͬɾԪأ + * ͬͽƶȷλãԪ˸ + *+ * + * @param A + * @return + */ + public int removeDuplicates(int[] A) { + + if (A == null) { + return 0; + } + + if (A.length < 2) { + return A.length; + } + + // ָһλ + int index = 1; + for (int i = 1; i < A.length; i++) { + // index - 1ʾǰһźõλ + if (A[index - 1] < A[i]) { + A[index] = A[i]; + index++; + } + } + + return index; + } +} diff --git a/[0026][Remove Duplicates from Sorted Array]/src/Solution2.java b/[0026][Remove Duplicates from Sorted Array]/src/Solution2.java new file mode 100644 index 0000000..fc801b2 --- /dev/null +++ b/[0026][Remove Duplicates from Sorted Array]/src/Solution2.java @@ -0,0 +1,57 @@ +/** + * Author: + * Date: 2015-08-21 + * Time: 16:40 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + /** + *
+ * ԭ + * Given a sorted array, remove the duplicates in place such that each element + * appear only once and return the new length. + * Do not allocate extra space for another array, you must do this in place + * with constant memory. + * For example, + * Given input array nums = [1,1,2], + * Your function should return length = 2, with the first two elements of nums + * being 1 and 2 respectively. It doesnt matter what you leave beyond the new length. + * + * Ŀ + * һ飬еظԪȥֻͬһҷµԪظ + * Ҫһµڳʱڽ + * + * ˼· + * ӵڶԪؿʼΪǰԪأǰԪǰһԪͬɾԪأ + * ͬͽƶȷλãԪ˸ + *+ * + * @param A + * @return + */ + public int removeDuplicates(int[] A) { + + if (A.length == 0) { + return 0; + } + + int index = 0;//[0,index]ֻ¼гֵİСΨһһѾź + int next = 1; + + // 㷨˼룺index֮ıA[index]ҵƶA[index+1] + // indexƶһλãnextƶһλãұA[index] + + while (next < A.length) { + while (next < A.length && A[index] == A[next]) { // Ҳ + next++; + } + + if (next < A.length) { + index++; + A[index] = A[next]; + next++; + } + } + return index + 1; + } +} diff --git a/[0027][Remove Element]/[0027][Remove Element].iml b/[0027][Remove Element]/[0027][Remove Element].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0027][Remove Element]/[0027][Remove Element].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Given an array and a value, remove all instances of that value in place and return the new length. + * The order of elements can be changed. It doesnt matter what you leave beyond the new length. + * + * Ŀ + * һһֵɾֵȵԪأҷµijȡ + * + * ˼· + * ֵΪelemԪصλãjұֵΪelemԪصλãȻjλõֵƶiλá + *+ * + * @param nums + * @param val + * @return + */ + public int removeElement(int[] nums, int val) { + int exchange = 0; // ¼ĴҲͳelemԪֵȵĸ + + // 㷨˼룺iֵΪelemԪصλãjұֵΪelemԪصλã + // ȡȺóΪ1Խ + for (int i = 0, j = nums.length - 1; i <= j; i++) { + // ҵҪԪ + if (nums[i] == val) { + exchange++; + + // 濪ʼǰҵһelemԪ + while (j > i && nums[j] == val) { + // ֵΪelemԪ˵Ҫǽ̿ʡȥ + exchange++; + j--; + } + + // 1ΪelemԪصλãjλõԪطŵiλ + // 2ûҵelemԪصλãiԪֵeʱj=i + // jеֵiûйϵ + nums[i] = nums[j]; + j--; // jѾʹԻҪǰƶһµλ + } + } + + return nums.length - exchange; + } +} diff --git a/[0027][Remove Element]/src/Solution2.java b/[0027][Remove Element]/src/Solution2.java new file mode 100644 index 0000000..e87040c --- /dev/null +++ b/[0027][Remove Element]/src/Solution2.java @@ -0,0 +1,40 @@ +/** + * Author: + * Date: 2015-08-21 + * Time: 16:43 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + /** + *
+ * ԭ + * Given an array and a value, remove all instances of that value in place and return the new length. + * The order of elements can be changed. It doesnt matter what you leave beyond the new length. + * + * Ŀ + * һһֵɾֵȵԪأҷµijȡ + * + * ˼· + * + *+ * + * @param nums + * @param val + * @return + */ + public int removeElement(int[] nums, int val) { + + // [0, ..., index - 1]ʾѾųvalֵ飬indexʾ֮ԷԪصλã + // Ҳʾij + int index = 0; + for (int i = 0; i < nums.length; i++) { + // Ⱦƶ + if (nums[i] != val) { + nums[index] = nums[i]; + ++index; + } + } + + return index; + } +} diff --git a/[0028][Implement-strStr()]/[0028][Implement-strStr()].iml b/[0028][Implement-strStr()]/[0028][Implement-strStr()].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0028][Implement-strStr()]/[0028][Implement-strStr()].iml @@ -0,0 +1,13 @@ + +
+ * You are given a string, s, and a list of words, words, + * that are all of the same length. Find all starting indices + * of substring(s) in s that is a concatenation of each word + * in words exactly once and without any intervening characters. + * + * For example, given: + * s: "barfoothefoobarman" + * words: ["foo", "bar"] + * You should return the indices: [0,9]. + * (order does not matter). + *+ * + * @param s + * @param words + * @return + */ + public List
+ * Implement next permutation, which rearranges numbers into the lexicographically next + * greater permutation of numbers. + * + * If such arrangement is not possible, it must rearrange it as the lowest possible order + * (ie, sorted in ascending order). + * + * The replacement must be in-place and use only constant extra memory. + * + * Here are some examples. Inputs are in the left-hand column and its corresponding outputs + * are in the right-hand column. + * + * 1,2,3 → 1,3,2 + * 3,2,1 → 1,2,3 + * 1,1,5 → 1,5,1 + * + * 1.首先从最尾端开始往前寻找一个元素,满足nums[i] < nums[i+1]。 + * 如果没有找到即i < 0, 说明整个数组是递增的,已经到了最大值,此时只要反转数组即可 + * 如果i >= 0 + * + * 2.再从最尾端开始往前检验,找出第一个大于nums[i]的元素nums[j] 并且,j >= i + * 将nums[i],nums[j]元素对调(swap)。 + * + * 3.再将i位置之后的所有元素颠倒(reverse)排序。 + *+ * + * @param nums + */ + public void nextPermutation(int[] nums) { + int i = nums.length - 2; + // 从后向前查找第一个元素i,并且使用nums[i] >= nums[i+1]不成立。 + while (i >= 0 && nums[i] >= nums[i + 1]) { + i--; + } + + // 此时nums[i+1, ..., last]是递增的 + + + if (i >= 0) { + int j = nums.length - 1; + // 从右开始向左找,找第一个大于等num[i]的元素 + // 如果找到i==j,说明没有找到 + while (j > i && nums[j] <= nums[i]) { + j--; + } + + // 交换两者之间的值,当j == i时,交换也没有问题 + swap(nums, i, j); + + // 将nums[i+1, last]进行反转 + reverse(nums, i + 1); + } else { + // 说明整个序列是非递增的 + // 对子数组进行翻转 + reverse(nums, 0); + } + + + } + + private void reverse(int[] nums, int start) { + int i = start; + int j = nums.length - 1; + while (i < j) { + swap(nums, i, j); + i++; + j--; + } + } + + private void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } +} diff --git a/[0032][Longest Valid Parentheses]/[0032][Longest Valid Parentheses].iml b/[0032][Longest Valid Parentheses]/[0032][Longest Valid Parentheses].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0032][Longest Valid Parentheses]/[0032][Longest Valid Parentheses].iml @@ -0,0 +1,13 @@ + +
+ * Given a string containing just the characters '(' and ')',
+ * find the length of the longest valid (well-formed) parentheses substring.
+ *
+ * For "(()", the longest valid parentheses substring is "()", which has length = 2.
+ * Another example is ")()())", where the longest valid parentheses substring is "()()",
+ * which has length = 4.
+ *
+ * Ŀ⣺
+ * һַֻСźţĺϷСŵĿ
+ *
+ * ˼·
+ * ʹջʵ
+ *
+ *
+ * @param s
+ * @return
+ */
+ public int longestValidParentheses(String s) {
+ // ڼ¼ƥźŵλ
+ Stack
+ * Given a string containing just the characters '(' and ')',
+ * find the length of the longest valid (well-formed) parentheses substring.
+ *
+ * For "(()", the longest valid parentheses substring is "()", which has length = 2.
+ * Another example is ")()())", where the longest valid parentheses substring is "()()",
+ * which has length = 4.
+ *
+ * Ŀ⣺
+ * һַֻСźţĺϷСŵĿ
+ *
+ * ˼·
+ * ʹջʵ
+ *
+ *
+ * @param s
+ * @return
+ */
+ public int longestValidParentheses(String s) {
+ int result = 0;
+ int start = 0;
+ // ¼ŵλ
+ Deque+ * Suppose a sorted array is rotated at some pivot unknown to you beforehand. + * (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + * You are given a target value to search. If found in the array return its + * index, otherwise return -1. + * + * You may assume no duplicate exists in the array. + * + * 题目大意: + * 假设一个排序的数组以一个未知的的枢轴旋转。(即,0 1 2 4 5 6 7可能成为4 5 6 7 0 1 2)。 + * 给定一个目标值,在数组中搜寻。如果存在就返回其对应的下标,否则返回-1。 + * 假设数组中不存在重复值。 + * + * 解题思路: + * 找旋转数组最小值的位置minIndex(见LeetCode第153题 ),如果minIndex不为,说明其在分隔成 + * 两个有序数组,并且前一个中的第一个元素都大于后一个数组的每一个元素,判断target中哪一个数组区 + * 间中使用二叉搜索算法查找,如果minIndex=0,说明全局有序,对整个数组进行二叉查找,返回查找结果 + *+ * + * @param nums + * @param target + * @return + */ + public int search(int[] nums, int target) { + if (nums == null || nums.length == 0) { + return -1; + } + + int left = 0; + int right = nums.length - 1; + int mid; + while (left <= right) { + mid = left + (right - left) / 2; + if (nums[mid] == target) { + return mid; + } + + // 说明first,mid都在同一个递增子序列中 + if (nums[left] <= nums[mid]) { + if (nums[left] <= target && target < nums[mid]) { + right = mid - 1; + } else { + left = mid + 1; + } + } else { + if (nums[mid] < target && target <= nums[right]) { + left = mid + 1; + } else { + right = mid - 1; + } + } + } + + return -1; + } + +} diff --git a/[0034][Search For A Range]/[0034][Search For A Range].iml b/[0034][Search For A Range]/[0034][Search For A Range].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0034][Search For A Range]/[0034][Search For A Range].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. + * The Sudoku board could be partially filled, where empty cells are filled + * with the character '.'. + * + * A partially filled sudoku which is valid. + * Note: + * A valid Sudoku board (partially filled) is not necessarily solvable. + * Only the filled cells need to be validated. + * + * Ŀ + * ֤һǷϷ̵֤ӶӦҳ档 + * Dzģյλʹõ档 + * ע⣺Ϸ̲һҪĿɽģֻҪҪͿԡ + * + * ˼· + * ȶнм飬ٶнм飬飳*ķ + *+ * + * @param board + * @return + */ + public boolean isValidSudoku(char[][] board) { + // .ASCIIֵ460ASCIIֵ48/ASCIIֵ47 + int number = board[0].length; + int[] record = new int[10 + 2]; //.9ֵݵλ[2, 10] + boolean isValid; + reset(record); + + // нм + for (int i = 0; i < number; i++) { + for (int j = 0; j < number; j++) { + record[board[i][j] - '.']++; + } + + // Ǽʧ + if (!check(record)) { + return false; + } + // ɹ + else { + reset(record); + } + } + + // нм + for (int i = 0; i < number; i++) { + for (int j = 0; j < number; j++) { + record[board[j][i] - '.']++; + } + + if (!check(record)) { // Ǽʧ + return false; + } else { // ɹ + reset(record); + } + } + + // 3*3 + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + + for (int k = i * 3; k < (i + 1) * 3; k++) { + for (int l = j * 3; l < (j + 1) * 3; l++) { + record[board[k][l] - '.']++; + } + } + + if (!check(record)) { // Ǽʧ + return false; + } else { // ɹ + reset(record); + } + } + } + return true; + } + + private void reset(int[] a) { + Arrays.fill(a, 0); + } + + /** + * һУһУ3*3ķǷϷ1-9еָ1ͲϷ + * + * @param a ֤ + * @return ؽ + */ + private boolean check(int[] a) { + for (int i = 2; i < a.length; i++) { + if (a[i] > 1) { + return false; + } + } + return true; + } +} diff --git "a/\343\200\220036\343\200\221\343\200\220Valid Sudoku\343\200\221/src/sodoku.png" b/[0036][Valid Sudoku]/src/sodoku.png similarity index 100% rename from "\343\200\220036\343\200\221\343\200\220Valid Sudoku\343\200\221/src/sodoku.png" rename to [0036][Valid Sudoku]/src/sodoku.png diff --git a/[0037][Sudoku Solver]/[0037][Sudoku Solver].iml b/[0037][Sudoku Solver]/[0037][Sudoku Solver].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0037][Sudoku Solver]/[0037][Sudoku Solver].iml @@ -0,0 +1,13 @@ + +
+ * Given an unsorted integer array, find the smallest missing positive integer. + * + * Example 1: + * + * Input: [1,2,0] + * Output: 3 + * Example 2: + * + * Input: [3,4,-1,1] + * Output: 2 + * Example 3: + * + * Input: [7,8,9,11,12] + * Output: 1 + * + * 本质上是桶排序(bucket sort),每当A[i]!= i+1 的时候,将A[i] 与A[A[i]-1] 交换, + * 直到无法交换为止,终止条件是A[i]== A[A[i]-1]。 + *+ * + * @param nums + * @return + */ + public int firstMissingPositive(int[] nums) { + int n = nums.length; + for (int i = 0; i < n; i++) { + // nums[i] == nums[nums[i] - 1] 说明出现了两个同样的元素或者两个是同一个元素 + while (nums[i] > 0 && nums[i] <= n && nums[i] != nums[nums[i] - 1]) { + swap(nums, i, nums[i] - 1); + } + } + for (int i = 0; i < n; i++) { + if (nums[i] != i + 1) { + return i + 1; + } + } + + return n + 1; + } + + private void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } +} diff --git a/[0042][Trapping Rain Water]/[0042][Trapping Rain Water].iml b/[0042][Trapping Rain Water]/[0042][Trapping Rain Water].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0042][Trapping Rain Water]/[0042][Trapping Rain Water].iml @@ -0,0 +1,13 @@ + +
+ * 对于每个柱子,找到其左右两边最高的柱子,该柱子能容纳的面积就是min(max_left,max_right) - height。所以, + * 1. 从左往右扫描一遍,对于每个柱子,求取左边最大值; + * 2. 从右往左扫描一遍,对于每个柱子,求最大右值; + * 3. 再扫描一遍,把每个柱子的面积并累加。 + *+ * + * @param height + * @return + */ + public int trap1(int[] height) { + int ans = 0; + int size = height.length; + for (int i = 1; i < size - 1; i++) { + int maxLeft = 0; + int maxRight = 0; + // 找此柱左边最高的柱子 + for (int j = i - 1; j >= 0; j--) { + maxLeft = Math.max(maxLeft, height[j]); + } + // 找此柱子右边最高的柱子 + for (int j = i + 2; j < size; j++) { + maxRight = Math.max(maxRight, height[j]); + } + + // Math.min(maxLeft, maxRight) - height[i] 此柱子可以容纳的水 + ans += Math.min(maxLeft, maxRight) - height[i]; + } + return ans; + } + + int trap2(int[] height) { + if (height == null || height.length == 0) { + return 0; + } + int ans = 0; + int size = height.length; + int[] leftMax = new int[size]; + int[] rightMax = new int[size]; + + + // 对于每个柱子求左右最大值,并保存起来 + for (int i = 1; i < size - 1; i++) { + leftMax[i] = Math.max(height[i], leftMax[i - 1]); + rightMax[size - i - 1] = Math.max(height[size - i], rightMax[size - i]); + } + + + for (int i = 1; i < size - 1; i++) { + ans += Math.min(leftMax[i], rightMax[i]) - height[i]; + } + return ans; + } + + /** + *
+ * 用一个栈辅助,小于栈顶的元素压入,大于等于栈顶就把栈里所有小于或 + * 等于当前值的元素全部出栈处理掉,计算面积,最后把当前元素入栈 + * + * + * + * = + * = === = + * = == ======= + * ============= + * 0123456789012 + *+ * + * @param height + * @return + */ + int trap3(int[] height) { + int ans = 0, current = 0; + Deque
+ * 1. 扫描一遍,找到最高的柱子,这个柱子将数组分为两半; + * 2. 处理左边一半; + * 3. 处理右边一半。 + *+ * + * @param height + * @return + */ + int trap4(int[] height) { + int left = 0; + int right = height.length - 1; + int ans = 0; + int leftMax = 0; + int rightMax = 0; + + while (left < right) { + if (height[left] < height[right]) { + if (height[left] >= leftMax) { + leftMax = height[left]; + } else { + ans += leftMax - height[left]; + } + + ++left; + } else { + if (height[right] >= rightMax) { + rightMax = height[right]; + } else { + ans += rightMax - height[right]; + } + + --right; + } + } + return ans; + } +} diff --git a/[0043][Multiply Strings]/[0043][Multiply Strings].iml b/[0043][Multiply Strings]/[0043][Multiply Strings].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0043][Multiply Strings]/[0043][Multiply Strings].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Given a collection of numbers, return all possible permutations. + * For example, + * [1,2,3] have the following permutations: + * [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. + * + * Ŀ + * һ飬С + * + * ˼· + * ʹ÷η⡣ + *+ * + * @param num + * @return + */ + public List
+ * Given an integer array nums, find the contiguous subarray (containing at least one number)
+ * which has the largest sum and return its sum.
+ *
+ * Example:
+ *
+ * Input: [-2,1,-3,4,-1,2,1,-5,4],
+ * Output: 6
+ * Explanation: [4,-1,2,1] has the largest sum = 6.
+ * Follow up:
+ *
+ * If you have figured out the O(n) solution, try coding another solution using the divide and
+ * conquer approach, which is more subtle.
+ *
+ * Ŀ⣺
+ * ĺ
+ * ˼·
+ * ̬滮⣬֪ǰkԪصкΪmaxSubѾ¼ˣԼһʱsum
+ * ˵k+1Ԫأƣk+1Ԫ֮ǰĺС0ģ
+ * ôk+1ԪشӶȥûйģԿsum 0
+ *
+ * Ǵͷβʱһмѡأֻ
+ * ѡ1֮ǰSubArray2. ԼһSubArrayʲôʱأ
+ * ֮ǰSubArray ʹ0 ĻΪԺйġ
+ * ѡ֮ǰSubArray
+ * ֮ǰSubArray Ϊ0 С0 ĻΪԺûйף
+ * кģС0 ʱѡֿʼһSubArray
+ * ״̬Ϊf[j]ʾS[j] βкͣ״̬תƷ£
+ * f[j] = max {f[j - 1] + S[j]; S[j]} ; 1 <= j <= n
+ * target = max {f[j]}; 1 <= j <= n
+ * £
+ * һS[j] ǰijЩһУкΪf[j - 1] + S[j]
+ * S[j] ֳΪһΣнһS[j]кΪS[j]
+ *
+ *
+ *
+ * @param nums
+ * @return
+ */
+ public int maxSubArray(int[] nums) {
+ // У
+ if (nums == null || nums.length < 1) {
+ throw new IllegalArgumentException();
+ }
+
+ int max = Integer.MIN_VALUE;
+ int curSum = 0;
+
+ for (int i : nums) {
+ // ǰС0ͽǰֵcurSum
+ if (curSum <= 0) {
+ curSum = i;
+ }
+ // ۼ
+ else {
+ curSum += i;
+ }
+
+ // ϴֵ
+ if (max < curSum) {
+ max = curSum;
+ }
+ }
+
+ return max;
+ }
+}
diff --git a/[0054][Spiral Matrix]/[0054][Spiral Matrix].iml b/[0054][Spiral Matrix]/[0054][Spiral Matrix].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0054][Spiral Matrix]/[0054][Spiral Matrix].iml
@@ -0,0 +1,13 @@
+
++ * Given an array of non-negative integers, you are initially positioned at the + * first index of the array. + * + * Each element in the array represents your maximum jump length at that position. + * + * Determine if you are able to reach the last index. + * + * For example: + * A = [2,3,1,1,4], return true. + * A = [3,2,1,0,4], return false. + * + * 题目大意: + * 给定的非负整数的数组,则最初定位在数组的第一个位置。数组中的每个元素都代表你的最大跳跃长度在那个位置。 + * 决定你是否能到达最后一个索引。 + * + *+ * + * @param nums + * @return + */ + public boolean canJump(int[] nums) { + return canJump2(nums); + } + + public boolean canJump1(int[] nums) { + if (nums == null || nums.length < 2) { + return true; + } + + // 最后可以移动的位置 + int lastPos = 0; + + // 处理每一个位置 + for (int i = 0; i < nums.length; i++) { + // i不能比lastPos大,否则说明不能走到i,走不到i也就不能走到最后 + // 如果在i位置可以移动的距离比已经记录到的最大距离还要大,那么更新最大的移动距离 + if (i <= lastPos && i + nums[i] > lastPos) { + lastPos = i + nums[i]; + } else if (i > lastPos) { + return false; + } + } + + // 最后的位置必然可以达到最后 + return lastPos >= nums.length - 1; + } + + /** + * 逆向,从最高层下楼梯,一层一层下降,看最后能不能下降到第0 层。 + * + * @param nums + * @return + */ + public boolean canJump2(int[] nums) { + int lastPos = nums.length - 1; + for (int i = nums.length - 1; i >= 0; i--) { + if (i + nums[i] >= lastPos) { + lastPos = i; + } + } + return lastPos == 0; + } +} diff --git a/[0056][Merge Intervals]/[0056][Merge Intervals].iml b/[0056][Merge Intervals]/[0056][Merge Intervals].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0056][Merge Intervals]/[0056][Merge Intervals].iml @@ -0,0 +1,13 @@ + +
+ * Given a collection of intervals, merge all overlapping intervals. + * + * For example, + * Given [1,3],[2,6],[8,10],[15,18], + * return [1,6],[8,10],[15,18]. + * + * Ŀ⣬ + * һ伯ϣϲص + * + * ˼· + * ȶʼһһкϲ + *+ * + * @param intervals + * @return + */ + public List
+ * Given a set of non-overlapping intervals, insert a new interval into the intervals + * (merge if necessary). + * + * You may assume that the intervals were initially sorted according to their start times. + * + * Example 1: + * Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9]. + * + * Example 2: + * Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16]. + * + * This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10]. + * + * Ŀ⣺ + * һϵзǸǵ䣬һµ䣬бҪʱϲ + * 俪ʼʼʱкϲ + * + * ˼· + * ԭȲСͲص²䣬 + * Сԭ䣬Ȳ䣬Ӵ + *+ * + * @param intervals + * @param newInterval + * @return + */ + public List
+ * 利用康托编码的思路,假设有n 个不重复的元素,第k 个排列是a1; a2; a3; :::; an,那么a1 是 + * 哪一个位置呢? + * 我们把a1 去掉,那么剩下的排列为a2; a3; :::; an, 共计n-1 个元素,n-1 个元素共有(n-1)! + * 个排列,于是就可以知道a1 = k/(n - 1)!。 + * 同理,a2; a3; :::; an 的值推导如下: + * k2 = k%(n - 1)! + * a2 = k2/(n - 2)! + * ... + * k(n-1) = k(n-2)%2! + * a(n-1) = k(n-1)/1! + * an = 0 + *+ * + * @param n + * @param k + * @return + */ + public String getPermutation(int n, int k) { + + StringBuilder sb = new StringBuilder(); + List
+ * ԭ + * A robot is located at the top-left corner of a m x n grid + * (marked Start in the diagram below). + * The robot can only move either down or right at any point in time. + * The robot is trying to reach the bottom-right corner of the grid + * (marked Finish in the diagram below). + * How many possible unique paths are there? + * + * Above is a 3 x 7 grid. How many possible unique paths are there? + * Note: m and n will be at most 100. + * + * Ŀ + * һһm*nķϽǡ + * ֻһһҪ½ǵķ + * һжΨһ· + * ע⣺ͣ100 + * + * ˼· + * ͵Ķ̬滮⣬ʹö̬滮ķ⡣ + * һm*nA + * AеԪС + * 1x=0y=0ʱA[x][y] = 1 + * 2x>=1y>=1ʱA[x][y] = A[x-1][y]+A[x][y-1] + * 3ĽA[m-1][n-1] + *+ * + * @param m + * @param n + * @return + */ + public int uniquePaths(int m, int n) { + int[][] result = new int[m][n]; + + // һеĽ + for (int i = 0; i < m; i++) { + result[i][0] = 1; + } + + // һеĽ + for (int i = 1; i < n; i++) { + result[0][i] = 1; + } + + // λõĽ + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + result[i][j] = result[i - 1][j] + result[i][j - 1]; + } + } + + // Ľ + return result[m - 1][n - 1]; + } +} diff --git a/[0063][Unique Paths II]/[0063][Unique Paths II].iml b/[0063][Unique Paths II]/[0063][Unique Paths II].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0063][Unique Paths II]/[0063][Unique Paths II].iml @@ -0,0 +1,13 @@ + +
+ * Validate if a given string can be interpreted as a decimal number. + * + * Some examples: + * "0" => true + * " 0.1 " => true + * "abc" => false + * "1 a" => false + * "2e10" => true + * " -90e3 " => true + * " 1e" => false + * "e3" => false + * " 6e-1" => true + * " 99e2.5 " => false + * "53.5e93" => true + * " --6 " => false + * "-+3" => false + * "95a54e53" => false + * + * Note: It is intended for the problem statement to be ambiguous. You should gather all requirements + * up front before implementing one. However, here is a list of characters that can be in a valid decimal number: + * + * Numbers 0-9 + * Exponent - "e" + * Positive/negative sign - "+"/"-" + * Decimal point - "." + * Of course, the context of these characters also matters in the input. + *+ * + * @param s + * @return + */ + public boolean isNumber(String s) { + int state = 0; + for (int i = 0; i < s.length(); i++) { + InputType inputType = InputType.INVALID; + if (Character.isSpaceChar(s.charAt(i))) { + inputType = InputType.SPACE; + } else if (s.charAt(i) == '+' || s.charAt(i) == '-') { + inputType = InputType.SIGN; + } else if (Character.isDigit(s.charAt(i))) { + inputType = InputType.DIGIT; + } else if (s.charAt(i) == '.') { + inputType = InputType.DOT; + } else if (s.charAt(i) == 'e' || s.charAt(i) == 'E') { + inputType = InputType.EXPONENT; + } + // Get next state from current state and input symbol + state = TRANSITION_TABLE[state][inputType.ordinal()]; + + // Invalid input + if (state == -1) { + return false; + } + } + // If the current state belongs to one of the accepting (final) states, + // then the number is valid + return state == 1 || state == 4 || state == 7 || state == 8; + } + + private boolean isDigit(char charAt) { + return charAt >= '0' && charAt <= '9'; + } + + private boolean isSpace(char charAt) { + return charAt == ' '; + } +} diff --git a/[0066][Plus One]/[0066][Plus One].iml b/[0066][Plus One]/[0066][Plus One].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0066][Plus One]/[0066][Plus One].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Given a non-negative number represented as an array of digits, plus one to the number. + * The digits are stored such that the most significant digit is at the head of the list. + * + * Ŀ + * һʾһмһ + * ÿһλ洢һλϡ±ӴСʾλӵλλ + * + * ˼· + * ֱ⣬һλ־carryֵΪ1ʾ1λʼtmp = a[x] + carry + * a[x] = tmp%10carry = tmp/10carryΪ0һλٽвֱеλcarray + * Ϊ0˳carrayΪ0˵Ҫչһλ + *+ * + * @param digits + * @return + */ + public int[] plusOne(int[] digits) { + + // λ־һλĽλ־ + int carry = 1; + int tmp; + for (int i = digits.length - 1; i >= 0; i--) { + tmp = digits[i]; + // 㵱ǰλֵ + digits[i] = (tmp + carry) % 10; + // µĽλ + carry = (tmp + carry) / 10; + + // ûнλ˾Ϳ˳ + if (carry == 0) { + break; + } + } + + // һλ + if (carry == 1) { + int[] result = new int[digits.length + 1]; + System.arraycopy(digits, 0, result, 1, digits.length); + result[0] = carry; + return result; + } else { + return digits; + } + } +} diff --git a/[0067][Add Binary]/[0067][Add Binary].iml b/[0067][Add Binary]/[0067][Add Binary].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0067][Add Binary]/[0067][Add Binary].iml @@ -0,0 +1,13 @@ + +
+ * Implement int sqrt(int x). + * + * Compute and return the square root of x, where x is guaranteed to be a non-negative integer. + * + * Since the return type is an integer, the decimal digits are truncated and only the integer + * part of the result is returned. + * + * Example 1: + * + * Input: 4 + * Output: 2 + * Example 2: + * + * Input: 8 + * Output: 2 + * Explanation: The square root of 8 is 2.82842..., and since + * the decimal part is truncated, 2 is returned. + *+ * + * @param x + * @return + */ + public int mySqrt(int x) { + return mySqrt2(x); + } + + /** + * 使用二分法 + *
+ * 思路:要实现一个sqrt函数,可以使用二分法,首先确定一个范围[begin, end],这个范围的中间数mid, + * 看mid的平方是否等于x,如果相等,则返回mid,如果不等则缩小[begin,end]的范围,为原来的一半。这 + * 里的初始范围可以是[1, x],也可以是更精确一些的[1, (x/2) + 1]。(因 (x/2) + 1 的平方等于 + * x+1+(x^2/4),它一定大于x,所以,x的平方根一定在[1, (x/2) + 1]范围内) + * + *+ * + * @param x + * @return + */ + public int mySqrt1(int x) { + if (x == 0) { + return 0; + } + int left = 1; + int right = x; + while (true) { + int mid = left + (right - left) / 2; + if (mid > x / mid) { + right = mid - 1; + } else { + if (mid + 1 > x / (mid + 1)) { + return mid; + } + left = mid + 1; + } + } + } + + /** + * 使用牛顿法 + *
+ * x^2 = a的解,也就是函数f(x) = x^2 – a与x轴的交点。可以在x轴上先任选一点x0,则点(x0, f(x0)) + * 在f(x)上的切线,与x轴的交点为x1,它们满足切线的方程:f(x0)=(x0-x1)f’(x0),可得x1更接近最终的 + * 结果,解方程得到: + * 切线方程:y = 2x0(x - x0) + x0^2 - a,令y=0 -> x = (x0 + (a/x0))/2,即为x1的值 + * + * x1 = (x0 + (a/x0))/2。以x1为新的x0,按照切线的方法依次迭代下去,最终求得符合精确度要求的结果值。 + *+ * + * @param x + * @return + */ + public int mySqrt2(int x) { + long r = x; + while (r * r > x) { + r = (r + x / r) / 2; + } + return (int) r; + } +} diff --git a/[0070][Climbing Stairs]/[0070][Climbing Stairs].iml b/[0070][Climbing Stairs]/[0070][Climbing Stairs].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0070][Climbing Stairs]/[0070][Climbing Stairs].iml @@ -0,0 +1,13 @@ + +
+ * f(n) ʾn ¥ݵIJͬΪn ¥ݣѡ + * - ӵn - 1 ǰ1 + * - ӵn - 1 ǰ2 + * ˣf(n) = f(n - 1) + f(n - 2) + *+ * + * @param n + * @return + */ + public int climbStairs(int n) { + + int result = 0; + + // ֻһ + if (n == 1) { + result = 1; + } + // ֻ + else if (n == 2) { + result = 2; + } + // ¥ݽ2 + else if (n > 2) { + // еĽⷨ + int[] ways = new int[n]; + + ways[0] = 1; + ways[1] = 2; + + for (int i = 2; i < ways.length; i++) { + ways[i] = ways[i - 1] + ways[i - 2]; + } + + result = ways[ways.length - 1]; + } + + return result; + } +} diff --git a/[0071][Simplify Path]/[0071][Simplify Path].iml b/[0071][Simplify Path]/[0071][Simplify Path].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0071][Simplify Path]/[0071][Simplify Path].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: + * Integers in each row are sorted from left to right. + * The first integer of each row is greater than the last integer of the previous row. + * For example, + * Consider the following matrix:Given target = 3, return true. + * + * [ + * [1, 3, 5, 7], + * [10, 11, 16, 20], + * [23, 30, 34, 50] + * ] + * + * Ŀ + * һάʵһ㷨ھʵֿkھk + * ʣÿһÿһжźģÿһеĵһһеһ + * + * ˼· + * ⷨһö鿴㷨ҵڵУö㷨ڵСҵͷtruefalse + *+ * + * @param matrix + * @param target + * @return + */ + public boolean searchMatrix(int[][] matrix, int target) { + + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { + return false; + } + + int row = matrix.length; + int column = matrix[0].length; + int low = 0; + int high = row * column - 1; + int mid; + + // ҽڵ + while (low <= high) { + mid = low + (high - low) / 2; + int value = matrix[mid / column][mid % column]; + if (value == target) { + return true; + } else if (value < target) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + return false; + } +} diff --git a/[0074][Search A 2D Matrix]/src/Solution2.java b/[0074][Search A 2D Matrix]/src/Solution2.java new file mode 100644 index 0000000..0a5ed46 --- /dev/null +++ b/[0074][Search A 2D Matrix]/src/Solution2.java @@ -0,0 +1,88 @@ +/** + * Author: + * Date: 2015-08-21 + * Time: 19:36 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + /** + *
+ * ԭ + * Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: + * Integers in each row are sorted from left to right. + * The first integer of each row is greater than the last integer of the previous row. + * For example, + * Consider the following matrix:Given target = 3, return true. + * + * [ + * [1, 3, 5, 7], + * [10, 11, 16, 20], + * [23, 30, 34, 50] + * ] + * + * Ŀ + * һάʵһ㷨ھʵֿkھk + * ʣÿһÿһжźģÿһеĵһһеһ + * + * ˼· + * ⷨһö鿴㷨ҵڵУö㷨ڵСҵͷtruefalse + *+ * + * @param matrix + * @param target + * @return + */ + public boolean searchMatrix(int[][] matrix, int target) { + + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { + return false; + } + + int row = matrix.length; + int column = matrix[0].length; + int low = 0; + int high = row - 1; + int mid = 0; + + // ҽڵ + while (low <= high) { + mid = low + (high - low) / 2; + + if (target < matrix[mid][column - 1]) { + high = mid - 1; + } else if (target > matrix[mid][column - 1]) { + low = mid + 1; + } else { + return true; + } + } + + // ڵλ + int targetRow = mid; + if (matrix[mid][column - 1] < target) { + targetRow++; + } + + // Ŀг + if (targetRow >= row) { + return false; + } + + low = 0; + high = column - 1; + // ڵУҵtrueûзfalse + while (low <= high) { + mid = low + (high - low) / 2; + + if (target < matrix[targetRow][mid]) { + high = mid - 1; + } else if (target > matrix[targetRow][mid]) { + low = mid + 1; + } else { + return true; + } + } + + return false; + } +} diff --git a/[0075][Sort Colors]/[0075][Sort Colors].iml b/[0075][Sort Colors]/[0075][Sort Colors].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0075][Sort Colors]/[0075][Sort Colors].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Given an array with n objects colored red, white or blue, sort them so that objects + * of the same color are adjacent, with the colors in the order red, white and blue. + * Here, we will use the integers 0, 1, and 2 to represent the color red, white, + * and blue respectively. + * Note: + * You are not suppose to use the librarys sort function for this problem. + * + * Ŀ + * һ飬Ǻɫɫɫɫ죬ף + * ʹ012ֱ죬ף + * ע⣺ʹÿ⺯ + * + * ˼· + * һֱ012ֵĴٽ鸳ֵ + *+ * + * @param nums + */ + public void sortColors(int[] nums) { + + if (nums == null) { + return; + } + + int[] count = new int[3]; + + for (int n : nums) { + count[n]++; + } + + int start = 0; + int end = 0; + for (int i = 0; i < count.length; i++) { + if (i == 0) { + start = 0; + } else { + start += count[i - 1]; + } + end += count[i]; + for (int j = start; j < end; j++) { + nums[j] = i; + } + } + + // ϶ĸĽ +// for (int i = 0; i < count[0]; i++) { +// nums[i] = 0; +// } +// +// for (int i = count[0]; i < count[0] + count[1]; i++) { +// nums[i] = 1; +// } +// +// for (int i = count[0] + count[1]; i < nums.length; i++) { +// nums[i] = 2; +// } + } +} diff --git a/[0075][Sort Colors]/src/Solution2.java b/[0075][Sort Colors]/src/Solution2.java new file mode 100644 index 0000000..ac7b270 --- /dev/null +++ b/[0075][Sort Colors]/src/Solution2.java @@ -0,0 +1,71 @@ +/** + * Author: + * Date: 2015-08-21 + * Time: 19:37 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + /** + *
+ * ԭ + * Given an array with n objects colored red, white or blue, sort them so that objects + * of the same color are adjacent, with the colors in the order red, white and blue. + * Here, we will use the integers 0, 1, and 2 to represent the color red, white, + * and blue respectively. + * Note: + * You are not suppose to use the librarys sort function for this problem. + * + * Ŀ + * һ飬Ǻɫɫɫɫ죬ף + * ʹ012ֱ죬ף + * ע⣺ʹÿ⺯ + * + * ˼· + * ɨ裬¼1ĸĺ͡ɨԵó1Ŀt2Ŀ(sum-t)/2 + * Եó0ĿӸ012Ŀٶֵ + *+ * + * @param A + */ + public void sortColors(int[] A) { + + if (A == null) { + return; + } + + // ͳ1ĸ + int count = 0; + + // ͳĺ + int sum = 0; + + for (int i : A) { + if (i == 1) { + count++; + } + + sum += i; + } + + // 2Ŀ + sum = (sum - count) / 2; + + // 1ʼֵλ + count = A.length - count - sum; + + // 2ʼֵλ + sum = A.length - sum; + + for (int i = 0; i < count; i++) { + A[i] = 0; + } + + for (int i = count; i < sum; i++) { + A[i] = 1; + } + + for (int i = sum; i < A.length; i++) { + A[i] = 2; + } + } +} diff --git a/[0077][Combinations]/[0077][Combinations].iml b/[0077][Combinations]/[0077][Combinations].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0077][Combinations]/[0077][Combinations].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Given two integers n and k, return all possible combinations of k numbers out of 1 n. + * For example, + * If n = 4 and k = 2, a solution is: + * + * [ + * [2,4], + * [3,4], + * [2,3], + * [1,2], + * [1,3], + * [1,4], + * ] + * + * Ŀ + * nk1-nkϡ + * + * ˼· + * ʹùŻ㷨 + *+ * + * @param n + * @param k + * @return + */ + public List
+ * ԭ + * Given two integers n and k, return all possible combinations of k numbers out of 1 n. + * For example, + * If n = 4 and k = 2, a solution is: + * + * [ + * [2,4], + * [3,4], + * [2,3], + * [1,2], + * [1,3], + * [1,4], + * ] + * + * Ŀ + * nk1-nkϡ + * + * ˼· + * õݹη⣬롣 + *+ * + * @param n + * @param k + * @return + */ + public List
+ * ԭ + * Given a set of distinct integers, nums, return all possible subsets. + * Note: + * Elements in a subset must be in non-descending order. + * The solution set must not contain duplicate subsets. + * For example, + * If nums = [1,2,3], a solution is: + * + * [ + * [3], + * [1], + * [2], + * [1,2,3], + * [1,3], + * [2,3], + * [1,2], + * [] + * ] + * + * Ŀ + * һֵͬ飬Ӽ + * + * ˼· + * ȶеԪؽȻʹùŻ + *+ * + * @param nums + * @return + */ + public List
+ * ԭ + * Given a set of distinct integers, nums, return all possible subsets. + * Note: + * Elements in a subset must be in non-descending order. + * The solution set must not contain duplicate subsets. + * For example, + * If nums = [1,2,3], a solution is: + * + * [ + * [3], + * [1], + * [2], + * [1,2,3], + * [1,3], + * [2,3], + * [1,2], + * [] + * ] + * + * Ŀ + * һֵͬ飬Ӽ + * + * ˼· + * ȶеԪؽȻõݹη⡣ + *+ * + * @param S + * @return + */ + public List
+ * ԭ + * Given a set of distinct integers, nums, return all possible subsets. + * Note: + * Elements in a subset must be in non-descending order. + * The solution set must not contain duplicate subsets. + * For example, + * If nums = [1,2,3], a solution is: + * + * [ + * [3], + * [1], + * [2], + * [1,2,3], + * [1,3], + * [2,3], + * [1,2], + * [] + * ] + * + * Ŀ + * һֵͬ飬Ӽ + * + * ˼· + * ȶеԪؽȻõݹη⡣ + *+ * + * @param nums + * @return + */ + public List
+ * Given a 2D board and a word, find if the word exists in the grid. + * + * The word can be constructed from letters of sequentially adjacent cell, + * where "adjacent" cells are those horizontally or vertically neighboring. + * The same letter cell may not be used more than once. + * + * For example, + * Given board = + * [ + * ["ABCE"], + * ["SFCS"], + * ["ADEE"] + * ] + * word = "ABCCED", -> returns true, + * word = "SEE", -> returns true, + * word = "ABCB", -> returns false. + * + * Ŀ⣺ + * һboardַԴһ㿪ʼҵķʽߣÿֻһΣ + * һ·߹ַڸַôtrue + * + * ˼· + * ÿһΪ㣬ʹûݷ + *+ * + * @param board + * @param word + * @return + */ + public boolean exist(char[][] board, String word) { + // עǼٶIJǺϷ + + // ʱǾʼֵĬϻΪfalse + boolean[][] visited = new boolean[board.length][board[0].length]; + + // ÿһλΪҵһ·ֹͣ + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (search(board, visited, i, j, word, new int[]{0})) { + return true; + } + } + } + + return false; + } + + /** + * @param board ַ + * @param visited ʱǾ + * @param row ʵк + * @param col ʵк + * @param word ƥַ + * @param idx ƥλãȡǸºֵԱ + * @return + */ + private boolean search(char[][] board, boolean[][] visited, int row, int col, String word, int[] idx) { + // λõִijȣ˵Ѿҵҵƥ + if (idx[0] == word.length()) { + return true; + } + + boolean hasPath = false; + // ǰλúϷ + if (check(board, visited, row, col, word, idx[0])) { + // λñʹ + visited[row][col] = true; + idx[0]++; + // ϣң£ĸ + hasPath = search(board, visited, row - 1, col, word, idx) // + || search(board, visited, row, col + 1, word, idx) // + || search(board, visited, row + 1, col, word, idx) // + || search(board, visited, row, col - 1, word, idx); // + + + // ûҵ·ͻ + if (!hasPath) { + visited[row][col] = false; + idx[0]--; + } + } + + return hasPath; + } + + /** + * жʵλǷϷ + * + * @param board ַ + * @param visited ʱǾ + * @param row ʵк + * @param col ʵк + * @param word ƥַ + * @param idx ƥλ + * @return + */ + + public boolean check(char[][] board, boolean[][] visited, int row, int col, String word, int idx) { + return row >= 0 && row < board.length // кźϷ + && col >= 0 && col < board[0].length // кźϷ + && !visited[row][col] // ûбʹ + && board[row][col] == word.charAt(idx); // ַ + } +} diff --git a/[0080][Remove Duplicates from Sorted Array II]/[0080][Remove Duplicates from Sorted Array II].iml b/[0080][Remove Duplicates from Sorted Array II]/[0080][Remove Duplicates from Sorted Array II].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0080][Remove Duplicates from Sorted Array II]/[0080][Remove Duplicates from Sorted Array II].iml @@ -0,0 +1,13 @@ + +
+ * Follow up for "Search in Rotated Sorted Array": + * What if duplicates are allowed? + * Would this affect the run-time complexity? How and why? + * Write a function to determine if a given target is in the array + * + * Ŀ⣺ + * "תֵ"ĺеֵظ + * дһȷһֵǷ + *+ * + * @param nums + * @param target + * @return + */ + public boolean search(int[] nums, int target) { + if (nums != null && nums.length > 0) { + // СԪضӦ± + int minIndex = findMinIndex(nums); + + // ȫ + if (minIndex == 0) { + return binarySearch(nums, 0, nums.length - 1, target); + } + // ֲ, 4 5 6 7 8 9 0 1 2 3 + else { + // úͺһһԪȣضӦ± + if (nums[nums.length - 1] == target) { + return true; + } + // targetںһ + else if (nums[nums.length - 1] > target) { + return binarySearch(nums, minIndex, nums.length - 1, target); + } + // targetǰһ + else { + return binarySearch(nums, 0, minIndex - 1, target); + } + } + } + + return false; + } + + /** + * + * + * @param nums + * @param start ʼλ + * @param end λ + * @param target Ŀ + * @return trueҵfalseûҵ + */ + public boolean binarySearch(int[] nums, int start, int end, int target) { + + int mid; + while (start <= end) { + mid = start + ((end - start) >> 1); + + if (nums[mid] == target) { + return true; + } else if (nums[mid] > target) { + end = mid - 1; + } else { + start = mid + 1; + } + } + + return false; + } + + + public int findMinIndex(int[] nums) { + // У + if (nums == null || nums.length < 1) { + throw new IllegalArgumentException(); + } + + int lo = 0; + int hi = nums.length - 1; + int mid = 0; + + // ųȫ + while (nums[lo] >= nums[hi]) { + // ֻԪأغһ + if (hi - lo == 1) { + mid = hi; + break; + } + + mid = lo + ((hi - lo) >> 1); + + if (nums[mid] == nums[lo] && nums[mid] == nums[hi]) { + // ֻܲ˳ܲlo++hi--ķʽ + // Ϊloǰһһ + // hiҲǺһĵһ + return sequenceSearchMinIndex(nums, lo, hi); + } + + // midǰһ + if (nums[mid] >= nums[lo]) { + lo = mid; + } + // midںһ + else if (nums[mid] <= nums[hi]) { + hi = mid; + } + } + + return mid; + } + + /** + * ˳еСֵ±꣬nums鰴ijת + * + * @param nums + * @param start ʼλ + * @param end λ + * @return Сֵ± + */ + public int sequenceSearchMinIndex(int[] nums, int start, int end) { + for (int i = start; i < end; i++) { + if (nums[i] > nums[i + 1]) { + return i + 1; + } + } + return start; + } +} diff --git a/[0081][Search In Rotated Sorted Array II]/src/Solution2.java b/[0081][Search In Rotated Sorted Array II]/src/Solution2.java new file mode 100644 index 0000000..9e48b6c --- /dev/null +++ b/[0081][Search In Rotated Sorted Array II]/src/Solution2.java @@ -0,0 +1,56 @@ +/** + * @author: wangjunchao(王俊超) + * @time: 2019-06-13 06:19 + **/ +public class Solution2 { + /** + * 分析 + * 允许重复元素,则上一题中如果A[mid]>=A[left], 那么[left,mid] 为递增序列的假设就不能成立了,比 + * 如[1,3,1,1,1]。 + * 如果A[mid]>=A[left] 不能确定递增,那就把它拆分成两个条件: + * • 若A[mid]>A[left],则区间[left,mid] 一定递增 + * • 若A[mid]==A[left] 确定不了,那就l++,往下看一步即可。 + * + * @param nums + * @param target + * @return + */ + public boolean search(int[] nums, int target) { + if (nums == null || nums.length < 1) { + return false; + } + + int left = 0; + int right = nums.length - 1; + int mid; + while (left <= right) { + mid = left + (right - left) / 2; + if (nums[mid] == target) { + return true; + } + + // [left, mid]区间递增 + if (nums[left] < nums[mid]) { + // target在[nums[left], nums[mid]]之间 + if (nums[left] <= target && target < nums[mid]) { + right = mid - 1; + } else { + left = mid + 1; + } + } else if (nums[left] > nums[mid]) { // [mid, right]区间递增 + // target在[nums[mid], nums[right]]之间 + if (nums[mid] < target && target <= nums[right]) { + left = mid + 1; + } else { + right = mid - 1; + } + } else { + // 无法区分递增区间,向右移动一个位置 + left++; + } + } + + + return false; + } +} diff --git a/[0082][Remove Duplicates From Sorted List II]/[0082][Remove Duplicates From Sorted List II].iml b/[0082][Remove Duplicates From Sorted List II]/[0082][Remove Duplicates From Sorted List II].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0082][Remove Duplicates From Sorted List II]/[0082][Remove Duplicates From Sorted List II].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Given a sorted linked list, delete all nodes that have duplicate numbers, + * leaving only distinct numbers from the original list. + * For example, + * Given 1->2->3->3->4->4->5, return 1->2->5. + * Given 1->1->1->2->3, return 2->3. + * + * Ŀ + * һźĵɾظԪءֻֻһֵԪء + * + * ˼· + * һrootrootӵԭͷͷָ룬صԪؽɾ + *+ * + * @param head + * @return + */ + public ListNode deleteDuplicates(ListNode head) { + + // ͷ + ListNode root = new ListNode(0); + root.next = head; + ListNode p = head; + // ¼һûظԪأʼָͷ + ListNode q = root; + + // Ԫظ + int delta = 0; + + while (p != null && p.next != null) { + // ͬ + if (p.val == p.next.val) { + delta++; + // ƶһ + p = p.next; + } + // 㲻ͬ + else { + // ֵΪp.valĽûظ + if (delta == 0) { + // ӵûиԪ + q.next = p; + // ָһδظԪ + q = p; + // ƶһ + p = p.next; + } + // ֵΪp.valĽظ + else { + // ƶһԪ + p = p.next; + // ȥظԪ + q.next = p.next; + // ԪظΪ0 + delta = 0; + } + } + } + + // һԪǸľȥ + if (delta != 0) { + q.next = null; + } + // ûظͿӵβ + else { + q.next = p; + } + + return root.next; + } +} diff --git a/[0083][Remove Duplicates From Sorted List]/[0083][Remove Duplicates From Sorted List].iml b/[0083][Remove Duplicates From Sorted List]/[0083][Remove Duplicates From Sorted List].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0083][Remove Duplicates From Sorted List]/[0083][Remove Duplicates From Sorted List].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Given a sorted linked list, delete all duplicates such that each element appear only once. + * For example, + * Given 1->1->2, return 1->2. + * Given 1->1->2->3->3, return 1->2->3. + * + * Ŀ + * һɾظԪأֻͬһ + * + * ˼· + * ʹһָָͷһ뵱ǰĽɾֱһͬģָָ + * µĽ㣬ظֱеĽ㶼ꡣ + *+ * + * @param head + * @return + */ + public ListNode deleteDuplicates(ListNode head) { + ListNode point; + // ָ½βʼʱֻһԪأͷ + ListNode tail = head; + + if (head != null) { + // ָͷһԪ + point = head.next; + // δĩβ + while (point != null) { + + // βڵ㲻ͬͽͬĽڵӵtailһλ + if (tail.val != point.val) { + tail.next = point; + // ָβ + tail = tail.next; + } + + // ƶһλ + point = point.next; + } + + // βָ + tail.next = null; + } + + return head; + } +} diff --git a/[0084][Largest Rectangle in Histogram]/[0084][Largest Rectangle in Histogram].iml b/[0084][Largest Rectangle in Histogram]/[0084][Largest Rectangle in Histogram].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0084][Largest Rectangle in Histogram]/[0084][Largest Rectangle in Histogram].iml @@ -0,0 +1,13 @@ + +
+ * Given n non-negative integers representing the histogram's bar height where the width + * of each bar is 1, find the area of largest rectangle in the histogram. + * + * + * - + * -- + * -- + * -- - + * - ---- + * ------ + * Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. + * The largest rectangle is shown in the shaded area, which has area = 10 unit. + * - + * == + * == + * == - + * - ==-- + * --==-- + * Example: + * Input: [2,1,5,6,2,3] + * Output: 10 + * + * https://leetcode.com/problems/largest-rectangle-in-histogram/ + *+ */ + public int largestRectangleArea(int[] heights) { + if (heights == null || heights.length < 1) { + return 0; + } + // 记录位置 + Deque
+ * ԭ + * Given a linked list and a value x, partition it such that all nodes less + * than x come before nodes greater than or equal to x. + * You should preserve the original relative order of the nodes in each of + * the two partitions. + * + * For example, + * Given 1->4->3->2->5->2 and x = 3, + * return 1->2->2->4->3->5. + * + * Ŀ + * һһֵxֳСڵxIJֺʹxIJ֡ͬʱԭ˳ + * + * ˼· + * abԭеÿ㣬СڵxĽaĩβǴھͷb + * ĩβbͷӵaĩβ + *+ * + * @param head + * @param x + * @return + */ + public ListNode partition(ListNode head, int x) { + + ListNode le = new ListNode(0); // Сx + ListNode ge = new ListNode(0); // ڵx + ListNode t1 = le; + ListNode t2 = ge; + ListNode p = head; + + while (p != null) { + if (p.val < x) { + t1.next = p; + t1 = p; + } else { + t2.next = p; + t2 = p; + } + p = p.next; + } + + t2.next = null; + + // пt1û + // t1ƶ˵Сڵ + if (t1 != le) { + t1.next = ge.next; + head = le.next; + } else { + head = ge.next; + } + + return head; + } +} diff --git a/[0088][Merge Sorted Array]/[0088][Merge Sorted Array].iml b/[0088][Merge Sorted Array]/[0088][Merge Sorted Array].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0088][Merge Sorted Array]/[0088][Merge Sorted Array].iml @@ -0,0 +1,13 @@ + +
+ * ԭ + * Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. + * Note: + * You may assume that nums1 has enough space (size that is greater or equal to m + n) to + * hold additional elements from nums2. The number of elements initialized in nums1 and + * nums2 are m and n respectively. + * + * Ŀ + * 飬кϲϲҲģϲnums1С + * nums1㹻Ŀռnums2 + * + * ˼· + * еһλÿʼкϲнϴƶλãǸ + * λֵǰƶһλãٽͬIJֱеԪشꡣ + *+ * + * @param arr + * @param m + * @param brr + * @param n + */ + public void merge(int arr[], int m, int brr[], int n) { + int pa = m - 1; + int pb = n - 1; + int index = m + n - 1; + + while (pa >= 0 && pb >= 0) { + if (arr[pa] >= brr[pb]) { + arr[index--] = arr[pa--]; + } else { + arr[index--] = brr[pb--]; + } + } + + // ˵paһΪ0 + while (pb >= 0) { + arr[index--] = brr[pb--]; + } + + // pa >= 0˵[0, pa]ûнжϣΪ[0, pa]arrУԲҪƶ + } +} diff --git a/[0089][Gray Code]/[0089][Gray Code].iml b/[0089][Gray Code]/[0089][Gray Code].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0089][Gray Code]/[0089][Gray Code].iml @@ -0,0 +1,13 @@ + +
+ * The nums[c] is a binary numeral system where two successive values differ in only one bit. + * Given a non-negative integer n representing the total number of bits in the code, print the + * sequence of gray code. A gray code sequence must begin with 0. + * + * For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: + * 00 - 0 + * 01 - 1 + * 11 - 3 + * 10 - 2 + * + * Note: + * - For a given n, a gray code sequence is not uniquely defined. + * - For example, [0,2,3,1] is also a valid gray code sequence according to the above + * definition. + * - For now, the judge is able to judge based on one instance of gray code sequence. + * Sorry about that. + * + * Ŀ⣺ + * nΪnĸ + * + * (Gray Code) Ķοhttp://en.wikipedia.org/wiki/Gray_code + * ȻתΪ룺g0 = b0; gi = bi^b(i-1) + * ȻλΪλθλΪĸλθλ + * λθλơ磬Ȼ1001תΪĹǣ + * λȻ1 λ1 ͵2 λ0 õ1Ϊĵ2 λ2 λ0 ͵3 λ + * 0 õ0Ϊĵ3 λ3 λ0 ͵4 λ1 õ1Ϊ + * 4 λգΪ1101 + * תΪȻ룺b0 = g0; bi = gi^b(i-1) + * λΪȻλθλΪȻƸλθλ + * λθλơ磬1000 תΪȻĹǣ + * λ1ΪȻλȻȻĵ1 λ1 ĵ2 λ0 + * 1ΪȻĵ2 λȻĵ2 λ1 ĵ3 λ0 õ1 + * ΪȻĵ3 λȻĵ3 λ1 ĵ4 λ0 õ1Ϊ + * Ȼĵ4 λգȻΪ1111 + * ѧʽn ĸn^(n/2) + * Ҫn صи롣 + * 1ķѧʽԴ0 ~2^n-1 תΪ롣 + * 2nصĸ룬Եݹشn - 1 صĸɡ + * + * ˼· + * ݹ + * ַڸǷʵõݹ¹죺 + * 1λ + * (n+1)λеǰ2^nֵnλ֣˳дǰ0 + * (n+1)λеĺ2^nֵnλ֣дǰ1 + *+ * + * @param n + * @return + */ + public List
+ * Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set). + * + * Note: The solution set must not contain duplicate subsets. + * + * Example: + * + * Input: [1,2,2] + * Output: + * [ + * [2], + * [1], + * [1,2,2], + * [2,2], + * [1,2], + * [] + * ] + *+ * + * @param nums + * @return + */ + public List
+ * 'A' -> 1 + * 'B' -> 2 + * ... + * 'Z' -> 26 + * Given a non-empty string containing only digits, determine the total number of ways to decode it. + *
+ * Example 1: + *
+ * Input: "12" + * Output: 2 + * Explanation: It could be decoded as "AB" (1 2) or "L" (12). + * Example 2: + *
+ * Input: "226" + * Output: 3 + * Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6). + * + * @param s + * @return + */ + public int numDecodings(String s) { + if (s.isEmpty() || s.charAt(0) == '0') { + return 0; + } + int prev = 0; + int cur = 1; + // 长度为n 的字符串,有n+1 个阶梯 + for (int i = 1; i <= s.length(); ++i) { + if (s.charAt(i - 1) == '0') { + cur = 0; + } + if (i < 2 || !(s.charAt(i - 2) == '1' || (s.charAt(i - 2) == '2' && s.charAt(i - 1) <= '6'))) { + prev = 0; + } + + int tmp = cur; + cur = prev + cur; + prev = tmp; + } + return cur; + } + +} \ No newline at end of file diff --git a/[0091][Decode Ways]/src/Solution2.java b/[0091][Decode Ways]/src/Solution2.java new file mode 100644 index 0000000..3c3ccdf --- /dev/null +++ b/[0091][Decode Ways]/src/Solution2.java @@ -0,0 +1,96 @@ +/** + * @author: wangjunchao(王俊超) + * @time: 2019-06-25 19:17 + **/ +public class Solution2 { + /** + * A message containing letters from A-Z is being encoded to numbers using the following mapping: + *
+ * 'A' -> 1 + * 'B' -> 2 + * ... + * 'Z' -> 26 + * Given a non-empty string containing only digits, determine the total number of ways to decode it. + *
+ * Example 1: + *
+ * Input: "12" + * Output: 2 + * Explanation: It could be decoded as "AB" (1 2) or "L" (12). + * Example 2: + *
+ * Input: "226"
+ * Output: 3
+ * Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
+ *
+ * @param s
+ * @return
+ */
+ public int numDecodings(String s) {
+ int n = s.length();
+ if (n == 0) {
+ return 0;
+ }
+
+ int[] memo = new int[n + 1];
+ memo[n] = 1;
+ memo[n - 1] = s.charAt(n - 1) != '0' ? 1 : 0;
+
+ for (int i = n - 2; i >= 0; i--) {
+ if (s.charAt(i) == '0') {
+ continue;
+ } else {
+ memo[i] = (Integer.parseInt(s.substring(i, i + 2)) <= 26) ? memo[i + 1] + memo[i + 2] : memo[i + 1];
+ }
+ }
+ return memo[0];
+ }
+
+ // 太慢
+ public int numDecodings2(String s) {
+ // 如是不是纯数字的字符串就返回0
+ if (s == null || !s.matches("^\\d+$")) {
+ return 0;
+ }
+
+ // 第一位以0开头,没有可以匹配的
+ if (s.charAt(0) == '0') {
+ return 0;
+ }
+
+ // 如果只一位
+ if (s.length() == 1) {
+ return handle(s);
+ }
+
+ // 如果有两位
+ if (s.length() == 2) {
+ int v = Integer.parseInt(s);
+ // 如果拆成个一位的有几种可能
+ int r = handle(s.substring(s.length() - 1));
+
+ // 如是两位组成一个,1~26才可以算一种可能
+ if (v > 0 && v < 27) {
+ r++;
+ }
+ return r;
+ }
+
+ // 字符串长度大于3,f(s)=(0 or 1)*f(s-1) + (0 or 1)*f(s-2)
+ // 对于f(s-1),如果首位是0,取0
+ // 对于f(s-2),如果首位是0或者首两位的值小于1或者大于26,取0
+
+ int v = numDecodings(s.substring(1));
+ int t = Integer.parseInt(s.substring(0, 2));
+
+ if (t > 0 && t < 27) {
+ v += numDecodings(s.substring(2));
+ }
+
+ return v;
+ }
+
+ private int handle(String s) {
+ return Integer.parseInt(s) == 0 ? 0 : 1;
+ }
+}
\ No newline at end of file
diff --git a/[0092][Reverse Linked List II]/[0092][Reverse Linked List II].iml b/[0092][Reverse Linked List II]/[0092][Reverse Linked List II].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0092][Reverse Linked List II]/[0092][Reverse Linked List II].iml
@@ -0,0 +1,13 @@
+
+
+ * ԭ + * Reverse a linked list from position m to n. Do it in-place and in one-pass. + * For example: + * Given 1->2->3->4->5->NULL, m = 2 and n = 4, + * return 1->4->3->2->5->NULL. + * Note: + * Given m, n satisfy the following condition: + * 1 m n length of list. + * + * Ŀ + * һmn֮Ԫؽת + * nmǺϷģʹԭطнʹóռ䣩 + * + * ˼· + * ҵһҪתԪصǰprevټҪзתԪظԪؽͷ巨 + * prev棬ͬʱϿ + *+ * + * @param head + * @param m + * @param n + * @return + */ + public ListNode reverseBetween(ListNode head, int m, int n) { + + ListNode root = new ListNode(0); + ListNode p = root; + root.next = head; + + for (int i = 1; i < m && p != null; i++) { + p = p.next; + } + + if (p != null) { + ListNode q = p.next; + ListNode r; + + // mΪΪǴӵһʼ + if (m < 1) { + m = 1; + } + + // nΪҪĽĿ + n = n - m + 1; + // ʱҪʹβ巨βĸΪn-1 + for (int i = 1; i < n && q.next != null; i++) { + // ΪҪβĽ + r = q.next; + + // qĺβ + q.next = r.next; + r.next = p.next; + p.next = r; + } + + head = root.next; + } + + return head; + } +} diff --git a/[0093][Restore IP Addresses]/[0093][Restore IP Addresses].iml b/[0093][Restore IP Addresses]/[0093][Restore IP Addresses].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0093][Restore IP Addresses]/[0093][Restore IP Addresses].iml @@ -0,0 +1,13 @@ + +
+ * For example, + * Given n = 3, there are a total of 5 unique BST's. + * 1 3 3 2 1 + * \ / / / \ \ + * 3 2 1 1 3 2 + * / / \ \ + * 2 1 2 3 + *
+ * ƹʽ + * f(0) = 1 + * f(1) = 1 + * f(i) = f(0)f(i-1) + f(1)f(i-1) + ... + f(i-1)f(0) + * + * @param n + * @return + */ + public int numTrees(int n) { + + if (n <= 0) { + return 1; + } else if (n == 1) { + return 1; + } + + int[] result = new int[n + 1]; + result[0] = 1; + result[1] = 1; + + + // f(2)...f(n) + for (int i = 2; i <= n; i++) { + for (int j = 1; j <= i; j++) { + result[i] += result[j - 1] * result[i - j]; + } + + } + return result[n]; + } +} diff --git a/[0096][Unique Binary Search Trees]/src/Solution2.java b/[0096][Unique Binary Search Trees]/src/Solution2.java new file mode 100644 index 0000000..31624d1 --- /dev/null +++ b/[0096][Unique Binary Search Trees]/src/Solution2.java @@ -0,0 +1,51 @@ +/** + * Author: + * Date: 2015-06-18 + * Time: 17:36 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + /** + * Given n, how many structurally unique BST's (binary search trees) that store values 1...n? + *
+ * For example, + * Given n = 3, there are a total of 5 unique BST's. + * 1 3 3 2 1 + * \ / / / \ \ + * 3 2 1 1 3 2 + * / / \ \ + * 2 1 2 3 + *
+ * ƹʽ + * f(k)*f(n-1-k)f(k)ʾk㣬е״f(k)f(n-1-k)ʾn-1-k + *
+ * f(n) = 2*f(n-1) + f(1)*f(n-2) + f(2)f(n-3) + f(3)f(n-4) + ... +f(n-2)*f(1)
+ *
+ * @param n
+ * @return
+ */
+ public int numTrees(int n) {
+
+ if (n <= 0) {
+ return 1;
+ } else if (n == 1) {
+ return 1;
+ }
+
+ int[] result = new int[n + 1];
+ result[0] = 0;
+ result[1] = 1;
+
+
+ // f(2)...f(n)
+ for (int i = 2; i <= n; i++) {
+ // f(i)
+ result[i] = 2 * result[i - 1];
+ for (int j = 1; j <= i - 1; j++) {
+ result[i] += result[j] * result[i - 1 - j];
+ }
+
+ }
+ return result[n];
+ }
+}
diff --git a/[0098][Validate Binary Search Tree]/[0098][Validate Binary Search Tree].iml b/[0098][Validate Binary Search Tree]/[0098][Validate Binary Search Tree].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0098][Validate Binary Search Tree]/[0098][Validate Binary Search Tree].iml
@@ -0,0 +1,13 @@
+
+
+ * Given preorder and inorder traversal of a tree, construct the binary tree. + * + * Note: + * You may assume that duplicates do not exist in the tree. + * + * Ŀ⣺ + * һǰУһ + * ע⣺ + * - ԪظԪ + * + * ˼· + * ǰһԪǸ㣨kֵΪk±idx + * idxзֳǰҲһɽеݹ + *+ * + * @param preorder + * @param inorder + * @return + */ + public TreeNode buildTree(int[] preorder, int[] inorder) { + + // У + if (preorder == null || inorder == null || preorder.length == 0 || preorder.length != inorder.length) { + return null; + } + return solve(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); + } + + /** + * ȷԼ֤ + * + * @param preorder Ľ + * @param x Ŀʼλ + * @param y Ľλ + * @param inorder Ľ + * @param i Ŀʼλ + * @param j Ľλ + * @return ĸ + */ + public TreeNode solve(int[] preorder, int x, int y, int[] inorder, int i, int j) { + + if (x >= 0 && x <= y && i >= 0 && i <= j) { + // ֻһԪ + if (x == y) { + return new TreeNode(preorder[x]); + } + // xܴy + else if (x < y) { + // ¼ + int idx = i; + while (idx <= j && inorder[idx] != preorder[x]) { + idx++; + } + + // + TreeNode root = new TreeNode(inorder[idx]); + + // Ľ + //[i, i+1, ..., idx - 1] -> ܼidx - i + int leftLength = idx - i; + // + if (leftLength > 0) { + // x + 1, x + leftLengthʼͽλ + root.left = solve(preorder, x + 1, x + leftLength, inorder, i, idx - 1); + } + + // Ľ + // [idx+1, idx+2, ..., j] -> ܼƣj - idx + int rightLength = j - idx; + if (rightLength > 0) { + // x + leftLength + 1, yʼͽλ + root.right = solve(preorder, x + leftLength + 1, y, inorder, idx + 1, j); + } + return root; + } + } + + return null; + } +} diff --git "a/\343\200\220105\343\200\221\343\200\220ConstructBinaryTreeFromPreorderAndInorderTraversal\343\200\221/src/TreeNode.java" b/[0105][Construct Binary Tree From Preorder And Inorder Traversal]/src/TreeNode.java similarity index 100% rename from "\343\200\220105\343\200\221\343\200\220ConstructBinaryTreeFromPreorderAndInorderTraversal\343\200\221/src/TreeNode.java" rename to [0105][Construct Binary Tree From Preorder And Inorder Traversal]/src/TreeNode.java diff --git a/[0106][Construct Binary Tree From Inorder And Postorder Traversal]/[0106][Construct Binary Tree From Inorder And Postorder Traversal].iml b/[0106][Construct Binary Tree From Inorder And Postorder Traversal]/[0106][Construct Binary Tree From Inorder And Postorder Traversal].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0106][Construct Binary Tree From Inorder And Postorder Traversal]/[0106][Construct Binary Tree From Inorder And Postorder Traversal].iml @@ -0,0 +1,13 @@ + +
+ * Given inorder and postorder traversal of a tree, construct the binary tree. + * + * Note: + * You may assume that duplicates do not exist in the tree. + * + * Ŀ⣺ + * һͺУһö + * ע⣺ + * ûظԪ + * + * ˼· + * һԪؾĸ(ֵΪr) + * ֵΪrλidxidxзΪ + * ӦԽзݹ + *+ * + * @param inorder + * @param postorder + * @return + */ + public TreeNode buildTree(int[] inorder, int[] postorder) { + + // + if (inorder == null || postorder == null || inorder.length == 0 || inorder.length != postorder.length) { + return null; + } + + // + return solve(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1); + } + + /** + * + * + * @param inorder Ľ + * @param x Ŀʼλ + * @param y Ľλ + * @param postorder Ľ + * @param i Ŀʼλ + * @param j Ľλ + * @return + */ + public TreeNode solve(int[] inorder, int x, int y, int[] postorder, int i, int j) { + + if (x >= 0 && x <= y && i >= 0 && i <= j) { + // ֻһԪأʱҲi=jɣ + if (x == y) { + return new TreeNode(postorder[j]); + } + // һԪأʱҲi
+ * ԭ + * Given a binary tree, find its minimum depth. + * The minimum depth is the number of nodes along the shortest path from + * the root node down to the nearest leaf node. + * + * Ŀ + * һСȡ + * + * ˼· + * бҳСȡ + *+ * + * @param root + * @return + */ + public int minDepth(TreeNode root) { + return minDepth(root, false); + } + + public int minDepth(TreeNode root, boolean hasBrother) { + if (root == null) { + // ԼΪnullֵܲΪnullϲӽ㣬˵ǰûҵС + // ûֵܣ˵ǰʱֲСѾҵ + return hasBrother ? Integer.MAX_VALUE : 0; + } + + return 1 + Math.min(minDepth(root.left, root.right != null), + minDepth(root.right, root.left != null)); + } + +} diff --git a/[0111][Minimum Depth Of Binary Tree]/src/Solution2.java b/[0111][Minimum Depth Of Binary Tree]/src/Solution2.java new file mode 100644 index 0000000..6dfcd46 --- /dev/null +++ b/[0111][Minimum Depth Of Binary Tree]/src/Solution2.java @@ -0,0 +1,64 @@ +/** + * Author: + * Date: 2015-08-21 + * Time: 18:51 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + private int min = Integer.MAX_VALUE; // ¼С + private int cur = 0; // iǰij + + /** + *
+ * ԭ + * Given a binary tree, find its minimum depth. + * The minimum depth is the number of nodes along the shortest path from + * the root node down to the nearest leaf node. + * + * Ŀ + * һСȡ + * + * ˼· + * бҳСȡ + *+ * + * @param root + * @return + */ + public int minDepth(TreeNode root) { + + depth(root); + return min; + } + + /** + * + * + * @param node ǰ + */ + private void depth(TreeNode node) { + + if (node == null) { + min = cur; + return; + } + + cur++; // ǰIJμ1 + // Ҷڵ㣬·ȼ¼СС + if (node.left == null && node.right == null && cur < min) { + min = cur; // Сֵ + } + // + if (node.left != null) { + depth(node.left); + } + + // + if (node.right != null) { + depth(node.right); + } + + cur--; // ԭ + + } +} diff --git "a/\343\200\220111\343\200\221\343\200\220MinimumDepthOfBinaryTree\343\200\221/src/TreeNode.java" b/[0111][Minimum Depth Of Binary Tree]/src/TreeNode.java similarity index 100% rename from "\343\200\220111\343\200\221\343\200\220MinimumDepthOfBinaryTree\343\200\221/src/TreeNode.java" rename to [0111][Minimum Depth Of Binary Tree]/src/TreeNode.java diff --git a/[0112][Path Sum]/[0112][Path Sum].iml b/[0112][Path Sum]/[0112][Path Sum].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0112][Path Sum]/[0112][Path Sum].iml @@ -0,0 +1,13 @@ + +
+ * Say you have an array for which the ith element is the price of a given stock on day i. + * + * If you were only permitted to complete at most one transaction (ie, buy one and sell + * one share of the stock), design an algorithm to find the maximum profit. + * + * Ŀ⣺ + * һprices[]prices[i]Ʊڵiۼֻۣһν(һ)ܵõ档 + * + * ˼· + * + * ̰ķֱҵ۸ͺߵһ죬ͽ߳ע͵һҪߵһ֮ǰ + * ԭʼ۸бɲУҲmӶκͣm = 1 + * + * ֻҪҳIJֵɣ max(prices[j], prices[i]) i < jһαɣڱʱñ + * low¼ prices[0, ..., i] еСֵǵǰΪֹۼۣʱ临ӶΪ O(n) + *+ * + * @param prices + * @return + */ + public int maxProfit(int[] prices) { + + if (prices == null || prices.length < 1) { + return 0; + } + + int min = prices[0]; + int profit = 0; + + // iļ۸ԿҲԿ + for (int i = 1; i < prices.length; i++) { + // ҵ͵ + if (min > prices[i]) { + // + min = prices[i]; + } + // ļ۸ + else { + // ļ۸֮ǰļ۸ + if (profit < prices[i] - min) { + // + profit = prices[i] - min; + } + } + } + + return profit; + } +} diff --git a/[0122][Best Time to Buy and Sell Stock II]/[0122][Best Time to Buy and Sell Stock II].iml b/[0122][Best Time to Buy and Sell Stock II]/[0122][Best Time to Buy and Sell Stock II].iml new file mode 100644 index 0000000..c8cb479 --- /dev/null +++ b/[0122][Best Time to Buy and Sell Stock II]/[0122][Best Time to Buy and Sell Stock II].iml @@ -0,0 +1,23 @@ + +
+ * Say you have an array for which the ith element is the price of a given stock on day i. + * + * Design an algorithm to find the maximum profit. You may complete as many transactions as you + * like (i.e., buy one and sell one share of the stock multiple times). + * + * Note: You may not engage in multiple transactions at the same time (i.e., you must sell the + * stock before you buy again). + * + * Example 1: + * + * Input: [7,1,5,3,6,4] + * Output: 7 + * Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. + * Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. + * Example 2: + * + * Input: [1,2,3,4,5] + * Output: 4 + * Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. + * Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are + * engaging multiple transactions at the same time. You must sell before buying again. + * Example 3: + * + * Input: [7,6,4,3,1] + * Output: 0 + * Explanation: In this case, no transaction is done, i.e. max profit = 0. + * + *+ * + * @param prices + * @return + */ + public int maxProfit(int[] prices) { + + if (prices == null || prices.length < 2) { + return 0; + } + + int sum = 0; + int diff; + for (int i = 1; i < prices.length; i++) { + // 如果后一天的价格比前一天高就卖出 + diff = prices[i] - prices[i - 1]; + if (diff > 0) { + sum += diff; + } + } + + return sum; + } +} diff --git a/[0122][Best Time to Buy and Sell Stock II]/src/Solution2.java b/[0122][Best Time to Buy and Sell Stock II]/src/Solution2.java new file mode 100644 index 0000000..cef7e3c --- /dev/null +++ b/[0122][Best Time to Buy and Sell Stock II]/src/Solution2.java @@ -0,0 +1,71 @@ +/** + * @author: wangjunchao(王俊超) + * @time: 2018-10-09 08:46 + **/ +public class Solution2 { + /** + *
+ * Say you have an array for which the ith element is the price of a given stock on day i. + * + * Design an algorithm to find the maximum profit. You may complete as many transactions as you + * like (i.e., buy one and sell one share of the stock multiple times). + * + * Note: You may not engage in multiple transactions at the same time (i.e., you must sell the + * stock before you buy again). + * + * Example 1: + * + * Input: [7,1,5,3,6,4] + * Output: 7 + * Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. + * Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. + * Example 2: + * + * Input: [1,2,3,4,5] + * Output: 4 + * Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. + * Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are + * engaging multiple transactions at the same time. You must sell before buying again. + * Example 3: + * + * Input: [7,6,4,3,1] + * Output: 0 + * Explanation: In this case, no transaction is done, i.e. max profit = 0. + * + *+ * + * @param prices + * @return + */ + public int maxProfit(int[] prices) { + + if (prices == null || prices.length < 2) { + return 0; + } + + int buy = 0; + int sell = 1; + + int sum = 0; + while (sell < prices.length) { + // 从buy的位置开始找降序子序列中最小的值 + while (buy + 1 < prices.length && prices[buy] >= prices[buy + 1]) { + buy++; + } + // 从buy的位置开始找升序子序列中最大的值 + sell = buy + 1; + while (sell + 1 < prices.length && prices[sell] <= prices[sell + 1]) { + sell++; + } + + if (sell < prices.length) { + sum += prices[sell] - prices[buy]; + } + + buy = sell + 1; + + } + + return sum; + } +} diff --git a/[0124][Binary Tree Maximum Path Sum]/[0124][Binary Tree Maximum Path Sum].iml b/[0124][Binary Tree Maximum Path Sum]/[0124][Binary Tree Maximum Path Sum].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0124][Binary Tree Maximum Path Sum]/[0124][Binary Tree Maximum Path Sum].iml @@ -0,0 +1,13 @@ + +
+ * Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: + * + * Only one letter can be changed at a time + * Each transformed word must exist in the word list. Note that beginWord is not a transformed word. + * Note: + * + * Return an empty list if there is no such transformation sequence. + * All words have the same length. + * All words contain only lowercase alphabetic characters. + * You may assume no duplicates in the word list. + * You may assume beginWord and endWord are non-empty and are not the same. + * Example 1: + * + * Input: + * beginWord = "hit", + * endWord = "cog", + * wordList = ["hot","dot","dog","lot","log","cog"] + * + * Output: + * [ + * ["hit","hot","dot","dog","cog"], + * ["hit","hot","lot","log","cog"] + * ] + * Example 2: + * + * Input: + * beginWord = "hit" + * endWord = "cog" + * wordList = ["hot","dot","dog","lot","log"] + * + * Output: [] + * + * Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. + * + * 使用了图的遍历 + * https://www.cnblogs.com/splash/p/4102786.html + *+ * + * @param beginWord + * @param endWord + * @param wordList + * @return + */ + HashMap
+ * Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: + * + * Only one letter can be changed at a time + * Each transformed word must exist in the word list. Note that beginWord is not a transformed word. + * Note: + * + * Return an empty list if there is no such transformation sequence. + * All words have the same length. + * All words contain only lowercase alphabetic characters. + * You may assume no duplicates in the word list. + * You may assume beginWord and endWord are non-empty and are not the same. + * Example 1: + * + * Input: + * beginWord = "hit", + * endWord = "cog", + * wordList = ["hot","dot","dog","lot","log","cog"] + * + * Output: + * [ + * ["hit","hot","dot","dog","cog"], + * ["hit","hot","lot","log","cog"] + * ] + * Example 2: + * + * Input: + * beginWord = "hit" + * endWord = "cog" + * wordList = ["hot","dot","dog","lot","log"] + * + * Output: [] + * + * Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. + * + * 使用了深度优化遍历方案,会超时 + *+ * + * @param beginWord + * @param endWord + * @param wordList + * @return + */ + public List
+ * Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: + * + * Only one letter can be changed at a time + * Each transformed word must exist in the word list. Note that beginWord is not a transformed word. + * Note: + * + * Return an empty list if there is no such transformation sequence. + * All words have the same length. + * All words contain only lowercase alphabetic characters. + * You may assume no duplicates in the word list. + * You may assume beginWord and endWord are non-empty and are not the same. + * Example 1: + * + * Input: + * beginWord = "hit", + * endWord = "cog", + * wordList = ["hot","dot","dog","lot","log","cog"] + * + * Output: + * [ + * ["hit","hot","dot","dog","cog"], + * ["hit","hot","lot","log","cog"] + * ] + * Example 2: + * + * Input: + * beginWord = "hit" + * endWord = "cog" + * wordList = ["hot","dot","dog","lot","log"] + * + * Output: [] + * + * Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. + * + * 使用了广度优化遍历方案,会超时 + *+ * + * @param beginWord + * @param endWord + * @param wordList + * @return + */ + public List
+ * Given two words (beginWord and endWord), and a dictionary, find the length + * of shortest transformation sequence from beginWord to endWord, such that: + * + * - Only one letter can be changed at a time + * - Each intermediate word must exist in the dictionary + * + * For example, + * + * Given: + * start = "hit" + * end = "cog" + * dict = ["hot","dot","dog","lot","log"] + * As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", + * return its length 5. + * + * Note: + * - Return 0 if there is no such transformation sequence. + * - All words have the same length. + * - All words contain only lowercase alphabetic characters. + * + * Ŀ⣺ + * ʣbeginWordendWordһֵ䣬ҴbeginWordת͵endWord̳ȣ + * - һֻһĸԱı + * - ÿмֱڴʵ + * + * ע⣺ + * - ı任У0 + * - еʾͬijȡ + * - еֻСдĸַ + * + * ˼· + * Ż + *+ * + * @param beginWord + * @param endWord + * @param wordList + * @return + */ + public int ladderLength(String beginWord, String endWord, List
+ * Given an unsorted array of integers, find the length of the longest consecutive elements sequence. + * + * Your algorithm should run in O(n) complexity. + * + * Example: + * + * Input: [100, 4, 200, 1, 3, 2] + * Output: 4 + * Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. + * + * 这道题要求求最长连续序列,并给定了O(n)复杂度限制,我们的思路是,使用一个集合HashSet存入所有的数字, + * 然后遍历数组中的每个数字,如果其在集合中存在,那么将其移除,然后分别用两个变量pre和next算出其前一个 + * 数跟后一个数,然后在集合中循环查找,如果pre在集合中,那么将pre移除集合,然后pre再自减1,直至pre不在 + * 集合之中,对next采用同样的方法,那么next-pre-1就是当前数字的最长连续序列,更新res即可。这里再说下, + * 为啥当检测某数字在集合中存在当时候,都要移除数字。这是为了避免大量的重复计算,就拿题目中的例子来说吧, + * 我们在遍历到4的时候,会向下遍历3,2,1,如果都不移除数字的话,遍历到1的时候,还会遍历2,3,4。同样, + * 遍历到3的时候,向上遍历4,向下遍历2,1,等等等。如果数组中有大量的连续数字的话,那么就有大量的重复计算, + * 十分的不高效,所以我们要从HashSet中移除数字 + *+ * + * @param nums + * @return + */ + public int longestConsecutive(int[] nums) { + int res = 0; + Set
+ * Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. + * A region is captured by flipping all 'O's into 'X's in that surrounded region. + * + * For example, + * X X X X + * X O O X + * X X O X + * X O X X + * + * After running your function, the board should be: + * X X X X + * X X X X + * X X X X + * X O X X + * + * Ŀ⣺ + * һά'X''O'ԱXΧOX + * ˼· + * ȶȱķʽҳXΧOΪ$ + *+ * + * @param board + */ + void solve(char[][] board) { + + // У + if (board == null || board.length < 1 || board[0].length < 1) { + return; + } + + // һк + for (int i = 0; i < board[0].length; i++) { + dfs(board, 0, i); + dfs(board, board.length - 1, i); + } + + // һкһ + for (int i = 1; i < board.length - 1; i++) { + dfs(board, i, 0); + dfs(board, i, board[0].length - 1); + } + + + for (int i = 0; i < board.length; ++i) { + for (int j = 0; j < board[i].length; ++j) { + if (board[i][j] == 'O') { + board[i][j] = 'X'; + } + if (board[i][j] == '$') { + board[i][j] = 'O'; + } + } + } + } + + void dfs(char[][] board, int i, int j) { + if (board[i][j] == 'O') { + board[i][j] = '$'; + if (i > 0 && board[i - 1][j] == 'O') { + dfs(board, i - 1, j); + } + if (j < board[i].length - 1 && board[i][j + 1] == 'O') { + dfs(board, i, j + 1); + } + if (i < board.length - 1 && board[i + 1][j] == 'O') { + dfs(board, i + 1, j); + } + if (j > 1 && board[i][j - 1] == 'O') { + dfs(board, i, j - 1); + } + } + } +} diff --git a/[0130][Surrounded Regions]/src/Solution2.java b/[0130][Surrounded Regions]/src/Solution2.java new file mode 100644 index 0000000..3308a10 --- /dev/null +++ b/[0130][Surrounded Regions]/src/Solution2.java @@ -0,0 +1,258 @@ +import java.util.LinkedList; +import java.util.List; + +/** + * Author: + * Date: 2015-06-22 + * Time: 08:51 + * Declaration: All Rights Reserved !!! + */ +public class Solution2 { + /** + *
+ * Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. + * A region is captured by flipping all 'O's into 'X's in that surrounded region. + * + * For example, + * X X X X + * X O O X + * X X O X + * X O X X + * + * After running your function, the board should be: + * X X X X + * X X X X + * X X X X + * X O X X + * + * Ŀ⣺ + * һά'X''O'ԱXΧOX + * ˼· + * ùȱķʽҲԲóȵķʽջ,dzеıΧĵ㣬ʣµľDzΧĵ + *+ * + * @param board + */ + //////////////////////////////////////////////////////////////////////////////////////////////// + // ùȶȱķʽҳеġΧĵ + //////////////////////////////////////////////////////////////////////////////////////////////// + public void solve(char[][] board) { + // У + if (board == null || board.length < 1 || board[0].length < 1) { + return; + } + + boolean[][] visited = new boolean[board.length][board[0].length]; + // ʱΧһȦԪ + List
+ * Given a string s, partition s such that every substring of the partition is a palindrome. + * + * Return all possible palindrome partitioning of s. + * + * Example: + * + * Input: "aab" + * Output: + * [ + * ["aa","b"], + * ["a","a","b"] + * ] + * + * 解决方案:可以使用回溯法 + * TODO : 可以构建一个回文表,再进行判定 + *+ * + * @param s + * @return + */ + public List
+ * Given a string s, partition s such that every substring of the partition is a palindrome.
+ *
+ * Return the minimum cuts needed for a palindrome partitioning of s.
+ *
+ * Example:
+ *
+ * Input: "aab"
+ * Output: 1
+ * Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.
+ *
+ * 分析
+ * 定义状态f(i,j) 表示区间[i,j] 之间最小的cut 数,则状态转移方程为
+ * f(i; j) = min {f(i; k) + f(k + 1; j)} ; i k j; 0 i j < n
+ * 这是一个二维函数,实际写代码比较麻烦。
+ * 所以要转换成一维DP。如果每次,从i 往右扫描,每找到一个回文就算一次DP 的话,就可以
+ * 转换为f(i)= 区间[i, n-1] 之间最小的cut 数,n 为字符串长度,则状态转移方程为
+ * f(i) = min {f(j + 1) + 1} ; i <= j < n TODO 怎么理解?
+ * 一个问题出现了,就是如何判断[i,j] 是否是回文?每次都从i 到j 比较一遍?太浪费了,这
+ * 里也是一个DP 问题。
+ * 定义状态P[i][j] = true if [i,j] 为回文,那么
+ * P[i][j] = str[i] == str[j] && P[i+1][j-1]
+ *
+ * https://www.cnblogs.com/grandyang/p/4271456.html
+ *
+ *
+ * @param s
+ * @return
+ */
+ public int minCut(String s) {
+ final int n = s.length();
+
+ int[] dp = new int[n];
+ boolean[][] p = new boolean[n][];
+
+ for (int i = 0; i < n; ++i) {
+ dp[i] = i;
+ p[i] = new boolean[n];
+
+ for (int j = 0; j <= i; ++j) {
+ if (s.charAt(i) == s.charAt(j) && (i - j < 2 || p[j + 1][i - 1])) {
+ p[j][i] = true;
+ dp[i] = (j == 0) ? 0 : Math.min(dp[i], dp[j - 1] + 1);
+ }
+ }
+ }
+
+ return dp[n - 1];
+ }
+}
diff --git a/[0132][Palindrome Partitioning II]/src/Solution2.java b/[0132][Palindrome Partitioning II]/src/Solution2.java
new file mode 100644
index 0000000..c0611da
--- /dev/null
+++ b/[0132][Palindrome Partitioning II]/src/Solution2.java
@@ -0,0 +1,62 @@
+/**
+ * @author: wangjunchao(王俊超)
+ * @time: 2019-06-24 19:22
+ **/
+public class Solution2 {
+ /**
+ *
+ * Given a string s, partition s such that every substring of the partition is a palindrome.
+ *
+ * Return the minimum cuts needed for a palindrome partitioning of s.
+ *
+ * Example:
+ *
+ * Input: "aab"
+ * Output: 1
+ * Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.
+ *
+ * 分析
+ * 定义状态f(i,j) 表示区间[i,j] 之间最小的cut 数,则状态转移方程为
+ * f(i; j) = min {f(i; k) + f(k + 1; j)} ; i k j; 0 i j < n
+ * 这是一个二维函数,实际写代码比较麻烦。
+ * 所以要转换成一维DP。如果每次,从i 往右扫描,每找到一个回文就算一次DP 的话,就可以
+ * 转换为f(i)= 区间[i, n-1] 之间最小的cut 数,n 为字符串长度,则状态转移方程为
+ * f(i) = min {f(j + 1) + 1} ; i <= j < n TODO 怎么理解?
+ * 一个问题出现了,就是如何判断[i,j] 是否是回文?每次都从i 到j 比较一遍?太浪费了,这
+ * 里也是一个DP 问题。
+ * 定义状态P[i][j] = true if [i,j] 为回文,那么
+ * P[i][j] = str[i] == str[j] && P[i+1][j-1]
+ *
+ * https://www.cnblogs.com/grandyang/p/4271456.html
+ *
+ *
+ * @param s
+ * @return
+ */
+ public int minCut(String s) {
+ final int n = s.length();
+
+ int[] f = new int[n + 1];
+ boolean[][] p = new boolean[n][];
+ //the worst case is cutting by each char
+ // 最后一个f[n]=-1
+ for (int i = 0; i <= n; i++) {
+ // [n-1, n-2, ..., 1, 0, -1],为了后面做切分
+ f[i] = n - 1 - i;
+ }
+ for (int i = n - 1; i >= 0; i--) {
+ p[i] = new boolean[n];
+
+ for (int j = i; j < n; j++) {
+ // j - i < 2 : 表示j在i位置或者j在i之后一个位置
+ // p[i + 1][j - 1] : [i+1, j-1]是回文
+ if (s.charAt(i) == s.charAt(j) && (j - i < 2 || p[i + 1][j - 1])) {
+ p[i][j] = true;
+ f[i] = Math.min(f[i], f[j + 1] + 1);
+ }
+ }
+ }
+
+ return f[0];
+ }
+}
diff --git a/[0134][Gas Station]/[0134][Gas Station].iml b/[0134][Gas Station]/[0134][Gas Station].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0134][Gas Station]/[0134][Gas Station].iml
@@ -0,0 +1,13 @@
+
++ * There are N gas stations along a circular route, where the amount + * of gas at station i is gas[i]. + * + * You have a car with an unlimited gas tank and it costs cost[i] of gas + * to travel from station i to its next station (i+1). You begin the journey + * with an empty tank at one of the gas stations. + * + * Return the starting gas station's index if you can travel around the + * circuit once, otherwise return -1. + * + * Note: + * - The solution is guaranteed to be unique. + * + * Ŀ⣺ + * ػ·Nվڳվigas[i] + * гޣӼվiһվվi+1Ҫcost[i]塣 + * 㿪ʼóʱǿյġصʼվָѡһ㿪ʼΣ + * ΧһΣͷؿʼļվ-1 + * + * ע⣺ + * - 𰸱֤Ψһ + * + * ˼· + * վ i վ k ֮ǰȻܱ֤ûk ˡ + * ô˵ diff[i] + diff[i+1] + ... + diff[k] < 0diff[k]⣬diff[i] + * ʼۼӶ >= 0ġҲ˵diff[i] Ҳ >= 0ģʱǻбҪվ i + 1 + * ϸһ֪ҪǴվ i+1վkûվkͼ + * ˣΪټվ i ͡ + * + * ˣǷֵk վi k Щվ㶼Ϊˣ϶ + * ֻҪk+1վ㳢Լɣ˽ⷨʱ临ӶȴO(n2) O(2n)֮ + * O(2n)Ϊk+1վΪʼվȦk֤k+1Ƿ㡣 + * + * ȵȣҪ + * ģһ¹̣ + * a. ʼվ0ʼվ賵վpˣ + * sum1 = diff[0] +diff[1] + ... + diff[p]֪sum1 < 0 + * + * b. ǽp+1Ϊʼվqվֿˣ + * sum2 = diff[p+1] +diff[p+2] + ... + diff[q]֪sum2 < 0 + * + * c. q+1Ϊʼվһֱδѭĩվû + * sum3 = diff[q+1] +diff[q+2] + ... + diff[size-1]֪sum3 >= 0 + * + * Ҫ֪ܷ q վʵsum3 Ļϣμ diff[0] diff[q] + * sum3ǷС0֮ǰѾ֪ diff[0] diff[p-1] · + * һֱַǸֻҪsum3 + sum1Ƿ <0֪ܲܿ p+1վˡ + * ܴp+1վֻҪsum3 + sum1 + sum2 Ƿ < 0֪ܲܿqվˡ + * + * Ϊ sum1, sum2 < 0 sum3 + sum1 + sum2 >=0 ô + * sum3 + sum1 Ȼ >= 0Ҳ˵ֻҪsum3 + sum1 + sum2 >=0Ȼܿqվ + * sum3 + sum1 + sum2 ʵ diffܺ TotalԪѾˡ + * Total ܷ >= 0Ƿվ ֱҪ + * + * ʱ临ӶȽһO(2n) O(n) + *+ * + * @param gas + * @param cost + * @return + */ + public int canCompleteCircuit(int[] gas, int[] cost) { + // + if (gas == null || cost == null || gas.length == 0 || gas.length != cost.length) { + return -1; + } + + // ¼ʵʼ + int start = 0; + // ӵĵֵܲ + int total = 0; + // startλÿʼӵĵֵܲ + int sum = 0; + + for (int i = 0; i < gas.length; i++) { + total += (gas[i] - cost[i]); + + // û + if (sum < 0) { + // е + sum = gas[i] - cost[i]; + // ¼µλ + start = i; + } else { + // лͣе + sum += (gas[i] - cost[i]); + } + } + + return total >= 0 ? start : -1; + } + + + /** + * ķᳬʱO(N^2)ʱ临Ӷ + */ + public int canCompleteCircuit2(int[] gas, int[] cost) { + // + if (gas == null || cost == null || gas.length == 0 || gas.length != cost.length) { + return -1; + } + + // ʣµ壬ʼʱΪ0 + int leftGas = 0; + // ʼվ + int start = 0; + // վ + int end = 1; + + // δһ + while (start < gas.length) { + + // һվ + leftGas = gas[start] - cost[start]; + + // ߵһվ + if (leftGas > 0) { + // ¼һվ + end = (start + 1) % gas.length; + + // һֱԵһվͳв + while (start != end && (leftGas += (gas[end] - cost[end])) >= 0) { + end = (end + 1) % gas.length; + } + + // ˵Ѿһ + if (start == end) { + return start; + } + } + + start++; + } + + return -1; + } +} diff --git a/[0135][Candy]/[0135][Candy].iml b/[0135][Candy]/[0135][Candy].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0135][Candy]/[0135][Candy].iml @@ -0,0 +1,13 @@ + +
+ * There are N children standing in a line. Each child is assigned a rating value. + * + * You are giving candies to these children subjected to the following requirements: + * + * 1. Each child must have at least one candy. + * 2. Children with a higher rating get more candies than their neighbors. + * What is the minimum candies you must give? + * + * Example 1: + * + * Input: [1,0,2] + * Output: 5 + * Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively. + * Example 2: + * + * Input: [1,2,2] + * Output: 4 + * Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively. + * The third child gets 1 candy because it satisfies the above two conditions. + *+ * + * @param ratings + * @return + */ + public int candy(int[] ratings) { + if (ratings == null || ratings.length < 1) { + return 0; + } + + + int[] increment = new int[ratings.length]; + // 左右各扫描一遍 + for (int i = 1, inc = 1; i < ratings.length; i++) { + // 右边的孩子分数比左边的孩子分数高 + if (ratings[i] > ratings[i - 1]) { + // 右边的孩子比左边的孩子多发至少一个糖果 + increment[i] = increment[i - 1] + 1; + } +// // 右边的孩子分数与左边的孩子分数相等,相等可以少发 +// else if (ratings[i] == ratings[i - 1]) { +// // 右边和左边的孩子增同样多颗糖 +// increment[i] = increment[i - 1]; +// } + // 可以不处理 +// else{ +// increment[i] = 0; +// } + } + + // 从右到左进行处理 + for (int i = ratings.length - 2, inc = 1; i >= 0; i--) { + // 左边的孩子分数比右边高 + if (ratings[i] > ratings[i + 1]) { + increment[i] = Math.max(increment[i], increment[i + 1] + 1); + } + // +// else if (ratings[i] == ratings[i + 1]) { +// // 总是成立了 +// increment[i] = increment[i - 1]; +// } + // ratings[i] < ratings[i + 1] 不需要操作 + } + + int sum = ratings.length; + for (int n : increment) { + sum += n; + } + return sum; + } +} diff --git a/[0136][Single Number]/[0136][Single Number].iml b/[0136][Single Number]/[0136][Single Number].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0136][Single Number]/[0136][Single Number].iml @@ -0,0 +1,13 @@ + +
+ * Note: Your algorithm should have a linear runtime complexity. + * Could you implement it without using extra memory? + *
+ * һ飬ÿԪض2γеһҳֻһε + * ע⣺㷨ʱ临ӶȣԲʹöռʵ + *
+ * ˼·ʹ
+ *
+ * @param nums
+ * @return
+ */
+ public int singleNumber(int[] nums) {
+
+ if (nums == null || nums.length < 1) {
+ throw new IllegalArgumentException("nums should contain at least one element");
+ }
+
+
+ for (int i = 1; i < nums.length; i++) {
+ nums[0] ^= nums[i];
+ }
+ return nums[0];
+ }
+}
diff --git a/[0137][Single Number II]/[0137][Single Number II].iml b/[0137][Single Number II]/[0137][Single Number II].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0137][Single Number II]/[0137][Single Number II].iml
@@ -0,0 +1,13 @@
+
+
+ * A linked list is given such that each node contains an additional random + * pointer which could point to any node in the list or null. + * + * Return a deep copy of the list. + * + * Ŀ⣺ + * һһָnullĽָ룬 + * + * ˼· + * һƽ㣬ƵĽڴƵĽȻһ + * ڶָ + * ָƺ + *+ * + * @param head + * @return + */ + public RandomListNode copyRandomList(RandomListNode head) { + if (head == null) { + return null; + } + + copyNode(head); + linkRandomPointer(head); + + return splitList(head); + } + + /** + * ƽ㣬ƵĽڴƵĽȻһ + * + * @param head ͷ + */ + public void copyNode(RandomListNode head) { + // ¼ǰҪƵ + RandomListNode node = head; + while (node != null) { + // һµĽ + RandomListNode copyNode = new RandomListNode(node.label); + // 㴮ӵƵĽȻɵ + copyNode.next = node.next; + node.next = copyNode; + node = copyNode.next; + } + } + + /** + * ָ + * + * @param head ͷ + */ + public void linkRandomPointer(RandomListNode head) { + // ¼ǰҪƵ + RandomListNode node = head; + while (node != null) { + // ָָijĽ + if (node.random != null) { + // nodeƽָ + node.next.random = node.random.next; + } + + // ָһƵĽ + node = node.next.next; + } + } + + /** + * ֣ԭԭװ + * + * @param head ͷ + * @return ͷ + */ + public RandomListNode splitList(RandomListNode head) { + // ͷ + RandomListNode copyHead = head.next; + // ǰıƵĽ + RandomListNode node = head; + // ǰƵĽ + RandomListNode copy; + + while (node != null) { + // ָƽ + copy = node.next; + + // node.nextָһƵĽ + node.next = copy.next; + + // һƵĽ㲻Ϊnull + if (node.next != null) { + // copy.nextָһƵĽ + copy.next = node.next.next; + } + + // nodeָһҪıƽ + node = node.next; + } + return copyHead; + } +} diff --git a/[0139][Word Break]/[0139][Word Break].iml b/[0139][Word Break]/[0139][Word Break].iml new file mode 100644 index 0000000..73f33e3 --- /dev/null +++ b/[0139][Word Break]/[0139][Word Break].iml @@ -0,0 +1,23 @@ + +
+ * ԭ + * Given a linked list, determine if it has a cycle in it. + * Follow up: + * Can you solve it without using extra space? + * + * Ŀ + * һжǷл + * + * ˼· + * ָ(fast, slow)ʼֵָͷslowÿǰһfastÿǰڻ + * fastضȽ뻷slow뻷ָض + *+ * + * @param head + * @return + */ + 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 (slow == fast) { + return true; + } + } + + return false; + } + + public boolean hasCycle2(ListNode head) { + + ListNode fast = head; + ListNode slow = head; + + while (fast != null && fast.next != null) { + fast = fast.next.next; + slow = slow.next; + if (slow == fast) { + break; + } + } + + return !(fast == null || fast.next == null); + } +} diff --git a/[0142][Linked List Cycle II]/[0142][Linked List Cycle II].iml b/[0142][Linked List Cycle II]/[0142][Linked List Cycle II].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0142][Linked List Cycle II]/[0142][Linked List Cycle II].iml @@ -0,0 +1,13 @@ + +
+ * Given a singly linked list L: L0L1Ln-1Ln, + * reorder it to: L0LnL1Ln-1L2Ln-2 + * + * You may not modify the values in the list's nodes, only nodes itself may be changed. + * + * Example 1: + * + * Given 1->2->3->4, reorder it to 1->4->2->3. + * Example 2: + * + * Given 1->2->3->4->5, reorder it to 1->5->2->4->3. + * + * ˼· + * 1ҵм + * 2㣬ͽм֮в֣ + * + *+ * + * @param head + */ + public void reorderList(ListNode head) { + if (head == null || head.next == null) { + return; + } + + ListNode root = new ListNode(-1); + root.next = head; + ListNode fast = head; + // мǰ + ListNode slow = root; + + while (fast != null && fast.next != null) { + fast = fast.next.next; + slow = slow.next; + } + + // ˵żڵ + if (fast == null) { + root.next = slow.next; + slow.next = null; + + } else { // + slow = slow.next; + root.next = slow.next; + slow.next = null; + } + + // һҪͷ巨 + fast = root.next; + ListNode tmp; + // 벿 + while (fast.next != null) { + tmp = fast.next; + fast.next = tmp.next; + tmp.next = root.next; + root.next = tmp; + } + + slow = head; + fast = root.next; + + while (fast != null) { + tmp = fast.next; + fast.next = slow.next; + slow.next = fast; + slow = slow.next.next; + fast = tmp; + } + } +} diff --git a/[0144][Binary Tree Preorder Traversal]/[0144][Binary Tree Preorder Traversal].iml b/[0144][Binary Tree Preorder Traversal]/[0144][Binary Tree Preorder Traversal].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0144][Binary Tree Preorder Traversal]/[0144][Binary Tree Preorder Traversal].iml @@ -0,0 +1,13 @@ + +
+ * Given a binary tree, return the postorder traversal of its nodes' values.
+ *
+ * For example:
+ * Given binary tree {1,#,2,3},
+ * 1
+ * \
+ * 2
+ * /
+ * 3
+ * return [3,2,1].
+ *
+ * Note: Recursive solution is trivial, could you do it iteratively?
+ *
+ * Ŀ⣺
+ * һŶĺĽֵ
+ *
+ * ע⣺
+ * - ݹⷨף볢ʽ
+ *
+ * ˼·
+ * ǵݹ
+ * ݺ˳ȷٷʸڵ㣬ÿ˵
+ * ְͬķ˳бķǵݹʵ˵ҪһЩҪ֤
+ * ʺܷʣ˼·£
+ *
+ * һڵP
+ * 1ȽڵPջ
+ * 2PӺҺӣPӻҺӣҺѾ
+ * ֱڵPջջڵPΪһĽڵ㣬ٽʱ
+ * ջΪǰڵ㣻
+ * 32еPҺӺջǰڵΪջ㣬
+ * ֮ظ2
+ * 4ֱջգ
+ *
+ *
+ * @param root
+ * @return
+ */
+ public List+ * Design and implement a data structure for Least Recently Used (LRU) cache. + * It should support the following operations: get and put. + * + * get(key) - Get the value (will always be positive) of the key if the key exists + * in the cache, otherwise return -1. + * put(key, value) - Set or insert the value if the key is not already present. When + * the cache reached its capacity, it should invalidate the least recently used item + * before inserting a new item. + * + * The cache is initialized with a positive capacity. + * + * Follow up: + * Could you do both operations in O(1) time complexity? + * + * Example: + * + * LRUCache cache = new LRUCache( 2 );// capacity + * + * cache.put(1,1); + * cache.put(2,2); + * cache.get(1); // returns 1 + * cache.put(3,3); // evicts key 2 + * cache.get(2); // returns -1 (not found) + * cache.put(4,4); // evicts key 1 + * cache.get(1); // returns -1 (not found) + * cache.get(3); // returns 3 + * cache.get(4); // returns 4 + *+ * + * @param capacity + */ + + private int capacity; + + + public LRUCache(int capacity) { + super(capacity, 0.75F, true); + this.capacity = capacity; + } + + public int get(int key) { + Integer value = super.get(key); + if (value == null) { + return -1; + } else { + return value; + } + } + + public void put(int key, int value) { + super.put(key, value); + } + + + @Override + protected boolean removeEldestEntry(Map.Entry
+ * Sort a linked list in O(n log n) time using constant space complexity. + * + * Example 1: + * + * Input: 4->2->1->3 + * Output: 1->2->3->4 + * Example 2: + * + * Input: -1->5->3->4->0 + * Output: -1->0->3->4->5 + * + * 使用链表的归并排序可以解决 + *+ * + * @param head + * @return + */ + public ListNode sortList(ListNode head) { + + if (head == null || head.next == null) { + return head; + } + return mergeSort(head); + } + + private ListNode mergeSort(ListNode head) { + + if (head == null || head.next == null) { + return head; + } + + ListNode p = head; + ListNode q = head; + // 记录前驱 + ListNode r = null; + + // 将链表分害割成两半 + while (p != null && p.next != null) { + p = p.next.next; + r = q; + q = q.next; + } + + r.next = null; + + // 两个链接分别进行排序 + ListNode h1 = mergeSort(head); + ListNode h2 = mergeSort(q); + + return merge(h1, h2); + } + + private ListNode merge(ListNode l1, ListNode l2) { + + ListNode head = new ListNode(0); + ListNode p = head; + while (l1 != null && l2 != null) { + if (l1.val <= l2.val) { + p.next = l1; + l1 = l1.next; + } else { + p.next = l2; + l2 = l2.next; + } + + p = p.next; + } + + if (l1 != null) { + p.next = l1; + } else { + p.next = l2; + } + + return head.next; + } +} diff --git a/[0150][Evaluate Reverse Polish Notation]/[0150][Evaluate Reverse Polish Notation].iml b/[0150][Evaluate Reverse Polish Notation]/[0150][Evaluate Reverse Polish Notation].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0150][Evaluate Reverse Polish Notation]/[0150][Evaluate Reverse Polish Notation].iml @@ -0,0 +1,13 @@ + +
+ * Evaluate the value of an arithmetic expression in Reverse Polish Notation. + * Valid operators are +, -, *, /. Each operand may be an integer or another expression. + * + * Some examples: + * ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 + * ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6 + * + * Ŀ⣺ + * 沨ʽֵЧǣ+-*/ÿҪôһҪôһʽ + * + * ˼· + * ʹջв + *+ * + * @param tokens + * @return + */ + public int evalRPN(String[] tokens) { + // У + if (tokens == null || tokens.length < 1) { + throw new IllegalArgumentException(); + } + + int op1; + int op2; + // ջ + Stack
+ * A peak element is an element that is greater than its neighbors. + * + * Given an input array where num[i] num[i+1], find a peak element and return its index. + * + * The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. + * + * You may imagine that num[-1] = num[n] = -. + * + * For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return + * the index number 2. + * + * Note: + * Your solution should be in logarithmic complexity. + * + * Ŀ⣺ + * ֵԪءֵָھӵԪ + * + * һnum[i] num[i+1]ҵһֵԪز±ꡣ + * + * ֵܰ·һɡ + * + * Լnum[-1] = num[n] = -ޣʼԪصĩβԪصҲΪ + * + * 磬[1, 2, 3, 1]У3ǷֵԪأĺӦ÷±2 + * + * ע⣺ + * ΪӶȡ + *+ * + * @param nums + * @return + */ + public int findPeakElement(int[] nums) { + + if (nums == null || nums.length < 1) { + return -1; + } + + if (nums.length == 1) { + return 0; + } + + if (nums[0] > nums[1]) { + return 0; + } else if (nums[nums.length - 1] > nums[nums.length - 2]) { + return nums.length - 1; + } + + + for (int i = 1; i < nums.length - 1; i++) { + if (nums[i] > nums[i - 1] && nums[i] > nums[i + 1]) { + return i; + } + } + + return -1; + } + +} diff --git a/[0167][Two Sum II - Input array is sorted]/[0167][Two Sum II - Input array is sorted].iml b/[0167][Two Sum II - Input array is sorted]/[0167][Two Sum II - Input array is sorted].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0167][Two Sum II - Input array is sorted]/[0167][Two Sum II - Input array is sorted].iml @@ -0,0 +1,13 @@ + +
+ * For example, the 32-bit integer ��11' has binary representation 00000000000000000000000000001011, + * so the function should return 3. + *
+ * ���������е�λ��
+ *
+ * @param n
+ * @return
+ */
+ // you need to treat n as an unsigned value
+ public int hammingWeight(int n) {
+
+ int count = 0;
+ while (n != 0) {
+ count++;
+ n = (n - 1) & n;
+ }
+ return count;
+ }
+}
diff --git a/[0198][House Robber]/[0198][House Robber].iml b/[0198][House Robber]/[0198][House Robber].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0198][House Robber]/[0198][House Robber].iml
@@ -0,0 +1,13 @@
+
+
+ * Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. + * An island is surrounded by water and is formed by connecting adjacent lands horizontally + * or vertically. You may assume all four edges of the grid are all surrounded by water. + * + * Example 1: + * 11110 + * 11010 + * 11000 + * 00000 + * Answer: 1 + * + * Example 2: + * 11000 + * 11000 + * 00100 + * 00011 + * Answer: 3 + * + * ��Ŀ���⣺ + * ������һ����ά����ĵ�ͼ��'1'��½�أ���0��ˮ�����������������������������滷ˮ�� + * �������ڵ�½��ˮƽ��ֱ���Ӷ��γɵġ�����Լ��������������ĸ��߶���ˮ��Χ�� + * + * ����˼·�� + * һ��������һ����Ӧ�ķ��ʱ�Ǿ�������ÿ��Ԫ��ʱ�й�����ȱ���������������ȱ�������ͳ�Ƶ�����Ŀ + * + *+ * + * @param grid + * @return + */ + public int numIslands(char[][] grid) { + // ����У�� + if (grid == null || grid.length == 0 || grid[0].length == 0) { + return 0; + } + + // Ԫ��Ĭ��ֵ��false + boolean[][] visited = new boolean[grid.length][grid[0].length]; + + int result = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + // �����λ��û�б����ʹ������Ҵ�λ���ǵ�������¹�����ȱ��� + if (!visited[i][j] && grid[i][j] == '1') { + result++; + bfs(grid, visited, i, j); + } + } + } + return result; + } + + /** + * ����������� + * + * @param grid ���� + * @param visited ���ʱ�Ǿ��� + * @param row ������ + * @param col ������ + */ + private void bfs(char[][] grid, boolean[][] visited, int row, int col) { + + if (row >= 0 && row < grid.length // �кϷ� + && col >= 0 && col < grid[0].length // �кϷ� + && !visited[row][col] // û�з��ʹ� + && grid[row][col] == '1') { // �ǵ���½�� + + // ��Ǵ�λ���Ѿ����ʹ��� + visited[row][col] = true; + + // �� + bfs(grid, visited, row - 1, col); + // �� + bfs(grid, visited, row, col + 1); + // �� + bfs(grid, visited, row + 1, col); + // �� + bfs(grid, visited, row, col - 1); + } + } +} diff --git a/[0201][Bitwise AND Of Numbers Range]/[0201][Bitwise AND Of Numbers Range].iml b/[0201][Bitwise AND Of Numbers Range]/[0201][Bitwise AND Of Numbers Range].iml new file mode 100644 index 0000000..f080bef --- /dev/null +++ b/[0201][Bitwise AND Of Numbers Range]/[0201][Bitwise AND Of Numbers Range].iml @@ -0,0 +1,13 @@ + +
+ * ��ĿҪ�������һ�������������ϸ�����λ�����ֵ�ƽ���ͣ�����������Ϊ1���������Ϊhappy number��
+ * ���������ܴ�ij������ʼ����ѭ����
+ *
+ * @param n
+ * @return
+ */
+ public boolean isHappy(int n) {
+
+ if (n < 1) {
+ return false;
+ }
+
+ // ���ڱ����м���ֵĽ��
+ HashSet
+ * ��Ŀ���⣺����һ���������飬�ж��������Ƿ�����ظ�Ԫ�ء��������������һ�����ֳ������������Σ�
+ * ��ĺ���Ӧ�÷���true�����ÿһ��Ԫ�ض���Ψһ�ģ�����false��
+ *
+ * ����˼·����set���ݽṹ
+ *
+ * @param nums
+ * @return
+ */
+ public boolean containsDuplicate(int[] nums) {
+
+ // Ԫ�ظ�������1�Ž�������IJ���
+ if (nums != null && nums.length > 1) {
+ //����һ��hashSet
+ Set
+ * ��Ŀ���⣺
+ * ����һ����������nums��һ������k�����ҽ�������������ͬ���±�i��j����nums[i] = nums[j]
+ * ����|i-j|<=kʱ����true������false��
+ *
+ * ����˼·��
+ * ��nums[0...n-1]������һ��map�У�(muns[i], i)�������nums[k]�Ѿ����ڣ�
+ * ��Ƚ�֮ǰ���±�����ڵ��±�IJ�ֵ�������ֵ������k��˵��������������������ֵ��
+ * ����ʹ���µ��±���Ϊֵ
+ *
+ * @param nums
+ * @param k
+ * @return
+ */
+ public boolean containsNearbyDuplicate(int[] nums, int k) {
+ // ���������ж�
+ if (nums == null || nums.length < 2 || k < 1) {
+ return false;
+ }
+
+ Map
+ * ����˼·��
+ * ���㷽��Ϊ����1�����+����2�����-�������ι�ͬ�ĸ��������
+ *
+ * @param A
+ * @param B
+ * @param C
+ * @param D
+ * @param E
+ * @param F
+ * @param G
+ * @param H
+ * @return
+ */
+ public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
+ long area = (long) (C - A) * (D - B) + (long) (G - E) * (H - F);
+ // Math.min(C, G) ��ʾ�ұ߱ߵ���С�ı�
+ // Math.max(A, E) ��ʾ��߱ߵ����ı�
+ // ����ļ������������Խ�飬Ҫ�������ݷ�Χ
+ long width = Math.max((long) Math.min(C, G) - (long) Math.max(A, E), 0);
+ // Math.min(D, H) ��ʾ���߱ߵ���С�ı�
+ // Math.max(B, F) ��ʾ�ױ߱ߵ����ı�
+ long height = Math.max((long) Math.min(D, H) - (long) Math.max(B, F), 0);
+
+ System.out.println(width + ":" + height + "=" + width * height);
+
+ return (int) (area - width * height);
+ }
+
+
+}
diff --git a/[0225][Implement Stack Using Queues]/[0225][Implement Stack Using Queues].iml b/[0225][Implement Stack Using Queues]/[0225][Implement Stack Using Queues].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0225][Implement Stack Using Queues]/[0225][Implement Stack Using Queues].iml
@@ -0,0 +1,13 @@
+
+
+ * There are a total of n courses you have to take, labeled from 0 to n-1.
+ *
+ * Some courses may have prerequisites, for example to take course 0 you have to first take
+ * course 1, which is expressed as a pair: [0,1]
+ *
+ * Given the total number of courses and a list of prerequisite pairs, is it possible for
+ * you to finish all courses?
+ *
+ * Example 1:
+ *
+ * Input: 2, [[1,0]]
+ * Output: true
+ * Explanation: There are a total of 2 courses to take.
+ * To take course 1 you should have finished course 0. So it is possible.
+ * Example 2:
+ *
+ * Input: 2, [[1,0],[0,1]]
+ * Output: false
+ * Explanation: There are a total of 2 courses to take.
+ * To take course 1 you should have finished course 0, and to take course 0 you should
+ * also have finished course 1. So it is impossible.
+ * Note:
+ *
+ * The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read
+ * more about how a graph is represented.
+ * You may assume that there are no duplicate edges in the input prerequisites.
+ *
+ * 解题思路:
+ * 使用深度度优先遍历,记录每个访问过的点,如果遍历过程中再次遍历到了已经访问过的点,
+ * 说明有环状依赖,课程安排不合理
+ *
+ */
+
+ public boolean canFinish(int numCourses, int[][] prerequisites) {
+ // 说明没有课程依赖
+ if (prerequisites == null || prerequisites.length == 0) {
+ return true;
+ }
+
+
+ Map
+ * Find the kth largest element in an unsorted array. Note that it is the kth
+ * largest element in the sorted order, not the kth distinct element.
+ *
+ * For example,
+ * Given [3,2,1,5,6,4] and k = 2, return 5.
+ *
+ * Note:
+ * You may assume k is always valid, 1 �� k �� array's length.
+ *
+ * ��Ŀ���⣺
+ * ��һ��δ��������������ҳ���k���Ԫ�ء�ע��������֮��ĵ�k���ǵ�k�����ظ���Ԫ��
+ * ���Լ���kһ������Ч�ģ� 1 �� k �� ���鳤��
+ *
+ * ����˼·��
+ * O(n)�ⷨ������ѡ��QuickSelect���㷨
+ *
+ *
+ * @param nums
+ * @param k
+ * @return
+ */
+ public int findKthLargest(int[] nums, int k) {
+
+ if (k < 1 || nums == null || nums.length < k) {
+ throw new IllegalArgumentException();
+ }
+
+ return findKthLargest(nums, 0, nums.length - 1, k);
+ }
+
+ public int findKthLargest(int[] nums, int start, int end, int k) {
+
+ // ����ֵ
+ int pivot = nums[start];
+ int lo = start;
+ int hi = end;
+
+ while (lo < hi) {
+ // ��С������ֵ�����ƶ����������
+ while (lo < hi && nums[hi] >= pivot) {
+ hi--;
+ }
+ nums[lo] = nums[hi];
+
+ // ����������ֵ�����ƶ��������ұ�
+ while (lo < hi && nums[lo] <= pivot) {
+ lo++;
+ }
+ nums[hi] = nums[lo];
+ }
+
+ nums[lo] = pivot;
+
+ // ����Ѿ��ҵ���
+ if (end - lo + 1 == k) {
+ return pivot;
+ }
+ // ��k�������loλ�õ��ұ�
+ else if (end - lo + 1 > k) {
+ return findKthLargest(nums, lo + 1, end, k);
+ }
+ // ��k�������loλ�õ����
+ else {
+ // k-(end-lo+1)
+ // (end-lo+1)����ʾ��loλ�ÿ�ʼ��endλ�õ�Ԫ�ظ�������������Ұ벿��
+ // ԭ���ĵ�k����k-(end-lo+1)��
+ return findKthLargest(nums, start, lo - 1, k - (end - lo + 1));
+ }
+ }
+}
diff --git a/[0216][Combination Sum III]/[0216][Combination Sum III].iml b/[0216][Combination Sum III]/[0216][Combination Sum III].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0216][Combination Sum III]/[0216][Combination Sum III].iml
@@ -0,0 +1,13 @@
+
+
+ * Find all possible combinations of k numbers that add up to a number n,
+ * given that only numbers from 1 to 9 can be used and each combination
+ * should be a unique set of numbers.
+ *
+ * Ensure that numbers within the set are sorted in ascending order.
+ *
+ * Example 1:
+ * Input: k = 3, n = 7
+ * Output:
+ * [[1,2,4]]
+ *
+ * Example 2:
+ * Input: k = 3, n = 9
+ * Output:
+ * [[1,2,6], [1,3,5], [2,3,4]]
+ *
+ * ��Ŀ���⣺
+ * Ѱ����������k����֮�͵���n����ϣ�ֻ����ʹ������1-9������ÿһ������е�����Ӧ����Ψһ�ġ�
+ * ȷ������е������Ե���˳�����С�
+ *
+ * ����˼·��
+ * ���ݷ�
+ *
+ *
+ * @param k
+ * @param n
+ * @return
+ */
+ public List> combinationSum3(int k, int n) {
+ // ���ڱ������н��
+ List
> result = new LinkedList<>();
+ // ���ڱ����м���
+ List
> result) {
+ // �������һ��Ԫ��
+ if (cur == k) {
+ // remainderΪ���һ����Ԫ�ص�ֵ�����������ǰһ����Ԫ�ص�ֵ�����Ҳ��ܳ���9
+ if (remainder > prevVal && remainder <= 9) {
+ // ���Ԫ��ֵ
+ list.add(remainder);
+
+ // ����������µĶ�����
+ List
+ * Find the total area covered by two rectilinear rectangles in a 2D plane.
+ * Each rectangle is defined by its bottom left corner and top right
+ * corner as shown in the figure.
+ *
+ * Assume that the total area is never beyond the maximum possible value of int.
+ *
+ * *****************************(C,D):(3,4)
+ * * *
+ * * *
+ * * *************************************(G,H):(9,2)
+ * * * * *
+ * * * * *
+ * * * * *
+ * * * * *
+ * * *(0,0) * *
+ * ***************************** *
+ * (A,B):(-3,0)* *
+ * * *
+ * * (E,F):(0��-1) *
+ * *************************************
+ *
+ * *************************** ***************************
+ * * D * * H *
+ * * * * *
+ * *A C* *E G*
+ * * * * *
+ * * * * *
+ * * B * * F *
+ * *************************** ***************************
+ *
+ *
+ *
+ *
+ * ��Ŀ���⣺
+ * �������������ܹ����ǵ����
+ *
+ * Implement a basic calculator to evaluate a simple expression string.
+ *
+ * The expression string contains only non-negative integers, +, -, *, / operators
+ * and empty spaces . The integer division should truncate toward zero.
+ *
+ * Example 1:
+ *
+ * Input: "3+2*2"
+ * Output: 7
+ * Example 2:
+ *
+ * Input: " 3/2 "
+ * Output: 1
+ * Example 3:
+ *
+ * Input: " 3+5 / 2 "
+ * Output: 5
+ * Note:
+ *
+ * You may assume that the given expression is always valid.
+ * Do not use the eval built-in library function.
+ * 思路:
+ * 遇到加减就入操作数栈和操作符栈,遇到乘除就计算,将计算结果作为新的字符串的第一个值,后面是处理的字符串
+ * 最后处理所有剩下的加减操作
+ * 如 1+2+3*4+5+6
+ * 处理完第一个*号后
+ * operator: +, +
+ * operand: 1, 2
+ * s: 12+5+6
+ * 整个字符串处理完后
+ * operator: +, +, +, +
+ * operand: 1, 2, 12, 5, 6
+ * 再进行计算
+ *
+ *
+ * @param s
+ * @return
+ */
+ public int calculate(String s) {
+
+ if (s == null || s.length() < 1) {
+ throw new IllegalArgumentException("s: " + s);
+ }
+
+ Deque
+ * 1->2->2->1
+ * 1->2->3->2->1
+ * 先找到第二个2的位置,将2及后面的链逆转,形成新的链A,再按A与原来的链,从头开开始比较
+ *
+ *
+ * @author: wangjunchao(王俊超)
+ * @time: 2018-10-09 11:02
+ **/
+public class Solution {
+ public boolean isPalindrome(ListNode head) {
+
+ // 没有节点或者只有一个结点
+ if (head == null || head.next == null) {
+ return true;
+ }
+
+ int count = 0;
+ ListNode node = head;
+ while (node != null) {
+ count++;
+ node = node.next;
+ }
+
+ // 找反向链的起始位置
+ count = (count + 1) / 2;
+ node = head;
+ while (count > 0) {
+ count--;
+ node = node.next;
+ }
+
+
+ ListNode reverseHead = new ListNode(0);
+ ListNode temp;
+ while (node != null) {
+ temp = node.next;
+ node.next = reverseHead.next;
+ reverseHead.next = node;
+ node = temp;
+ }
+
+ reverseHead = reverseHead.next;
+
+ while (reverseHead != null) {
+ if (head.val != reverseHead.val) {
+ return false;
+ }
+
+ reverseHead = reverseHead.next;
+ head = head.next;
+ }
+
+ return true;
+ }
+}
diff --git "a/\343\200\220234\343\200\221\343\200\220Palindrome Linked List\343\200\221/src/Solution2.java" b/[0234][Palindrome Linked List]/src/Solution2.java
similarity index 100%
rename from "\343\200\220234\343\200\221\343\200\220Palindrome Linked List\343\200\221/src/Solution2.java"
rename to [0234][Palindrome Linked List]/src/Solution2.java
diff --git a/[0234][Palindrome Linked List]/src/Test.java b/[0234][Palindrome Linked List]/src/Test.java
new file mode 100644
index 0000000..28f5ec5
--- /dev/null
+++ b/[0234][Palindrome Linked List]/src/Test.java
@@ -0,0 +1,42 @@
+/**
+ * @author: wangjunchao(王俊超)
+ * @time: 2018-10-09 11:10
+ **/
+public class Test {
+ public static void main(String[] args) {
+ test1();
+ test2();
+ test3();
+ }
+
+ public static void test1() {
+ Solution solution = new Solution();
+ ListNode head = new ListNode(1);
+ head.next = new ListNode(2);
+ System.out.println(solution.isPalindrome(head));
+ }
+
+ public static void test2() {
+ Solution solution = new Solution();
+
+ ListNode head = new ListNode(1);
+ head.next = new ListNode(2);
+ head.next.next = new ListNode(2);
+ head.next.next.next = new ListNode(1);
+ head.next.next.next.next = new ListNode(2);
+ head.next.next.next.next.next = new ListNode(2);
+ head.next.next.next.next.next.next = new ListNode(1);
+ System.out.println(solution.isPalindrome(head));
+ }
+
+ public static void test3() {
+ Solution solution = new Solution();
+
+ ListNode head = new ListNode(1);
+ head.next = new ListNode(2);
+ head.next.next = new ListNode(2);
+ head.next.next.next = new ListNode(1);
+
+ System.out.println(solution.isPalindrome(head));
+ }
+}
diff --git a/[0235][Lowest Common Ancestor of a Binary Search Tree]/[0235][Lowest Common Ancestor of a Binary Search Tree].iml b/[0235][Lowest Common Ancestor of a Binary Search Tree]/[0235][Lowest Common Ancestor of a Binary Search Tree].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0235][Lowest Common Ancestor of a Binary Search Tree]/[0235][Lowest Common Ancestor of a Binary Search Tree].iml
@@ -0,0 +1,13 @@
+
+
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * int val;
+ * ListNode next;
+ * ListNode(int x) { val = x; }
+ * }
+ *
+ *
+ * @author: wangjunchao(王俊超)
+ * @time: 2018-10-10 09:57
+ **/
+class Solution {
+ public void deleteNode(ListNode node) {
+
+ if (node == null || node.next == null) {
+ return;
+ }
+
+ ListNode prev = node;
+ while (node.next != null) {
+ node.val = node.next.val;
+ prev = node;
+ node = node.next;
+
+
+ }
+
+ prev.next = null;
+ }
+}
\ No newline at end of file
diff --git a/[0237][Delete Node in a Linked List]/src/Test.java b/[0237][Delete Node in a Linked List]/src/Test.java
new file mode 100644
index 0000000..a6ee290
--- /dev/null
+++ b/[0237][Delete Node in a Linked List]/src/Test.java
@@ -0,0 +1,32 @@
+/**
+ * @author: wangjunchao(王俊超)
+ * @time: 2018-10-10 10:01
+ **/
+public class Test {
+ public static void main(String[] args) {
+ ListNode node = new ListNode(4);
+ node.next = new ListNode(5);
+ node.next.next = new ListNode(1);
+ node.next.next.next = new ListNode(9);
+
+ Solution solution = new Solution();
+ solution.deleteNode(node.next);
+
+ print(node);
+ }
+
+ private static void print(ListNode node) {
+ do {
+ if (node == null) {
+ System.out.println("null");
+ } else if (node.next != null) {
+ System.out.print(node.val + "->");
+ node = node.next;
+ } else {
+ System.out.println(node.val + "->null");
+ node = node.next;
+ }
+
+ } while (node != null);
+ }
+}
diff --git a/[0238][Product of Array Except Self]/[0238][Product of Array Except Self].iml b/[0238][Product of Array Except Self]/[0238][Product of Array Except Self].iml
new file mode 100644
index 0000000..c8cb479
--- /dev/null
+++ b/[0238][Product of Array Except Self]/[0238][Product of Array Except Self].iml
@@ -0,0 +1,23 @@
+
+
+ * Given an array nums of n integers where n > 1,
+ * return an array output such that output[i] is equal to the product of all the
+ * elements of nums except nums[i].
+ *
+ * Example:
+ *
+ * Input: [1,2,3,4]
+ * Output: [24,12,8,6]
+ * Note: Please solve it without division and in O(n).
+ *
+ * Follow up:
+ * Could you solve it with constant space complexity? (The output array does not count as
+ * extra space for the purpose of space complexity analysis.)
+ *
+ *
+ * @param nums
+ * @return
+ */
+ public int[] productExceptSelf(int[] nums) {
+ int[] result = new int[nums.length];
+
+ // 记录为0的下票
+ Set
+ * Write an efficient algorithm that searches for a value in an m x n matrix.
+ * This matrix has the following properties:
+ *
+ * Integers in each row are sorted in ascending from left to right.
+ * Integers in each column are sorted in ascending from top to bottom.
+ * Example:
+ *
+ * Consider the following matrix:
+ *
+ * [
+ * [1, 4, 7, 11, 15],
+ * [2, 5, 8, 12, 19],
+ * [3, 6, 9, 16, 22],
+ * [10, 13, 14, 17, 24],
+ * [18, 21, 23, 26, 30]
+ * ]
+ * Given target = 5, return true.
+ *
+ * Given target = 20, return false.
+ *
+ *
+ * @param matrix
+ * @param target
+ * @return
+ */
+ public boolean searchMatrix(int[][] matrix, int target) {
+
+ if (matrix == null || matrix.length == 0) {
+ return false;
+ }
+
+ int i = 0;
+ int j = matrix[0].length - 1;
+ while (i < matrix.length && j > -1) {
+ if (matrix[i][j] == target) {
+ return true;
+ } else if (target < matrix[i][j]) {
+ j--;
+ } else {
+ i++;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/[0241][Different Ways to Add Parentheses]/[0241][Different Ways to Add Parentheses].iml b/[0241][Different Ways to Add Parentheses]/[0241][Different Ways to Add Parentheses].iml
new file mode 100644
index 0000000..c8cb479
--- /dev/null
+++ b/[0241][Different Ways to Add Parentheses]/[0241][Different Ways to Add Parentheses].iml
@@ -0,0 +1,23 @@
+
+
+ * Given a string of numbers and operators, return all possible results from computing all the
+ * different possible ways to group numbers and operators. The valid operators are +, - and *.
+ *
+ * Example 1:
+ *
+ * Input: "2-1-1"
+ * Output: [0, 2]
+ * Explanation:
+ * ((2-1)-1) = 0
+ * (2-(1-1)) = 2
+ * Example 2:
+ *
+ * Input: "2*3-4*5"
+ * Output: [-34, -14, -10, -10, 10]
+ * Explanation:
+ * (2*(3-(4*5))) = -34
+ * ((2*3)-(4*5)) = -14
+ * ((2*(3-4))*5) = -10
+ * (2*((3-4)*5)) = -10
+ * (((2*3)-4)*5) = 10
+ *
+ *
+ * @param input
+ * @return
+ */
+ public List
+ * Given an array of numbers nums, in which exactly two elements appear only
+ * once and all the other elements appear exactly twice. Find the two elements that appear only once.
+ *
+ * Example:
+ *
+ * Input: [1,2,1,3,2,5]
+ * Output: [3,5]
+ * Note:
+ *
+ * The order of the result is not important. So in the above example, [5, 3] is also correct.
+ * Your algorithm should run in linear runtime complexity. Could you implement it using
+ * only constant space complexity?
+ *
+ *
+ * @param nums
+ * @return
+ */
+ public int[] singleNumber(int[] nums) {
+ int xor = nums[0];
+ for (int i = 1; i < nums.length; i++) {
+ xor ^= nums[i];
+ }
+
+ int temp = xor;
+ int count = 0;
+ while ((1 & (temp % 2)) != 1) {
+ count++;
+ temp >>>= 1;
+ }
+
+ int x = 0;
+ int y = 0;
+
+ for (int i : nums) {
+ if (((i >> count) & 1) == 1) {
+ x ^= i;
+ } else {
+ y ^= i;
+ }
+ }
+
+ return new int[]{x, y};
+ }
+}
diff --git a/[0263][Ugly Number]/[0263][Ugly Number].iml b/[0263][Ugly Number]/[0263][Ugly Number].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0263][Ugly Number]/[0263][Ugly Number].iml
@@ -0,0 +1,13 @@
+
+
+ * Given an array nums containing n + 1 integers where each integer is between 1
+ * and n (inclusive), prove that at least one duplicate number must exist. Assume
+ * that there is only one duplicate number, find the duplicate one.
+ *
+ * Example 1:
+ *
+ * Input: [1,3,4,2,2]
+ * Output: 2
+ * Example 2:
+ *
+ * Input: [3,1,3,4,2]
+ * Output: 3
+ * Note:
+ *
+ * You must not modify the array (assume the array is read only).
+ * You must use only constant, O(1) extra space.
+ * Your runtime complexity should be less than O(n2).
+ * There is only one duplicate number in the array, but it could be repeated more than once.
+ *
+ *
+ * @param nums
+ * @return
+ */
+ public int findDuplicate(int[] nums) {
+
+ for (int i = 1; i <= nums.length; i++) {
+ // nums[i - 1] != i ; 当 num[8] = 9 的情况
+ // nums[i - 1] != nums[nums[i - 1] - 1] ; 两个相同的数,位置被占用
+ while (nums[i - 1] != i && nums[i - 1] != nums[nums[i - 1] - 1]) {
+ swap(nums, i - 1, nums[i - 1] - 1);
+ }
+ }
+
+ for (int i = 1; i <= nums.length; i++) {
+ if (nums[i - 1] != i) {
+ return nums[i - 1];
+ }
+ }
+
+ return -1;
+ }
+
+ private void swap(int[] nums, int x, int y) {
+ int temp = nums[x];
+ nums[x] = nums[y];
+ nums[y] = temp;
+ }
+}
diff --git a/[0290][Word Pattern]/[0290][Word Pattern].iml b/[0290][Word Pattern]/[0290][Word Pattern].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0290][Word Pattern]/[0290][Word Pattern].iml
@@ -0,0 +1,13 @@
+
+
+ * You are playing the following Nim Game with your friend: There is a heap of stones on the table,
+ * each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will
+ * be the winner. You will take the first turn to remove the stones.
+ *
+ * Both of you are very clever and have optimal strategies for the game. Write a function to determine
+ * whether you can win the game given the number of stones in the heap.
+ *
+ * Example:
+ *
+ * Input: 4
+ * Output: false
+ * Explanation: If there are 4 stones in the heap, then you will never win the game;
+ * No matter 1, 2, or 3 stones you remove, the last stone will always be
+ * removed by your friend.
+ *
+ * 这题往小说可以追溯到小学奥数或者脑筋急转弯的书中,往大说可以深究到博弈论。然而编程在这里并没有卵用,
+ * 策略在于,因为每个人都取不到4个,假设自己后走,要保证每轮自己和对方取得数量的和是4,这样就能确保每
+ * 轮完后都有4的倍数个石头被取走。这样,如果我们先走的话,先把n除4的余数个石头拿走,这样不管怎样,到最
+ * 后都会留4个下来,对方取1个你就取3个,对方取2个你就取2个,就必赢了。
+ *
+ *
+ * @param n
+ * @return
+ */
+ public boolean canWinNim(int n) {
+ return (n & 0b11) > 0;
+ }
+
+ public boolean canWinNim2(int n) {
+ return n % 4 != 0;
+ }
+}
diff --git a/[0299][Bulls and Cows]/[0299][Bulls and Cows].iml b/[0299][Bulls and Cows]/[0299][Bulls and Cows].iml
new file mode 100644
index 0000000..c70cbf1
--- /dev/null
+++ b/[0299][Bulls and Cows]/[0299][Bulls and Cows].iml
@@ -0,0 +1,21 @@
+
+
+ * Given a non negative integer number num. For every numbers i in the range
+ * 0 ≤ i ≤ num calculate the number of 1's in their binary representation and
+ * return them as an array.
+ *
+ * Example 1:
+ *
+ * Input: 2
+ * Output: [0,1,1]
+ * Example 2:
+ *
+ * Input: 5
+ * Output: [0,1,1,2,1,2]
+ * Follow up:
+ *
+ * It is very easy to come up with a solution with run time O(n*sizeof(integer)).
+ * But can you do it in linear time O(n) /possibly in a single pass?
+ * Space complexity should be O(n).
+ * Can you do it like a boss? Do it without using any builtin function like
+ * __builtin_popcount in c++ or in any other language.
+ *
+ * 思路:
+ * 使用治法,
+ * i为偶数 bit(i) = bit(i/2)
+ * i为奇数 bit(i) = bit(i/2) + 1
+ *
+ *
+ * @param num
+ * @return
+ */
+ public int[] countBits(int num) {
+ if (num < 0) {
+ return new int[0];
+ } else if (num == 0) {
+ return new int[]{0};
+ } else if (num == 1) {
+ return new int[]{0, 1};
+ }
+
+ int[] dp = new int[num + 1];
+ dp[0] = 0;
+ dp[1] = 1;
+ for (int i = 2; i <= num; i++) {
+ dp[i] += dp[i / 2];
+ // 不是偶数,说明其比 i/2多一个一
+ if (i % 2 != 0) {
+ dp[i]++;
+ }
+ }
+
+ return dp;
+ }
+}
diff --git a/[0342][Power of Four]/[0342][Power of Four].iml b/[0342][Power of Four]/[0342][Power of Four].iml
new file mode 100644
index 0000000..f080bef
--- /dev/null
+++ b/[0342][Power of Four]/[0342][Power of Four].iml
@@ -0,0 +1,13 @@
+
+
+ * Given a non-empty array of integers, return the k most frequent elements.
+ *
+ * Example 1:
+ *
+ * Input: nums = [1,1,1,2,2,3], k = 2
+ * Output: [1,2]
+ * Example 2:
+ *
+ * Input: nums = [1], k = 1
+ * Output: [1]
+ * Note:
+ *
+ * You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
+ * Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
+ *
+ *
+ *
+ * @param nums
+ * @param k
+ * @return
+ */
+ public List
+ * Given two arrays, write a function to compute their intersection.
+ *
+ * Example 1:
+ *
+ * Input: nums1 = [1,2,2,1], nums2 = [2,2]
+ * Output: [2,2]
+ * Example 2:
+ *
+ * Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
+ * Output: [4,9]
+ * Note:
+ *
+ * Each element in the result should appear as many times as it shows in both arrays.
+ * The result can be in any order.
+ * Follow up:
+ *
+ * What if the given array is already sorted? How would you optimize your algorithm?
+ * What if nums1's size is small compared to nums2's size? Which algorithm is better?
+ * What if elements of nums2 are stored on disk, and the memory is limited such that
+ * you cannot load all elements into the memory at once?
+ *
+ *
+ * @param nums1
+ * @param nums2
+ * @return
+ */
+ public int[] intersect(int[] nums1, int[] nums2) {
+
+ if (nums1 == null || nums1.length < 1 || nums2 == null || nums2.length < 1) {
+ return new int[0];
+ }
+
+ Map
+ * We are playing the Guess Game. The game is as follows:
+ *
+ * I pick a number from 1 to n. You have to guess which number I picked.
+ *
+ * Every time you guess wrong, I'll tell you whether the number is higher or lower.
+ *
+ * You call a pre-defined API guess(int num) which returns 3 possible results (-1, 1, or 0):
+ *
+ * -1 : My number is lower
+ * 1 : My number is higher
+ * 0 : Congrats! You got it!
+ * Example :
+ *
+ * Input: n = 10, pick = 6
+ * Output: 6
+ *
+ *
+ * @param n
+ * @return
+ */
+ public int guessNumber(int n) {
+ int left = 1;
+ int right = n;
+ while (left <= right) {
+ int mid = left + (right - left) / 2;
+ int result = guess(mid);
+ if (result == 0) {
+ return mid;
+ } else if (result < 0) {
+ right = mid - 1;
+ } else {
+ left = mid + 1;
+ }
+ }
+
+ return 0;
+ }
+}
diff --git a/[0383][Ransom Note]/[0383][Ransom Note].iml b/[0383][Ransom Note]/[0383][Ransom Note].iml
new file mode 100644
index 0000000..c8cb479
--- /dev/null
+++ b/[0383][Ransom Note]/[0383][Ransom Note].iml
@@ -0,0 +1,23 @@
+
+
+ * Given an arbitrary ransom note string and another string containing letters
+ * from all the magazines, write a function that will return true if the ransom
+ * note can be constructed from the magazines ; otherwise, it will return false.
+ *
+ * Each letter in the magazine string can only be used once in your ransom note.
+ *
+ * Note:
+ * You may assume that both strings contain only lowercase letters.
+ *
+ * canConstruct("a", "b") -> false
+ * canConstruct("aa", "ab") -> false
+ * canConstruct("aa", "aab") -> true
+ *
+ *
+ * @param ransomNote
+ * @param magazine
+ * @return
+ */
+ public boolean canConstruct(String ransomNote, String magazine) {
+ // 假设输入都是合法的
+
+ int[] chars = new int[26];
+
+ for (int i = 0; i < magazine.length(); i++) {
+ chars[magazine.charAt(i) - 'a']++;
+ }
+
+ for (int i = 0; i < ransomNote.length(); i++) {
+ chars[ransomNote.charAt(i) - 'a']--;
+ }
+
+ for (int n : chars) {
+ if (n < 0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/[0384][Shuffle an Array]/[0384][Shuffle an Array].iml b/[0384][Shuffle an Array]/[0384][Shuffle an Array].iml
new file mode 100644
index 0000000..c8cb479
--- /dev/null
+++ b/[0384][Shuffle an Array]/[0384][Shuffle an Array].iml
@@ -0,0 +1,23 @@
+
+
+ * // Init an array with set 1, 2, and 3.
+ * int[] nums = {1,2,3};
+ * Solution solution = new Solution(nums);
+ *
+ * // Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3]
+ * must equally likely to be returned.
+ * solution.shuffle();
+ *
+ * // Resets the array back to its original configuration [1,2,3].
+ * solution.reset();
+ *
+ * // Returns the random shuffling of array [1,2,3].
+ * solution.shuffle();
+ *
+ *
+ * @param nums
+ */
+ public Solution(int[] nums) {
+ original = nums;
+ }
+
+ /**
+ * Resets the array to its original configuration and return it.
+ */
+ public int[] reset() {
+ return Arrays.copyOf(original, original.length);
+ }
+
+ /**
+ * Returns a random shuffling of the array.
+ */
+ public int[] shuffle() {
+ int[] copy = Arrays.copyOf(original, original.length);
+
+ Random random = new Random();
+ for (int i = 0; i < copy.length - 1; i++) {
+ swap(copy, i, i + random.nextInt(copy.length - i));
+ }
+
+ return copy;
+ }
+
+ private void swap(int[] copy, int i, int j) {
+ int t = copy[i];
+ copy[i] = copy[j];
+ copy[j] = t;
+ }
+}
diff --git a/[0387][First Unique Character in a String]/[0387][First Unique Character in a String].iml b/[0387][First Unique Character in a String]/[0387][First Unique Character in a String].iml
new file mode 100644
index 0000000..c8cb479
--- /dev/null
+++ b/[0387][First Unique Character in a String]/[0387][First Unique Character in a String].iml
@@ -0,0 +1,23 @@
+
+
+ * Given a string, find the first non-repeating character in it and return it's index.
+ * If it doesn't exist, return -1.
+ *
+ * Examples:
+ *
+ * s = "leetcode"
+ * return 0.
+ *
+ * s = "loveleetcode",
+ * return 2.
+ *
+ *
+ * @param s
+ * @return
+ */
+ public int firstUniqChar(String s) {
+ if (s == null || s.length() < 1) {
+ return -1;
+ }
+
+
+ Map
+ * Given two strings s and t which consist of only lowercase letters.
+ *
+ * String t is generated by random shuffling string s and then add one
+ * more letter at a random position.
+ *
+ * Find the letter that was added in t.
+ *
+ * Example:
+ *
+ * Input:
+ * s = "abcd"
+ * t = "abcde"
+ *
+ * Output:
+ * e
+ *
+ * Explanation:
+ * 'e' is the letter that was added.
+ *
+ *
+ * @param s
+ * @param t
+ * @return
+ */
+ public char findTheDifference(String s, String t) {
+ // 假设输入都是合法的
+ int[] chars = new int[26];
+
+ for (int i = 0; i < s.length(); i++) {
+ chars[s.charAt(i) - 'a']++;
+ }
+
+ for (int i = 0; i < t.length(); i++) {
+ chars[t.charAt(i) - 'a']--;
+ }
+
+ for (int i = 0; i < chars.length; i++) {
+ if (chars[i] < 0) {
+ return (char) ('a' + i);
+ }
+ }
+
+ throw new NoSuchElementException("could not find the difference");
+ }
+}
diff --git a/[0392][Is Subsequence]/[0392][Is Subsequence].iml b/[0392][Is Subsequence]/[0392][Is Subsequence].iml
new file mode 100644
index 0000000..c70cbf1
--- /dev/null
+++ b/[0392][Is Subsequence]/[0392][Is Subsequence].iml
@@ -0,0 +1,21 @@
+
+
+ * Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...
+ *
+ * Note:
+ * n is positive and will fit within the range of a 32-bit signed integer (n < 231).
+ *
+ * Example 1:
+ *
+ * Input:
+ * 3
+ *
+ * Output:
+ * 3
+ * Example 2:
+ *
+ * Input:
+ * 11
+ *
+ * Output:
+ * 0
+ *
+ * Explanation:
+ * The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0,
+ * which is part of the number 10.
+ *
+ * https://blog.csdn.net/yeqiuzs/article/details/52573876
+ *
+ * 思路:
+ * 1~9 9个数 9*1=9个digit
+ * 10~99 90个数 90*2=180个digit
+ * 100~999 900个数 900*3=2700个digit
+ * 10^k ~ k个9连成的数 9*10^k个数 (90*10^k)*k个digit
+ *
+ * 所以给点n,首先确定在几位数之间,如在1000~9999还是在其他之间?然后确定是该区间的哪个数?
+ * 最后确定是该数字的哪个digit?
+ * 注意防止溢出。
+ *
+ *
+ *
+ * @param n
+ * @return
+ */
+ public int findNthDigit(int n) {
+ // 记录用多少位
+ int k = 1;
+ // 记录[10..0(k-1个0), ..., k个9]有多少个数字
+ long length = 0;
+ while (n > length) {
+
+ // 记录[0, ..., k个9]有多少位
+ // [10..0(k-1个0), ..., k个9]有 (int) (9 * k * Math.pow(10, k - 1)) 个数字
+ length += (int) (9 * k * Math.pow(10, k - 1));
+ k++;
+ }
+
+ k--;
+ // n >= 9..9, k个9,k取最大满足条件的值,计算有多少个数字
+ length -= (int) (9 * k * Math.pow(10, k - 1));
+ int num;
+
+ if ((n - length) % k == 0) {
+ num = (int) ((int) Math.pow(10, k - 1) + (n - length) / k - 1);
+ String s = String.valueOf(num);
+ return s.charAt(s.length() - 1) - '0';
+ } else {
+ num = (int) ((int) Math.pow(10, k - 1) + (n - length) / k);
+ String s = String.valueOf(num);
+ return s.charAt((int) ((n - length) % k - 1)) - '0';
+ }
+
+ }
+}
diff --git a/[0400][Nth Digit]/src/Solution2.java b/[0400][Nth Digit]/src/Solution2.java
new file mode 100644
index 0000000..4a5b2c9
--- /dev/null
+++ b/[0400][Nth Digit]/src/Solution2.java
@@ -0,0 +1,53 @@
+/**
+ * https://leetcode.com/problems/nth-digit/
+ *
+ * @author: wangjunchao(王俊超)
+ * @time: 2019-07-09 15:56
+ **/
+public class Solution2 {
+ /**
+ *
+ * Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...
+ *
+ * Note:
+ * n is positive and will fit within the range of a 32-bit signed integer (n < 231).
+ *
+ * Example 1:
+ *
+ * Input:
+ * 3
+ *
+ * Output:
+ * 3
+ * Example 2:
+ *
+ * Input:
+ * 11
+ *
+ * Output:
+ * 0
+ *
+ * Explanation:
+ * The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which is part of the number 10.
+ *
+ * https://www.cnblogs.com/grandyang/p/5891871.html
+ *
+ *
+ * @param n
+ * @return
+ */
+ public int findNthDigit(int n) {
+ long len = 1;
+ int cnt = 9;
+ int start = 1;
+ while (n > len * cnt) {
+ n -= len * cnt;
+ ++len;
+ cnt *= 10;
+ start *= 10;
+ }
+ start += (n - 1) / len;
+ String t = "" + start;
+ return t.charAt((int) ((n - 1) % len)) - '0';
+ }
+}
diff --git a/[0401][Binary Watch]/[0401][Binary Watch].iml b/[0401][Binary Watch]/[0401][Binary Watch].iml
new file mode 100644
index 0000000..c8cb479
--- /dev/null
+++ b/[0401][Binary Watch]/[0401][Binary Watch].iml
@@ -0,0 +1,23 @@
+
+
+ * Find the sum of all left leaves in a given binary tree.
+ *
+ * Example:
+ *
+ * 3
+ * / \
+ * 9 20
+ * / \
+ * 15 7
+ *
+ * There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.
+ *
+ *
+ * @param root
+ * @return
+ */
+ public int sumOfLeftLeaves(TreeNode root) {
+ int[] result = new int[1];
+ sumOfLeftLeaves(root, false, result);
+ return result[0];
+ }
+
+ /**
+ * 计算所有左叶子的和
+ *
+ * @param root
+ * @param result
+ */
+ private void sumOfLeftLeaves(TreeNode root, boolean isLeftLeaf, int[] result) {
+
+ if (root == null) {
+ return;
+ }
+
+ if (root.left == null && root.right == null && isLeftLeaf) {
+ result[0] += root.val;
+ return;
+ }
+
+ sumOfLeftLeaves(root.left, true, result);
+ sumOfLeftLeaves(root.right, false, result);
+ }
+}
diff --git a/[0404][Sum of Left Leaves]/src/TreeNode.java b/[0404][Sum of Left Leaves]/src/TreeNode.java
new file mode 100644
index 0000000..9aec4dd
--- /dev/null
+++ b/[0404][Sum of Left Leaves]/src/TreeNode.java
@@ -0,0 +1,15 @@
+/**
+ * Author:
+ * Date: 2015-08-19
+ * Time: 06:45
+ * Declaration: All Rights Reserved !!!
+ */
+public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int x) {
+ val = x;
+ }
+}
diff --git a/[0405][Convert a Number to Hexadecimal]/[0405][Convert a Number to Hexadecimal].iml b/[0405][Convert a Number to Hexadecimal]/[0405][Convert a Number to Hexadecimal].iml
new file mode 100644
index 0000000..c8cb479
--- /dev/null
+++ b/[0405][Convert a Number to Hexadecimal]/[0405][Convert a Number to Hexadecimal].iml
@@ -0,0 +1,23 @@
+
+
+ * Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, two’s complement method is used.
+ *
+ * Note:
+ *
+ * All letters in hexadecimal (a-f) must be in lowercase.
+ * The hexadecimal string must not contain extra leading 0s. If the number is zero, it is represented by a single zero character '0'; otherwise, the first character in the hexadecimal string will not be the zero character.
+ * The given number is guaranteed to fit within the range of a 32-bit signed integer.
+ * You must not use any method provided by the library which converts/formats the number to hex directly.
+ * Example 1:
+ *
+ * Input:
+ * 26
+ *
+ * Output:
+ * "1a"
+ * Example 2:
+ *
+ * Input:
+ * -1
+ *
+ * Output:
+ * "ffffffff"
+ *
+ *
+ * @param num
+ * @return
+ */
+ public String toHex(int num) {
+ String result = "";
+ String hex = "0123456789abcdef";
+ int mask = 0b1111;
+
+ int i;
+ do {
+ // 取低四位的值
+ i = num & mask;
+ // 转成16进制
+ result = hex.charAt(i) + result;
+ // 无符号右移四位,直到0
+ num >>>= 4;
+ } while (num > 0);
+
+ return result;
+ }
+}
diff --git a/[0409][Longest Palindrome]/[0409][Longest Palindrome].iml b/[0409][Longest Palindrome]/[0409][Longest Palindrome].iml
new file mode 100644
index 0000000..c8cb479
--- /dev/null
+++ b/[0409][Longest Palindrome]/[0409][Longest Palindrome].iml
@@ -0,0 +1,23 @@
+
+
+ * Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.
+ *
+ * This is case sensitive, for example "Aa" is not considered a palindrome here.
+ *
+ * Note:
+ * Assume the length of given string will not exceed 1,010.
+ *
+ * Example:
+ *
+ * Input:
+ * "abccccdd"
+ *
+ * Output:
+ * 7
+ *
+ * Explanation:
+ * One longest palindrome that can be built is "dccaccd", whose length is 7.
+ * 思路
+ * 1、先记录每个字符出现的次数
+ * 2、取每个字符出现的最大的偶数
+ * 3、如果还有剩下的单个字符,只取其中的一个
+ *
+ */
+ public int longestPalindrome(String s) {
+ if (s == null || s.length() < 1) {
+ return 0;
+ }
+
+ int[] counter = new int[256];
+
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ counter[ch - 'A']++;
+ }
+
+ int result = 0;
+ int left = 0;
+ for (int value : counter) {
+ result += 0xFFFFFFFE & value;
+ left |= 0b1 & value;
+ }
+
+ return result + left;
+ }
+}
diff --git a/[0409][Longest Palindrome]/src/Solution1.java b/[0409][Longest Palindrome]/src/Solution1.java
new file mode 100644
index 0000000..797d326
--- /dev/null
+++ b/[0409][Longest Palindrome]/src/Solution1.java
@@ -0,0 +1,60 @@
+/**
+ * https://leetcode.com/problems/longest-palindrome/
+ *
+ * @author: wangjunchao(王俊超)
+ * @time: 2019-07-03 04:08
+ **/
+public class Solution1 {
+ /**
+ *
+ * Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.
+ *
+ * This is case sensitive, for example "Aa" is not considered a palindrome here.
+ *
+ * Note:
+ * Assume the length of given string will not exceed 1,010.
+ *
+ * Example:
+ *
+ * Input:
+ * "abccccdd"
+ *
+ * Output:
+ * 7
+ *
+ * Explanation:
+ * One longest palindrome that can be built is "dccaccd", whose length is 7.
+ * 思路
+ * 1、先记录每个字符出现的次数
+ * 2、取每个字符出现的最大的偶数
+ * 3、如果还有剩下的单个字符,只取其中的一个
+ *
+ */
+ public int longestPalindrome(String s) {
+ if (s == null || s.length() < 1) {
+ return 0;
+ }
+
+ int[] counter = new int[256];
+
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ counter[ch - 'A']++;
+ }
+
+ int result = 0;
+ int left = 0;
+ for (int value : counter) {
+ if (value > 0) {
+ if (value % 2 == 0) {
+ result += value;
+ } else {
+ result += value - 1;
+ left = 1;
+ }
+ }
+ }
+
+ return result + left;
+ }
+}
diff --git a/[0409][Longest Palindrome]/src/Solution2.java b/[0409][Longest Palindrome]/src/Solution2.java
new file mode 100644
index 0000000..ad898f8
--- /dev/null
+++ b/[0409][Longest Palindrome]/src/Solution2.java
@@ -0,0 +1,67 @@
+/**
+ * https://leetcode.com/problems/longest-palindrome/
+ *
+ * @author: wangjunchao(王俊超)
+ * @time: 2019-07-03 04:08
+ **/
+public class Solution2 {
+ /**
+ *
+ * Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.
+ *
+ * This is case sensitive, for example "Aa" is not considered a palindrome here.
+ *
+ * Note:
+ * Assume the length of given string will not exceed 1,010.
+ *
+ * Example:
+ *
+ * Input:
+ * "abccccdd"
+ *
+ * Output:
+ * 7
+ *
+ * Explanation:
+ * One longest palindrome that can be built is "dccaccd", whose length is 7.
+ * 思路
+ * 1、先记录每个字符出现的次数
+ * 2、取每个字符出现的最大的偶数
+ * 3、如果还有剩下的单个字符,只取其中的一个
+ *
+ */
+ public int longestPalindrome(String s) {
+ if (s == null || s.length() < 1) {
+ return 0;
+ }
+
+ int[] counter = new int[26];
+ // TIP: 这里是大小写不敏感的
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ if (ch >= 'a' && ch <= 'z') {
+ counter[ch - 'a']++;
+ } else {
+ counter[ch - 'A']++;
+ }
+ }
+
+ int result = 0;
+ int left = 0;
+ for (int value : counter) {
+ if (value > 0) {
+ if (value % 2 == 0) {
+ result += value;
+// counter[i] = 0;
+ } else {
+ result += value - 1;
+// counter[i] = 1;
+ // 记录还有剩下的1
+ left = 1;
+ }
+ }
+ }
+
+ return result + left;
+ }
+}
diff --git a/[0412][Fizz Buzz]/[0412][Fizz Buzz].iml b/[0412][Fizz Buzz]/[0412][Fizz Buzz].iml
new file mode 100644
index 0000000..c8cb479
--- /dev/null
+++ b/[0412][Fizz Buzz]/[0412][Fizz Buzz].iml
@@ -0,0 +1,23 @@
+
+
+ * Write a program that outputs the string representation of numbers from 1 to n.
+ *
+ * But for multiples of three it should output “Fizz” instead of the number and for
+ * the multiples of five output “Buzz”. For numbers which are multiples of both three
+ * and five output “FizzBuzz”.
+ *
+ * Example:
+ *
+ * n = 15,
+ *
+ * Return:
+ * [
+ * "1",
+ * "2",
+ * "Fizz",
+ * "4",
+ * "Buzz",
+ * "Fizz",
+ * "7",
+ * "8",
+ * "Fizz",
+ * "Buzz",
+ * "11",
+ * "Fizz",
+ * "13",
+ * "14",
+ * "FizzBuzz"
+ * ]
+ *
+ *
+ * @param n
+ * @return
+ */
+ public List
+ * Given a non-empty array of integers, return the third maximum number in this array.
+ * If it does not exist, return the maximum number. The time complexity must be in O(n).
+ *
+ * Example 1:
+ * Input: [3, 2, 1]
+ *
+ * Output: 1
+ *
+ * Explanation: The third maximum is 1.
+ * Example 2:
+ * Input: [1, 2]
+ *
+ * Output: 2
+ *
+ * Explanation: The third maximum does not exist, so the maximum (2) is returned instead.
+ * Example 3:
+ * Input: [2, 2, 3, 1]
+ *
+ * Output: 1
+ *
+ * Explanation: Note that the third maximum here means the third maximum distinct number.
+ * Both numbers with value 2 are both considered as second maximum.
+ *
+ *
+ * @param nums
+ * @return
+ */
+ public int thirdMax(int[] nums) {
+ SortedSet