├── .DS_Store ├── ._.DS_Store ├── BloomFilter.java ├── Codec.java ├── CoinCount.java ├── FindDifferentInterval.java ├── FindTarget.java ├── HashFunc.java ├── Huffman.java ├── KeyValue.java ├── LRUCache.java ├── ListNodeDemo.java ├── MinimumMove.java ├── Pure.java ├── README.md ├── ShortPoint.java ├── SnapChat.java ├── Tokenizer.java ├── Trie.java ├── UberSerial.java ├── Vocabulary.java ├── WebFind.java ├── algorithm ├── NChapter │ └── findKthNumber │ │ ├── FindKthNumber.java │ │ ├── FindMedianSortedArrays.java │ │ ├── KthLargestElement_lintCode.java │ │ └── KthLargestElement_lintCode_v1.java ├── dp │ ├── FindLargeCommonLine.java │ ├── FindLargestPath.java │ ├── LongestPalindrome_dp1.java │ ├── MinAdjustmentCost_Class.java │ ├── MinPath_Block.java │ └── input.txt ├── others │ ├── AddBinary.java │ ├── Ag.java │ ├── Anagrams.java │ ├── BinarySearch.java │ ├── Combination2.java │ ├── CombinationSum.java │ ├── DivideTwoIntegers.java │ ├── FindSame.java │ ├── Flatten.java │ ├── GenerateParentheses.java │ ├── GraphDemo.java │ ├── InOrderTraversal.java │ ├── Insertion_Link.java │ ├── Interleaving.java │ ├── IntersectionOfThreeSets.java │ ├── IsMach.java │ ├── IsSymmetric.java │ ├── JavaAppWithoutMain.java │ ├── KthSort.java │ ├── LRUCache.java │ ├── LargestRectangleArea.java │ ├── Line.java │ ├── ListNode.java │ ├── LongestPare.java │ ├── Max_path_BinaryTree.java │ ├── MiniStack.java │ ├── MinimumWindowSubString.java │ ├── MortgageCalculator.java │ ├── MutiplyString.java │ ├── NumDecodings.java │ ├── NumTree.java │ ├── PartitionArray.java │ ├── Permute.java │ ├── PlusOne.java │ ├── Point.java │ ├── Populate2.java │ ├── Premute.java │ ├── Recover.java │ ├── Rectangle.java │ ├── ReverseString.java │ ├── Reverse_binary.java │ ├── SearchInRotatedArray.java │ ├── SingleNumber2.java │ ├── SortColors.java │ ├── SortList.java │ ├── SpiralMatrix.java │ ├── SpiralOrder.java │ ├── Sqrt.java │ ├── SubSet2.java │ ├── Subset.java │ ├── SurroundRegions.java │ ├── TestArrayChange.java │ ├── TreeSumCloset.java │ ├── WordBreak2.java │ ├── ZigzagLevelOrder.java │ └── letterCombinations.java ├── sort │ └── WaveSort.java └── thread │ ├── Deadlock_II.java │ ├── NewThread.java │ ├── Thread11.java │ ├── Thread22.java │ └── ThreadDemo.java ├── array ├── FindMedianSortedArrays.java ├── FirstMissingPositive.java ├── GenerateMatrix1.java ├── Interval.java ├── LargestRectangleArea.java ├── MaxProduct.java ├── MaxSubArray.java ├── MaxSubArray_1220_2014.java ├── MaximalRectangle.java ├── Merge.java ├── MergeSortedArray.java ├── PlusOne.java ├── RemoveDuplicates.java ├── RemoveDuplicates2.java ├── RemoveElement.java ├── Rotate.java ├── SearchInRotatedSortedArray.java ├── SearchInRotatedSortedArray2.java ├── SetZeroes.java ├── SpiralOrder.java ├── SpiralOrder_1201.java ├── ThreeSum.java ├── ThreeSumN2.java ├── TierTree.java ├── Trap.java └── TwoSum.java ├── bfs ├── CloneGraph.java ├── LadderLength.java ├── LadderLength_1218_2014.java ├── Solve.java └── Solve_SurroundedRegions.java ├── binarySearch ├── Divide.java ├── FindMin.java ├── FindMin2.java ├── FindPeakElement.java ├── SearchRange.java └── searchInsert.java ├── combination ├── CombinationSum.java ├── CombinationSum2.java ├── CombinationSum2_1203.java ├── CombinationSum_1203.java ├── Combinations.java ├── Combine_1203.java └── LetterCombinations.java ├── dfs ├── Exist.java ├── FiveChessman.java ├── LetterCombinations.java ├── LetterCombinations2.java ├── Partition.java ├── Partition_2014_1229.java ├── Permute.java ├── SolveNQueens.java ├── SolveNQueens_v2.java ├── Subsets.java ├── SubsetsWithDup.java ├── TotalNQueens.java └── totalNQueens_1218_2014.java ├── divide2 ├── Pow.java ├── Pow_1219_2014.java ├── SearchInsert.java ├── SearchMatrix.java ├── SearchRange.java └── Sqrt.java ├── dp ├── CanJump.java ├── Candy.java ├── Fibonacci.java ├── GetRow.java ├── IsInterleave.java ├── IsMatch.java ├── IsScramble.java ├── LongestPalindrome.java ├── LongestPalindrome_dp1.java ├── MaxProfit.java ├── MaxProfit2.java ├── MaxProfit3.java ├── MinCut.java ├── MinCut_1206.java ├── MinDistance.java ├── MinPathSum.java ├── MinPathSum_1222_2014.java ├── MinimumTotal.java ├── NQueens2.java ├── NumDecodings.java ├── NumDistinct.java ├── UniquePaths.java ├── UniquePathsWithObstacles.java ├── WordBreak.java └── WordBreak2.java ├── greedy ├── CanCompleteCircuit.java └── Jump.java ├── hash ├── Anagrams.java ├── IsValidSudoku.java ├── LRUCache.java ├── LRUCache2.java ├── LongestConsecutive.java ├── MaxPoints.java └── SolveSudoku.java ├── lintcode ├── array │ ├── FindFirstBadVersion.java │ ├── MinSubArray.java │ ├── Rerange.java │ ├── SortKColors.java │ ├── SubarraySum.java │ └── VersionControl.java ├── dp │ ├── KSum.java │ ├── LongestCommonSubsequence.java │ └── LongestCommonSubstring.java ├── math │ ├── FastPower.java │ ├── MajorityNumber.java │ └── MajorityNumber2.java └── stack │ └── StackQueue.java ├── list ├── AddTwoNumbers.java ├── CopyRandomList.java ├── DeleteDuplicates.java ├── DeleteDuplicates2.java ├── DetectCycle.java ├── Generate.java ├── GetIntersectionNode1.java ├── HasCycle.java ├── InsertionSortList.java ├── ListNodeDemo.java ├── MergeKLists.java ├── MergeKLists_1204.java ├── MergeTwoLists.java ├── MergeTwoLists_1206.java ├── Partition.java ├── PartitionList.java ├── RemoveNthFromEnd.java ├── ReorderList.java ├── ReverseBetween.java ├── ReverseKGroup.java ├── ReverseKGroup_1227_2014.java ├── ReverseLinkedList2.java ├── RotateList.java ├── RotateRight.java ├── SwapPairs.java └── SwapPairs3.java ├── math └── Reverse.java ├── new ├── FindSubstring.java ├── IsPalindrome.java ├── LRUCache.java ├── LengthOfLastWord.java ├── MinWindow.java └── ThreeSum.java ├── permutation ├── NextPermutation.java ├── Permutation.java ├── PermutationSequence.java ├── PermuteUnique.java └── Stopwatch.java ├── recursion ├── Factorial.java └── GrayCode.java ├── sequence ├── FourSum.java ├── Reverse.java ├── ThreeSum.java ├── ThreeSumClosest.java └── TwoSum.java ├── sort ├── BucketSorter.java ├── InsertionSortList.java ├── MergeSort.java ├── MergeSort_LinkedList.java ├── QuickSort.java ├── SortColors.java ├── SortList.java └── SortList_leetCode.java ├── stack ├── EvalRPN.java ├── IsValid.java └── MinStack.java ├── string ├── AddBinary.java ├── Anagrams.java ├── Atoi.java ├── CompareVersion.java ├── CompareVersion2.java ├── Convert.java ├── CountAndSay.java ├── FindLadders.java ├── FindLadders_1218_2014.java ├── FindSubstring.java ├── FullJustify.java ├── GenerateParenthesis.java ├── IntToRoman.java ├── IsNumber.java ├── IsPalindrome.java ├── IsPalindrome_2014_1229.java ├── LargestNumber.java ├── LengthOfLastWord.java ├── LengthOfLongestSubstring.java ├── LongestCommonPrefix.java ├── LongestCommonPrefix_1221_2014.java ├── LongestValidParentheses.java ├── MinWindow.java ├── Multiply.java ├── RestoreIpAddresses.java ├── ReverseWords.java ├── RomanToInt.java ├── SimplifyPath.java ├── StrStr.java ├── isMatch.java └── isMatch_2014_1228.java ├── tree ├── BuildTree.java ├── BuildTree2.java ├── Connect.java ├── Connect2.java ├── Connect2_2014_1229.java ├── Connect_2014_1229.java ├── GenerateTree2.java ├── InorderTraversal.java ├── IsBalanced.java ├── IsSameTree1.java ├── IsSymmetric.java ├── IsSymmetric_LeetCode.java ├── IsValidBST.java ├── IsValidBST_1221_2014.java ├── LCA.java ├── LCA_Demo.java ├── LargestCommonSubtrees.java ├── LevelOrder.java ├── Level_Order.java ├── MaxPathSum.java ├── MaxSameTree2.java ├── MinDepth.java ├── MinDepth_1218_2014.java ├── NumTrees.java ├── PathSum2.java ├── PostorderTraversal.java ├── PreorderTraversal.java ├── PrintPath.java ├── RecoverTree.java ├── SortedArrayToBST.java ├── SumNumbers.java ├── SumNumbers_1208_2014.java ├── TreeDemo.java ├── TreeDemo2.java ├── TreeLinkNode.java ├── TreeNode.java ├── hasPathSum.java ├── readme.md └── sortedListToBST.java └── twoPoints └── MaxArea.java /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuzhangcmu/LeetCode/eb2aaeada59cf42ea26f4003f9709c4f1b05ac17/.DS_Store -------------------------------------------------------------------------------- /._.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuzhangcmu/LeetCode/eb2aaeada59cf42ea26f4003f9709c4f1b05ac17/._.DS_Store -------------------------------------------------------------------------------- /BloomFilter.java: -------------------------------------------------------------------------------- 1 | package Algorithms; 2 | 3 | import java.util.ArrayList; 4 | import java.util.BitSet; 5 | 6 | public class BloomFilter { 7 | public class HashFunc { 8 | public int callFun(String s) { 9 | return 0; 10 | } 11 | } 12 | 13 | BitSet bits; 14 | int n; 15 | 16 | public BloomFilter(int n, ArrayList list) { 17 | super(); 18 | this.bits = new BitSet(n); 19 | this.n = n; 20 | this.list = list; 21 | } 22 | 23 | ArrayList list; 24 | 25 | public void add(String s) { 26 | for (HashFunc fun: list) { 27 | int code = fun.callFun(s); 28 | code = code % n; 29 | 30 | bits.set(code); 31 | } 32 | } 33 | 34 | public boolean contains(String s) { 35 | for (HashFunc fun: list) { 36 | int code = fun.callFun(s); 37 | code = code % n; 38 | 39 | if (!bits.get(code)) { 40 | return false; 41 | } 42 | } 43 | 44 | return true; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Codec.java: -------------------------------------------------------------------------------- 1 | package Algorithms; 2 | 3 | public class Codec { 4 | public static void main(String[] strs) { 5 | System.out.println(); 6 | 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /HashFunc.java: -------------------------------------------------------------------------------- 1 | package Algorithms; 2 | 3 | public class HashFunc { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /KeyValue.java: -------------------------------------------------------------------------------- 1 | package Algorithms; 2 | 3 | import java.util.HashMap; 4 | import java.util.Scanner; 5 | 6 | public class KeyValue { 7 | private static HashMap map; 8 | 9 | public static void main(String[] strs) { 10 | map = new HashMap(); 11 | 12 | Scanner scanner = new Scanner( System.in ); 13 | 14 | while (true) { 15 | // 2. Don't forget to prompt the user 16 | System.out.print( "Type the option you want to do(1: input data. 2: Get data): " ); 17 | 18 | // 3. Use the Scanner to read a line of text from the user. 19 | String input = scanner.nextLine(); 20 | 21 | if (input.equals("1")) { 22 | System.out.print( "Please input the key: " ); 23 | String key = scanner.nextLine(); 24 | System.out.println( "key = " + key ); 25 | 26 | System.out.print( "Please input the value: " ); 27 | String value = scanner.nextLine(); 28 | System.out.println( "value = " + value ); 29 | 30 | map.put(key, value); 31 | 32 | System.out.print( "Insert the key/value pair to the database." ); 33 | } else if (input.equals("2")){ 34 | System.out.print( "Please input the key: " ); 35 | String key = scanner.nextLine(); 36 | System.out.println( "key = " + key ); 37 | 38 | String value = map.get(key); 39 | if (value == null) { 40 | System.out.println( "The key does not exit." ); 41 | } else { 42 | System.out.println( "Value = " + map.get(key) ); 43 | } 44 | } 45 | 46 | System.out.println(); 47 | } 48 | 49 | } 50 | 51 | //public 52 | } 53 | -------------------------------------------------------------------------------- /MinimumMove.java: -------------------------------------------------------------------------------- 1 | package Algorithms; 2 | 3 | public class MinimumMove { 4 | //public static int easyString(String a, String b) { 5 | // int len = a.length(); 6 | // 7 | // // Use DP to solve it. 8 | // int D[][] = new int[len][len]; 9 | // 10 | // for (int i = 0; i < len; i++) { 11 | // 12 | // } 13 | //} 14 | public static void main(String args[] ) throws Exception { 15 | /* Enter your code here. Read input from STDIN. Print output to STDOUT */ 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Pure.java: -------------------------------------------------------------------------------- 1 | package Algorithms; 2 | 3 | public class Pure { 4 | static int cnt = 0; 5 | 6 | public static void main(String[] strs) { 7 | f(19); 8 | 9 | System.out.println(cnt); 10 | } 11 | 12 | public static int f(int x) { 13 | cnt++; 14 | if (x < 1) return 1; 15 | else return f(x - 1) + g(x); 16 | } 17 | 18 | public static int g(int x) { 19 | //cnt++; 20 | if (x < 2) return 1; 21 | else return f(x - 1) + g(x / 2); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LeetCode 2 | ================== 3 | 一、简介 4 | 1. Leetcode sol ution writtern in Java. 5 | 2. 部分公司面经 6 | 7 | 二、目录划分: 8 | algorithm ---- 包含除LeetCode以外的其它算法,如面经等。除了这个目录以外都是LeetCode 9 |   -- interviews 面经 10 |   -- facebook 各公司的面经 11 | array ---------- leetcode array 相关 12 | combination -- leetcode 组合相关 13 | ... etc 14 | 15 | 三、相关网页: 16 | 1. 微博解题报告: http://www.weibo.com/3948019741/profile?topnav=1&wvr=6 17 | 2. 微博园解题报告:http://www.cnblogs.com/yuzhangcmu/ 18 | 3. 算法辅导:http://goo.gl/zgA2Dn 19 | 4. Leetcode在线答案:http://goo.gl/12jBTx 20 | 5. 刷新题网站 :http://goo.gl/IolF5t 21 | -------------------------------------------------------------------------------- /ShortPoint.java: -------------------------------------------------------------------------------- 1 | package Algorithms; 2 | 3 | import java.util.HashMap; 4 | import java.util.Queue; 5 | 6 | public class ShortPoint { 7 | // 2323 8 | class Point { 9 | int row; 10 | int colum; 11 | 12 | public Point(int row, int colum) { 13 | super(); 14 | this.row = row; 15 | this.colum = colum; 16 | } 17 | } 18 | 19 | // 1: Robet 20 | // 0: Pass 21 | // -1: Block. 22 | public static void main(String[] strs) { 23 | HashMap map; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Vocabulary.java: -------------------------------------------------------------------------------- 1 | package Algorithms; 2 | 3 | public interface Vocabulary { 4 | boolean add(String word); 5 | boolean isPrefix(String prefix); 6 | boolean contains(String word); 7 | } 8 | -------------------------------------------------------------------------------- /WebFind.java: -------------------------------------------------------------------------------- 1 | package Algorithms; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | 7 | public class WebFind { 8 | 9 | public class UrlGraph { 10 | String val; 11 | ArrayList childrens; 12 | 13 | public UrlGraph(String val) { 14 | super(); 15 | this.val = val; 16 | this.childrens = new ArrayList(); 17 | } 18 | } 19 | 20 | public UrlGraph webClown(String url, HashMap map) { 21 | if (map.containsKey(url)) { 22 | return map.get(url); 23 | } 24 | 25 | UrlGraph node = new UrlGraph(url); 26 | 27 | ArrayList list = getUrls(url); 28 | for (String sub: list) { 29 | node.childrens.add(webClown(sub, map)); 30 | } 31 | 32 | map.put(url, node); 33 | return node; 34 | } 35 | 36 | public ArrayList getUrls(String url) { 37 | //return 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /algorithm/NChapter/findKthNumber/FindMedianSortedArrays.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.NChapter.findKthNumber; 2 | 3 | 4 | public class FindMedianSortedArrays { 5 | public static void main(String[] str) { 6 | int A[] = {1,2,3,3}; 7 | int B[] = {3,3,7,8}; 8 | double ret = findMedianSortedArrays(A, B); 9 | System.out.println(ret); 10 | } 11 | 12 | public static double findMedianSortedArrays(int A[], int B[]) { 13 | double ret = findKth(A, 0, B, 0, 6); 14 | return ret; 15 | 16 | /* 17 | if (len % 2 == 0) { 18 | return (findKth(A, 0, B, 0, len / 2) + findKth(A, 0, B, 0, len / 2 + 1)) / 2.0 ; 19 | } else { 20 | return findKth(A, 0, B, 0, len / 2 + 1); 21 | }*/ 22 | } 23 | 24 | // find kth number of two sorted array 25 | public static int findKth(int[] A, int A_start, int[] B, int B_start, int k){ 26 | if(A_start >= A.length) 27 | return B[B_start + k - 1]; 28 | if(B_start >= B.length) 29 | return A[A_start + k - 1]; 30 | 31 | if (k == 1) 32 | return Math.min(A[A_start], B[B_start]); 33 | 34 | int A_key = A_start + k / 2 - 1 < A.length 35 | ? A[A_start + k / 2 - 1] 36 | : Integer.MAX_VALUE; 37 | int B_key = B_start + k / 2 - 1 < B.length 38 | ? B[B_start + k / 2 - 1] 39 | : Integer.MAX_VALUE; 40 | 41 | if (A_key < B_key) { 42 | return findKth(A, A_start + k / 2, B, B_start, k - k / 2); 43 | } else { 44 | return findKth(A, A_start, B, B_start + k / 2, k - k / 2); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /algorithm/dp/FindLargeCommonLine.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.dp; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class FindLargeCommonLine { 6 | public static void main(String[] str) { 7 | int[][] input = { 8 | {0, 1}, 9 | {1, 0} 10 | }; 11 | 12 | System.out.println(find(input)); 13 | } 14 | 15 | public static class DpType { 16 | ArrayList set0; 17 | ArrayList set1; 18 | int max0; 19 | int max1; 20 | 21 | public DpType(int max0, int max1) { 22 | super(); 23 | this.set0 = new ArrayList(); 24 | this.set1 = new ArrayList(); 25 | this.max0 = max0; 26 | this.max1 = max1; 27 | } 28 | } 29 | 30 | public static int find(int[][] input) { 31 | if (input == null || input.length == 0 || input[0].length == 0) { 32 | return 0; 33 | } 34 | 35 | int rows = input.length; 36 | int cols = input[0].length; 37 | 38 | // create a DP 39 | int[] max1 = new int[cols]; 40 | int[] max0 = new int[cols]; 41 | 42 | // initate to be one, means the first line. 43 | int maxLine1 = 1; 44 | int maxLine0 = 1; 45 | 46 | for (int i = 0; i < cols; i++) { 47 | if (input[0][i] == 0) { 48 | // no change. 49 | max0[i] = 0; 50 | 51 | // should reverse. 52 | max1[i] = 1; 53 | } else { 54 | max0[i] = 1; 55 | max1[i] = 0; 56 | } 57 | } 58 | 59 | // Dp from the 2nd line to the last. 60 | for (int i = 1; i < rows; i++) { 61 | boolean is0 = true; 62 | for (int j = 0; j < cols; j++) { 63 | //if (input[]) 64 | } 65 | } 66 | 67 | return 0; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /algorithm/dp/MinPath_Block.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.dp; 2 | 3 | public class MinPath_Block { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /algorithm/dp/input.txt: -------------------------------------------------------------------------------- 1 | 2 -3 2 | 0 1 -------------------------------------------------------------------------------- /algorithm/others/AddBinary.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class AddBinary { 4 | public static void main(String[] args) { 5 | AddBinary ab = new AddBinary(); 6 | System.out.println(ab.addBinary("100", "110010")); 7 | 8 | return; 9 | 10 | } 11 | 12 | public String addBinary(String a, String b) { 13 | int sLen = 0; 14 | int lLen = 0; 15 | int carries = 0; 16 | 17 | String l = null; 18 | String s = null; 19 | if (a.length() > b.length()) { 20 | sLen = b.length(); 21 | lLen = a.length(); 22 | l = a; 23 | s = b; 24 | } else { 25 | sLen = a.length(); 26 | lLen = b.length(); 27 | l = b; 28 | s = a; 29 | } 30 | 31 | StringBuilder rst = new StringBuilder(); 32 | 33 | int i = 0; 34 | for (i = sLen - 1; i >= 0; i--) { 35 | int sum = (int)(s.charAt(i) - '0') + (int)(l.charAt(lLen - sLen + i) - '0') + carries; 36 | if (sum >= 2) { 37 | carries = 1; 38 | } else { 39 | carries = 0; 40 | } 41 | rst.insert(0, String.valueOf(sum%2)); 42 | } 43 | 44 | for (i = lLen - sLen - 1; i >= 0; i--) { 45 | if (carries == 1) { 46 | if (l.charAt(i) == '0') { 47 | carries = 0; 48 | rst.insert(0,'1'); 49 | } else { 50 | rst.insert(0,'0'); 51 | } 52 | } else { 53 | rst.insert(0, l, 0, i + 1); 54 | return rst.toString(); 55 | } 56 | } 57 | 58 | if (carries == 1) { 59 | rst.insert(0,'1'); 60 | } 61 | 62 | return rst.toString(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /algorithm/others/Ag.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | 4 | 5 | abstract public class Ag { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /algorithm/others/Anagrams.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.ArrayList; 3 | import java.util.HashMap; 4 | 5 | 6 | public class Anagrams { 7 | public static void main(String[] args) { 8 | Anagrams an = new Anagrams(); 9 | String[] strs = {"car","dog","god","rac","mon","bac","acr","mea","cab", "abd", "adb"}; 10 | //String[] strs = {"abc", "bac"}; 11 | System.out.println(an.anagrams(strs).toString()); 12 | } 13 | 14 | private int getHash(int[] count) { 15 | int hash = 0; 16 | int a = 378551; 17 | int b = 63689; 18 | 19 | // int a = 777877; 20 | // int b = 123451; 21 | for (int num : count) { 22 | hash = hash * a + num; 23 | a = a * b; 24 | } 25 | return hash; 26 | } 27 | 28 | public ArrayList anagrams(String[] strs) { 29 | ArrayList result = new ArrayList(); 30 | HashMap> map = new HashMap>(); 31 | 32 | for (String str : strs) { 33 | int[] count = new int[26]; 34 | for (int i = 0; i < str.length(); i++) { 35 | count[str.charAt(i) - 'a']++; 36 | } 37 | 38 | int hash = getHash(count); 39 | if (!map.containsKey(hash)) { 40 | map.put(hash, new ArrayList()); 41 | } 42 | 43 | map.get(hash).add(str); 44 | } 45 | 46 | for (ArrayList tmp : map.values()) { 47 | if (tmp.size() > 1) { 48 | result.addAll(tmp); 49 | } 50 | } 51 | 52 | return result; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /algorithm/others/BinarySearch.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class BinarySearch { 4 | public static void main(String[] strs) { 5 | BinarySearch bs = new BinarySearch(); 6 | int[] num = new int[]{0,1,2,3,4,5}; 7 | int target = 9; 8 | System.out.print(bs.binarySearch(num, target)); 9 | //int[] num2 = new int[0]; 10 | //System.out.print(bs.binarySearch(num2, target)); 11 | } 12 | 13 | public int binarySearch(int num[], int target) { 14 | if (num == null || num.length == 0) { 15 | return -1; 16 | } 17 | 18 | int left = 0; 19 | int right = num.length - 1; 20 | 21 | String test = "test"; 22 | String t2 = test.substring(0,0); 23 | System.out.printf(test.substring(0,0)); 24 | 25 | // while (left <= right) { 26 | // int mid = left + (right - left)/2; 27 | // if (num[mid] > target) { 28 | // right = mid - 1; 29 | // } else if (num[mid] < target) { 30 | // left = mid + 1; 31 | // } else { 32 | // return mid; 33 | // } 34 | // } 35 | // [1, 2] 36 | while (left + 1 < right) { 37 | int mid = left + (right - left)/2; 38 | if (num[mid] > target) { 39 | right = mid; 40 | } else if (num[mid] < target) { 41 | left = mid; 42 | } else { 43 | return mid; 44 | } 45 | } 46 | 47 | if (num[left] == target) { 48 | return left; 49 | } else if (num[right] == target) { 50 | return right; 51 | } 52 | 53 | return -1; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /algorithm/others/Combination2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | 6 | public class Combination2 { 7 | public static void main(String[] args) { 8 | ArrayList test = new ArrayList(); 9 | 10 | test.add('c'); 11 | test.add('b'); 12 | 13 | System.out.printf("Result: %s", test.toString()); 14 | 15 | Combination2 cb = new Combination2(); 16 | int[] num = {2,2,2}; 17 | cb.combinationSum2(num, 4); 18 | } 19 | 20 | public ArrayList> combinationSum2(int[] num, int target) { 21 | 22 | // first we should sort the array. 23 | Arrays.sort(num); 24 | 25 | ArrayList> rst = new ArrayList>(); 26 | ArrayList path = new ArrayList(); 27 | 28 | cmbHelp(num, 0, path, rst, target); 29 | 30 | return rst; 31 | } 32 | 33 | public void cmbHelp(int[] num, int index, ArrayList path, ArrayList> rst, int target) { 34 | if (target == 0) { 35 | // add the current set into the result. 36 | rst.add(new ArrayList(path)); 37 | } 38 | 39 | for (int i = index; i < num.length; i++) { 40 | if (num[i] > target) { 41 | // don't need to add new element; 42 | return; 43 | } 44 | 45 | if (i >= 1 && 46 | num[i] == num[i - 1] && 47 | (path.size() == 0 || path.get(path.size() - 1) != num[i])) { 48 | continue; 49 | } 50 | 51 | path.add(num[i]); 52 | cmbHelp(num, i + 1, path, rst, target - num[i]); 53 | path.remove(path.size() - 1); 54 | } 55 | 56 | return; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /algorithm/others/DivideTwoIntegers.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class DivideTwoIntegers { 4 | public static void main(String[] args) { 5 | System.out.println(divide(-2147483648, 1)); 6 | } 7 | 8 | public static int divide(int dividend, int divisor) { 9 | long a = Math.abs((long)dividend); 10 | long b = Math.abs((long)divisor); 11 | int ret = 0; 12 | 13 | while (a >= b) { 14 | long bTmp = b; 15 | int cnt = 1; 16 | for (int i = 1; a >= bTmp; cnt <<= 1, bTmp <<= 1) { 17 | a -= bTmp; 18 | ret += cnt; 19 | } 20 | } 21 | 22 | return ((dividend > 0) ^ (divisor > 0)) ? -ret: ret; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /algorithm/others/FindSame.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.LinkedList; 3 | 4 | 5 | public class FindSame { 6 | public static LinkedList findSameNum(int[] A, int[] B) { 7 | LinkedList result = new LinkedList(); 8 | int i = 0,j = 0; 9 | 10 | while(true) { 11 | if (A[i] == B[j]) { 12 | result.add(A[i]); 13 | i++; 14 | j++; 15 | } else if (A[i] < B[j]) { 16 | i++; 17 | } else { 18 | j++; 19 | } 20 | 21 | if (i == A.length || j == B.length) { 22 | break; 23 | } 24 | } 25 | 26 | return result; 27 | } 28 | 29 | public static void main(String[] args) { 30 | int[] A = {0,1,2,4,7,8,10}; 31 | int[] B = {2,3,4,5,6,10}; 32 | 33 | LinkedList result = FindSame.findSameNum(A, B); 34 | System.out.printf(result.toString()); 35 | 36 | System.out.printf("%d", (-5)%3); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /algorithm/others/Flatten.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.Stack; 3 | 4 | import Algorithms.tree.TreeNode; 5 | 6 | 7 | 8 | public class Flatten { 9 | public static void main(String[] args) { 10 | 11 | } 12 | 13 | public void flatten(TreeNode root) { 14 | 15 | if(root == null) return; 16 | Stack stack = new Stack(); 17 | TreeNode p = root; 18 | 19 | while(p != null || !stack.empty()){ 20 | 21 | if(p.right != null){ 22 | stack.push(p.right); 23 | } 24 | 25 | if(p.left != null){ 26 | p.right = p.left; 27 | p.left = null; 28 | }else if(!stack.empty()){ 29 | TreeNode temp = stack.pop(); 30 | p.right=temp; 31 | } 32 | 33 | p = p.right; 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /algorithm/others/InOrderTraversal.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.ArrayList; 3 | import java.util.Stack; 4 | 5 | import Algorithms.tree.TreeNode; 6 | 7 | 8 | public class InOrderTraversal { 9 | public ArrayList inorderTraversal(TreeNode root) { 10 | ArrayList rst = new ArrayList(); 11 | 12 | TreeNode curr = root; 13 | Stack s = new Stack(); 14 | 15 | //s.push(curr); 16 | while (true) { 17 | // store the root and go to the far left. 18 | while (curr != null) { 19 | s.push(curr); 20 | curr = curr.left; 21 | } 22 | 23 | if (s.isEmpty()) { 24 | return rst; 25 | } 26 | 27 | curr = s.pop(); 28 | 29 | rst.add(curr.val); 30 | 31 | // traversal the right branch. 32 | curr = curr.right; 33 | } 34 | 35 | //return rst; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /algorithm/others/Insertion_Link.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class Insertion_Link { 4 | public static void main(String[] str) { 5 | Insertion_Link il = new Insertion_Link(); 6 | ListNode head = new ListNode(-5); 7 | head.next = new ListNode(4); 8 | head.next.next = new ListNode(1); 9 | head.next.next.next = new ListNode(2); 10 | head.next.next.next.next = new ListNode(6); 11 | head.next.next.next.next.next = new ListNode(7); 12 | 13 | //il.insertionSortList(head); 14 | 15 | String s = "//..."; 16 | String[] stub = s.split("/+"); 17 | System.out.print(stub.toString()); 18 | } 19 | 20 | public ListNode insertionSortList(ListNode head) { 21 | ListNode dummy = new ListNode(0); 22 | 23 | while (head != null) { 24 | ListNode node = dummy; 25 | while (node.next != null && node.next.val < head.val) { 26 | 27 | //System.out.print(head.toString()); 28 | node = node.next; 29 | 30 | //System.out.print("After print node "); 31 | //System.out.print(node.toString()); 32 | 33 | } 34 | 35 | System.out.print("Node: "); 36 | System.out.print(node.toString()); 37 | System.out.print("Head: "); 38 | System.out.print(head.toString()); 39 | 40 | ListNode temp = head.next; 41 | head.next = node.next; 42 | node.next = head; 43 | head = temp; 44 | 45 | System.out.print("print dummy: "); 46 | System.out.print(dummy.toString()); 47 | } 48 | 49 | 50 | 51 | return dummy.next; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /algorithm/others/IntersectionOfThreeSets.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.HashMap; 3 | import java.util.LinkedList; 4 | 5 | 6 | public class IntersectionOfThreeSets { 7 | public static LinkedList findIntersection(int[] set1, int[] set2, int[] set3) { 8 | LinkedList result = new LinkedList(); 9 | 10 | HashMap tmp = new HashMap(); 11 | 12 | for(int i = 0; i < set1.length; i++) { 13 | tmp.put(set1[i],1); 14 | } 15 | 16 | for(int i = 0; i < set2.length; i++) { 17 | Integer re = tmp.get(set2[i]); 18 | if (re != null) { 19 | tmp.put(set2[i],2); 20 | } 21 | } 22 | 23 | for(int i = 0; i < set3.length; i++) { 24 | Integer re = tmp.get(set3[i]); 25 | if (re != null && re == 2) { 26 | result.add(set3[i]); 27 | } 28 | } 29 | return result; 30 | } 31 | 32 | public static void main(String[] args) { 33 | int[] a1 = {1,2,20,3,8,9}; 34 | int[] a2 = {1,2,3,7,20,9}; 35 | int[] a3 = {4,3,90,8,20,9}; 36 | LinkedList re = IntersectionOfThreeSets.findIntersection(a1,a2,a3); 37 | System.out.printf(re.toString()); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /algorithm/others/IsSymmetric.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | import java.util.ArrayDeque; 4 | 5 | import Algorithms.tree.TreeNode; 6 | 7 | public class IsSymmetric { 8 | public boolean isSymmetric(TreeNode root) { 9 | if (root == null) { 10 | return true; 11 | } 12 | 13 | if (root.left == null && root.right == null) { 14 | return true; 15 | } else if (root.left == null || root.right == null) { 16 | return false; 17 | } 18 | 19 | // left and right are both not null 20 | ArrayDeque queueL = new ArrayDeque(); 21 | ArrayDeque queueR = new ArrayDeque(); 22 | 23 | queueL.offer(root.left); 24 | queueR.offer(root.right); 25 | 26 | int num = 1; 27 | while (num != 0) { 28 | TreeNode l = queueL.poll(); 29 | TreeNode r = queueR.poll(); 30 | 31 | if (l != null && r != null) { // if they are all not null 32 | if (l.val != r.val) { 33 | return false; 34 | } 35 | queueL.offer(l.left); 36 | queueL.offer(l.right); 37 | queueR.offer(r.right); 38 | queueR.offer(r.left); 39 | num += 4; 40 | } else if (l == null || r == null) { 41 | return false; 42 | } 43 | 44 | } 45 | 46 | return true; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /algorithm/others/JavaAppWithoutMain.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class JavaAppWithoutMain { 4 | static 5 | { 6 | System . out . println ( "Hello World!" ) ; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /algorithm/others/KthSort.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | import java.util.HashMap; 4 | 5 | public class KthSort { 6 | public static class Graph { 7 | String name; 8 | HashMap subs; 9 | public Graph(String name) { 10 | this.name = name; 11 | } 12 | } 13 | 14 | public static void main(String[] strs) { 15 | // int[] input = new int[]{1,2,4,3,9,11,0}; 16 | // sort(input); 17 | // for(int n: input) { 18 | // System.out.print(n + " "); 19 | // } 20 | Graph c1 = new Graph("c1"); 21 | 22 | //for() 23 | } 24 | 25 | public static void sort(int[] input) { 26 | if (input == null) { 27 | return; 28 | } 29 | 30 | int len = input.length; 31 | for (int i = 1; i < len; i++) { 32 | int cur = input[i]; 33 | int j = i - 1; 34 | while (j >= 0 && input[j] > cur) { 35 | input[j + 1] = input[j]; 36 | j--; 37 | } 38 | 39 | input[j + 1] = cur; 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /algorithm/others/LargestRectangleArea.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.Stack; 3 | 4 | 5 | public class LargestRectangleArea { 6 | public int largestRectangleArea(int[] height) { 7 | 8 | if (height == null || height.length == 0) { 9 | 10 | return 0; 11 | 12 | } 13 | 14 | Stack stack = new Stack(); 15 | 16 | int max = 0; 17 | 18 | for (int i = 0; i <= height.length; i++) { 19 | 20 | int curt = (i == height.length) ? -1 : height[i]; 21 | 22 | while (!stack.isEmpty() && curt <= height[stack.peek()]) { 23 | 24 | int h = height[stack.pop()]; 25 | 26 | int w = stack.isEmpty() ? i : i - stack.peek() - 1; 27 | 28 | max = Math.max(max, h * w); 29 | 30 | } 31 | 32 | stack.push(i); 33 | 34 | } 35 | 36 | return max; 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /algorithm/others/ListNode.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class ListNode { 4 | public int val; 5 | public ListNode next; 6 | public ListNode(int x) { 7 | val = x; 8 | next = null; 9 | } 10 | 11 | public String toString() { 12 | StringBuilder sb = new StringBuilder(); 13 | ListNode head = this; 14 | while (head != null) { 15 | sb.append(head.val); 16 | sb.append(" "); 17 | head = head.next; 18 | } 19 | 20 | sb.append("\n"); 21 | return sb.toString(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /algorithm/others/MutiplyString.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | public class MutiplyString { 3 | public static void main(String[] args) { 4 | MutiplyString ms = new MutiplyString(); 5 | String rst = ms.multiply("0", "456"); 6 | System.out.println(rst); 7 | 8 | } 9 | 10 | 11 | 12 | public String multiply(String num1, String num2) { 13 | if (num1 == null || num2 == null) { 14 | return null; 15 | } 16 | 17 | if (num1.equals("0") || num2.equals("0")) { 18 | return "0"; 19 | } 20 | 21 | StringBuilder rst = new StringBuilder(); 22 | int carry = 0; 23 | 24 | for(int i = 0; i < num1.length(); i++) { 25 | for (int j = 0; j < num2.length(); j++) { 26 | int product = Character.getNumericValue(num1.charAt(num1.length() - 1 - i)) * Character.getNumericValue(num2.charAt(num2.length() - 1 - j)); 27 | product += carry; 28 | //carry = product / 10; 29 | 30 | int index = i + j; 31 | // if it does not exit in the stringBuilder, insert it. 32 | if (index >= rst.length()) { 33 | rst.insert(0, product); 34 | } else { 35 | int sum = product + Character.getNumericValue(rst.charAt(rst.length() - 1 - index)); 36 | carry = sum / 10; 37 | sum = sum % 10; 38 | rst.setCharAt(rst.length() - 1 - index, (char)('0' + sum)); 39 | 40 | if (index >= rst.length() - 1 && carry > 0) { 41 | rst.insert(0, carry); 42 | carry = 0; 43 | } 44 | } 45 | 46 | } 47 | } 48 | 49 | return rst.toString(); 50 | 51 | } 52 | } -------------------------------------------------------------------------------- /algorithm/others/NumDecodings.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class NumDecodings { 4 | public static void main(String[] strs) { 5 | int num = numDecodings("10"); 6 | } 7 | 8 | public static int numDecodings(String s) { 9 | // state: f[i]: from 0 to i , the number of ways to decode. 10 | // func: f[i] = f[i - 1] + 1 + f[i - 2] * if (s.charAt(i - 1) and s.charAt(i) is a char) 11 | // that is : s.charAt(i - 1) < = 2 12 | // init: f[0] = 1 13 | // solution: f[len - 1] 14 | 15 | if (s == null || s.length() == 0) { 16 | return 0; 17 | } 18 | 19 | int len = s.length(); 20 | 21 | // in here, 0 means 22 | int[] num = new int[len]; 23 | 24 | if ((int)s.charAt(0) - (int)'0' <= 0) { 25 | return 0; 26 | } else { 27 | num[0] = 1; 28 | } 29 | 30 | for (int i = 1; i < len; i++) { 31 | num[i] = 0; 32 | int curr = (int)s.charAt(i) - (int)'0'; 33 | int pre = (int)s.charAt(i - 1) - (int)'0'; 34 | if (curr >= 1) { 35 | num[i] += num[i - 1]; 36 | } 37 | 38 | int sum = pre * 10 + curr; 39 | 40 | if (sum >= 10 && sum <= 26) { 41 | if (i >= 2) { 42 | num[i] += num[i - 2]; 43 | } else { 44 | num[i] += 1; 45 | } 46 | } 47 | 48 | if (num[i] == 0) { 49 | return 0; 50 | } 51 | } 52 | 53 | return num[len - 1]; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /algorithm/others/NumTree.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class NumTree { 4 | public static void main(String[] strs) { 5 | NumTree nt = new NumTree(); 6 | nt.numTrees(1); 7 | } 8 | 9 | public int numTrees(int n) { 10 | // 0, 1, 2, 3... 11 | int num[] = new int[n + 1]; 12 | 13 | // n3 = n0*n2 + n1*n1 + n2*n0 0~ n-1 14 | // n2 = n0*n1 + n1*n0 15 | // n1 = n0*n0 16 | // n0 = 1 17 | for (int i = 0; i < n + 1; i++) { 18 | if (i == 0) { 19 | // if there is only 0 or 1 element, the result should be 1; 20 | num[i] = 1; 21 | } else { 22 | for (int j = 0; j < i; j++) { 23 | num[i] += num[j]*num[i - 1 - j]; 24 | } 25 | } 26 | } 27 | 28 | return num[n]; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /algorithm/others/PartitionArray.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class PartitionArray { 4 | public static void main(String[] strs) { 5 | PartitionArray pa = new PartitionArray(); 6 | int A[] = {1,2,6,7,9,3,4,6}; 7 | 8 | System.out.println(pa.partition(A, 0, A.length - 1, 7)); 9 | 10 | for(int i: A) { 11 | System.out.println(i); 12 | } 13 | } 14 | 15 | public int partition(int A[], int start, int end, int key) { 16 | int left = start; 17 | int right = end; 18 | 19 | while (left < right) { 20 | while (left < right && A[left] <= key) { 21 | left++; 22 | } 23 | 24 | while (left < right && A[right] > key) { 25 | right--; 26 | } 27 | 28 | swap(A, left, right); 29 | } 30 | 31 | 32 | 33 | return left; 34 | } 35 | 36 | public void swap(int[] A, int one, int two) { 37 | int tmp = A[one]; 38 | A[one] = A[two]; 39 | A[two] = tmp; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /algorithm/others/Permute.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.ArrayList; 3 | import java.util.Arrays; 4 | 5 | class Permute { 6 | public static void main(String[] strs) { 7 | Permute per = new Permute(); 8 | ArrayList> rst = per.permute(new int[]{1,2,3}); 9 | 10 | } 11 | 12 | public ArrayList> permute(int[] num) { 13 | ArrayList> rst = new ArrayList>(); 14 | ArrayList path = new ArrayList(); 15 | permuteHelp(num, rst, path); 16 | return rst; 17 | } 18 | 19 | public void permuteHelp(int[] num, ArrayList> rst, ArrayList path) { 20 | if (path.size() == num.length) { 21 | rst.add(new ArrayList(path)); 22 | return; 23 | } 24 | 25 | for (int i = 0; i < num.length; i++) { 26 | if (path.contains(num[i])) { 27 | continue; 28 | } 29 | 30 | path.add(num[i]); 31 | permuteHelp(num, rst, path); 32 | path.remove(path.size() - 1); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /algorithm/others/PlusOne.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class PlusOne { 4 | public static void main(String[] args) { 5 | PlusOne po = new PlusOne(); 6 | int[] digits = {1,2,3}; 7 | po.plusOne(digits); 8 | } 9 | 10 | public int[] plusOne(int[] digits) { 11 | if (digits.length == 0) { 12 | return digits; 13 | } 14 | 15 | int[] rst = new int[digits.length]; 16 | boolean next = true; 17 | 18 | for (int i = 0; i < digits.length; i++) { 19 | int tmp = digits[digits.length - i - 1]; 20 | if (next == true) { 21 | tmp++; 22 | if (tmp >= 10) { 23 | tmp = 0; 24 | next = true; 25 | } else { 26 | next = false; 27 | } 28 | } 29 | 30 | rst[digits.length - i - 1] = tmp; 31 | 32 | } 33 | return rst; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /algorithm/others/Point.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | class Point { 4 | int x; 5 | int y; 6 | Point() { 7 | x = 0; y = 0; 8 | } 9 | 10 | Point(int a, int b) { 11 | x = a; y = b; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /algorithm/others/Recover.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | import Algorithms.tree.TreeNode; 4 | 5 | public class Recover { 6 | private TreeNode big = null; 7 | private TreeNode small = null; 8 | private TreeNode pre = new TreeNode(Integer.MIN_VALUE); 9 | 10 | public void recoverTree(TreeNode root) { 11 | if (root == null) { 12 | return; 13 | } 14 | traverse(root); 15 | 16 | int tmp = big.val; 17 | big.val = small.val; 18 | small.val = tmp; 19 | 20 | } 21 | 22 | private void traverse(TreeNode root) { 23 | if (root == null) { 24 | return; 25 | } 26 | 27 | traverse(root.left); 28 | 29 | if (root.val < pre.val) { 30 | if (big == null) { 31 | big = pre; 32 | small = root; 33 | } else if (root.val < small.val){ 34 | small = root; 35 | } 36 | } 37 | 38 | if (big == null) { 39 | pre = root; 40 | } 41 | 42 | traverse(root.right); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /algorithm/others/Rectangle.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.Stack; 3 | 4 | 5 | public class Rectangle { 6 | public static void main(String[] args){ 7 | int[] input = {4,2,0,3,2,5}; 8 | 9 | int result = largestRectangleArea(input); 10 | System.out.printf("Result: %d\n", result); 11 | } 12 | 13 | public static int largestRectangleArea(int[] height) { 14 | if (height == null || height.length == 0){ 15 | return 0; 16 | } 17 | 18 | Stack stack = new Stack(); 19 | 20 | int rightBoard = 0; 21 | 22 | int maxArea = 0; 23 | 24 | stack.push(rightBoard); 25 | 26 | for (rightBoard = 1; rightBoard <= height.length; rightBoard ++){ 27 | int leftBoard; 28 | int h; 29 | int wide; 30 | 31 | int currentHeight = 0; 32 | if (rightBoard < height.length){ 33 | currentHeight = height[rightBoard]; 34 | } 35 | 36 | while (!stack.empty() && currentHeight < height[stack.peek()]){ 37 | /* get the left board of the rectangle. */ 38 | leftBoard = stack.pop(); 39 | h = height[leftBoard]; 40 | if (stack.empty()){ 41 | wide = rightBoard; 42 | }else{ 43 | //wide = rightBoard - leftBoard; 44 | wide = rightBoard - stack.peek() -1; 45 | } 46 | System.out.printf("area: %d, h:%d, w:%d\n", h*wide, h, wide); 47 | 48 | maxArea = Math.max(maxArea, h*wide); 49 | } 50 | 51 | stack.push(rightBoard); 52 | } 53 | 54 | return maxArea; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /algorithm/others/ReverseString.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class ReverseString { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /algorithm/others/Reverse_binary.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class Reverse_binary { 4 | public static void main(String[] strs) { 5 | System.out.println(reverse(20034556)); 6 | } 7 | 8 | public static int reverse(int in) { 9 | int ret = 0; 10 | 11 | for (int i = 0; i < 4; i++) { 12 | int tmp = (in & 0xFF); 13 | ret <<= 8; 14 | ret += tmp; 15 | in >>= 8; 16 | } 17 | 18 | return ret; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /algorithm/others/SingleNumber2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class SingleNumber2 { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /algorithm/others/SortColors.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.Collection; 3 | import java.util.LinkedList; 4 | 5 | public class SortColors { 6 | public void sortColors(int[] A) { 7 | 8 | int red = 0; 9 | int curr = 0; 10 | int blue = A.length - 1; 11 | 12 | while(curr <= blue) { 13 | /* 14 | while (A[blue] == 2 && curr < blue) { 15 | blue--; 16 | } 17 | 18 | while (A[red] == 0 && curr < blue) { 19 | red ++; 20 | } 21 | 22 | if (red >= curr){ 23 | curr = red + 1; 24 | }*/ 25 | 26 | if (A[curr] == 0) { 27 | swap(A, curr, red); 28 | curr++; 29 | red++; 30 | } else if (A[curr] == 1) { 31 | curr++; 32 | } else { 33 | swap(A, curr, blue); 34 | blue--; 35 | } 36 | } 37 | 38 | } 39 | 40 | public void swap(int[] a, int i, int j) { 41 | int temp = a[i]; 42 | a[i] = a[j]; 43 | a[j] = temp; 44 | } 45 | 46 | public static void main(String[] args){ 47 | SortColors sort = new SortColors(); 48 | 49 | int A[] = {1,0}; 50 | sort.sortColors(A); 51 | 52 | //Collection a = new LinkedList(A); 53 | 54 | System.out.printf("%d %d",A[0], A[1]); 55 | 56 | } 57 | } -------------------------------------------------------------------------------- /algorithm/others/SortList.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | public class SortList { 3 | public static void main(String[] str) { 4 | SortList sl = new SortList(); 5 | ListNode head = new ListNode(1); 6 | sl.sortList(head); 7 | 8 | } 9 | 10 | public ListNode sortList(ListNode head) { 11 | if (head == null) { 12 | return head; 13 | } 14 | 15 | ListNode mid = findMid(head); 16 | 17 | ListNode right = sortList(mid.next); 18 | mid.next = null; 19 | ListNode left = sortList(head); 20 | 21 | return merge(left, right); 22 | } 23 | 24 | private ListNode findMid(ListNode head) { 25 | ListNode s = head; 26 | ListNode f = head.next; 27 | while (f != null && f.next != null) { 28 | s = s.next; 29 | f = f.next.next; 30 | } 31 | 32 | return s; 33 | } 34 | 35 | private ListNode merge(ListNode head1, ListNode head2) { 36 | ListNode dummy = new ListNode(0); 37 | 38 | ListNode tail = dummy; 39 | 40 | while (head1 != null && head2 != null) { 41 | if (head1.val < head2.val) { 42 | tail.next = head1; 43 | head1 = head1.next; 44 | } else { 45 | tail.next = head2; 46 | head2 = head2.next; 47 | } 48 | 49 | tail = tail.next; 50 | } 51 | 52 | if (head1 != null) { 53 | tail.next = head1; 54 | } else { 55 | tail.next = head2; 56 | } 57 | 58 | return dummy.next; 59 | } 60 | } -------------------------------------------------------------------------------- /algorithm/others/SpiralMatrix.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | public class SpiralMatrix { 3 | public int[][] generateMatrix(int n) { 4 | int[][] rst = new int[n][n]; 5 | generateHelp(0, 1, rst, n); 6 | return rst; 7 | } 8 | 9 | private void generateHelp(int level, int beginNumber, int[][] rst, int n) { 10 | if (n % 2 == 0) { 11 | if (level == n/2) { 12 | return; 13 | } 14 | } else { 15 | if (level > n/2) { 16 | return; 17 | } 18 | } 19 | 20 | int right = n - 1 - level; 21 | 22 | int num = beginNumber; 23 | int i = level, j = level; 24 | 25 | // go through the first line. 26 | while (j <= right) { 27 | rst[i][j] = num; 28 | num++; 29 | j++; 30 | } 31 | 32 | while (i <= right) { 33 | rst[i][j] = num; 34 | num++; 35 | i++; 36 | } 37 | 38 | while (j > level) { 39 | rst[i][j] = num; 40 | num++; 41 | j--; 42 | } 43 | 44 | // go to the next level; 45 | generateHelp(level + 1, num, rst, n); 46 | return; 47 | } 48 | } -------------------------------------------------------------------------------- /algorithm/others/SpiralOrder.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.ArrayList; 3 | 4 | 5 | public class SpiralOrder { 6 | public ArrayList spiralOrder(int[][] matrix) { 7 | ArrayList result = new ArrayList(); 8 | 9 | // remember such kinds of board. 10 | if (matrix.length == 0 || matrix[0].length == 0) { 11 | return result; 12 | } 13 | 14 | spiralOrderhelp(matrix, result, matrix.length, matrix[0].length); 15 | 16 | return result; 17 | } 18 | 19 | // m, n: the middle m lines and n columns. 20 | public void spiralOrderhelp(int[][] matrix, ArrayList result, int m, int n) { 21 | if (m <= 0 || n <= 0) { 22 | return; 23 | } 24 | 25 | // setup the begin point. 26 | int lineB = (matrix.length - m)/2; 27 | int colB = (matrix[0].length - n)/2; 28 | 29 | int line = lineB; 30 | int col = colB-1; // begin from the first element. 31 | 32 | while (col < colB+n-1) { 33 | result.add(matrix[line][++col]); 34 | } 35 | 36 | 37 | while (line < lineB+m-1) { 38 | result.add(matrix[++line][col]); 39 | } 40 | 41 | // eliminate the duplicate calculating. 42 | while (col > colB && line != lineB) { 43 | result.add(matrix[line][--col]); 44 | } 45 | 46 | // eliminate the duplicate calculating. 47 | while (line > lineB+1 && col != colB) { 48 | result.add(matrix[--line][col]); 49 | } 50 | 51 | spiralOrderhelp(matrix, result, m-2, n-2); 52 | } 53 | 54 | public static void main(String[] args) { 55 | int[][] input = {{2,3}}; 56 | SpiralOrder test = new SpiralOrder(); 57 | ArrayList result = test.spiralOrder(input); 58 | System.out.printf(result.toString()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /algorithm/others/Sqrt.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class Sqrt { 4 | public static int sqrt(int x) { 5 | if (x == 0) { 6 | return x; 7 | } 8 | 9 | int left = 1; 10 | int right = x; 11 | 12 | int curr = 0; 13 | 14 | while(left < right) { 15 | curr = (left + right)/2; 16 | int rst = x/curr; 17 | 18 | System.out.printf("curr: %d rst:%d left:%d right:%d\n", curr, rst, left, right); 19 | 20 | if (rst == curr){ 21 | return rst; 22 | } else if (rst > curr) { 23 | left = curr+1; 24 | } else { 25 | right = curr-1; 26 | } 27 | } 28 | 29 | 30 | System.out.printf("Ret: curr: %d left:%d right:%d x/left:%d \n", curr, left, right, x/left); 31 | 32 | if (x/left >= left) { 33 | return left; 34 | } else { 35 | return left - 1; 36 | } 37 | } 38 | 39 | public static void main(String[] args) { 40 | int rst = sqrt(8); 41 | System.out.printf("rst: %d", rst); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /algorithm/others/SubSet2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | import java.util.ArrayList; 3 | import java.util.Arrays; 4 | 5 | public class SubSet2 { 6 | public static void main(String[] args){ 7 | int[] a = {1,2,3}; 8 | ArrayList> test = subsets(a); 9 | } 10 | 11 | public static ArrayList> subsets(int[] num) { 12 | ArrayList> result = new ArrayList>(); 13 | if(num == null || num.length == 0) { 14 | return result; 15 | } 16 | ArrayList list = new ArrayList(); 17 | Arrays.sort(num); 18 | subsetsHelper(result, list, num, 0); 19 | 20 | return result; 21 | } 22 | 23 | 24 | private static void subsetsHelper(ArrayList> result, 25 | ArrayList list, int[] num, int pos) { 26 | 27 | result.add(new ArrayList(list)); 28 | 29 | System.out.printf("generate: %s pos:%d\n", list.toString(), pos); 30 | 31 | for (int i = pos; i < num.length; i++) { 32 | 33 | list.add(num[i]); 34 | System.out.printf("ADD:%d\n", num[i]); 35 | 36 | subsetsHelper(result, list, num, i + 1); 37 | 38 | System.out.printf("REMOVE:%d i=%d\n", list.get(list.size() - 1),i); 39 | list.remove(list.size() - 1); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /algorithm/others/TestArrayChange.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.others; 2 | 3 | public class TestArrayChange { 4 | public static void main(String[] args) { 5 | char[][] A = { 6 | {'1','2'}, 7 | {'3','4'} 8 | }; 9 | TestArrayChange.changeValue(A); 10 | 11 | for (int i = 0; i < 2; i++) { 12 | for (int j = 0; j < 2; j++) { 13 | System.out.print(A[i][j]); 14 | } 15 | System.out.println(); 16 | } 17 | } 18 | 19 | public static void changeValue(char[][] A) { 20 | A[0][0] = '5'; 21 | return; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /algorithm/sort/WaveSort.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.sort; 2 | 3 | import java.util.Arrays; 4 | 5 | /* 6 | * 给定一个未排序的数组,请给出波浪状排序: 7 | * Example: 8 | * input: 1 2 5 4 3 9 9 | * output: 1 4 3 5 2 9 10 | * 11 | * input: 1 2 2 5 3 9 12 | * output: 1 5 2 3 2 9 13 | * */ 14 | public class WaveSort { 15 | public static void main(String[] str) { 16 | int[] in = {1,2,5,4,3,9,9,9, 12}; 17 | 18 | for (int i: in) { 19 | System.out.print(i + " "); 20 | } 21 | System.out.println(); 22 | 23 | waveSort(in); 24 | for (int i: in) { 25 | System.out.print(i + " "); 26 | } 27 | } 28 | 29 | public static void waveSort(int[] in) { 30 | if (in == null) { 31 | return; 32 | } 33 | 34 | // there should be at least 3 numbers. 35 | if (in.length <= 2) { 36 | return; 37 | } 38 | 39 | int len = in.length; 40 | 41 | Arrays.sort(in); 42 | 43 | for (int i: in) { 44 | System.out.print(i + " "); 45 | } 46 | System.out.println(); 47 | 48 | for (int i = 0; i < len; i++) { 49 | if (i % 2 == 0) { 50 | for (int j = i + 1; j < len; j++) { 51 | if (in[j] != in[i]) { 52 | int tmp = in[i]; 53 | in[i] = in[j]; 54 | in[j] = tmp; 55 | break; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | 62 | public static void findKthNumber(int[] in, int k) { 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /algorithm/thread/Thread11.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.thread; 2 | 3 | public class Thread11 extends Thread { 4 | String resource1; 5 | String resource2; 6 | 7 | public Thread11(String resource1, String reource2) { 8 | this.resource1 = resource1; 9 | this.resource2 = reource2; 10 | System.out.println("coming1"); 11 | } 12 | 13 | public void run() { 14 | synchronized (resource1) { 15 | System.out.println("Thread 1: locked resource 1"); 16 | try { 17 | Thread.sleep(1000); 18 | } catch (Exception e) { 19 | } 20 | 21 | synchronized (resource2) { 22 | System.out.println("Thread 1: locked resource 2"); 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /algorithm/thread/Thread22.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.thread; 2 | 3 | public class Thread22 extends Thread { 4 | String resource1; 5 | String resource2; 6 | 7 | public Thread22(String resource1, String reource2) { 8 | this.resource1 = resource1; 9 | this.resource2 = reource2; 10 | System.out.println("coming2"); 11 | } 12 | 13 | public void run() { 14 | synchronized (resource2) { 15 | System.out.println("Thread 2: locked resource 2"); 16 | 17 | try { 18 | Thread.sleep(1000); 19 | } catch (Exception e) { 20 | } 21 | 22 | synchronized (resource1) { 23 | System.out.println("Thread 2: locked resource 1"); 24 | } 25 | 26 | } 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /algorithm/thread/ThreadDemo.java: -------------------------------------------------------------------------------- 1 | package Algorithms.algorithm.thread; 2 | 3 | public class ThreadDemo { 4 | public static void main(String args[]) { 5 | new NewThread(); // 创建一个新线程 6 | try { 7 | for (int i = 5; i > 0; i--) { 8 | //System.out.println("Main Thread: " + i); 9 | Thread.sleep(100); 10 | } 11 | } catch (InterruptedException e) { 12 | System.out.println("Main thread interrupted."); 13 | } 14 | System.out.println("Main thread exiting."); 15 | } 16 | } -------------------------------------------------------------------------------- /array/FirstMissingPositive.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class FirstMissingPositive { 4 | public static void main(String[] strs) { 5 | int[] in = {1,4,2,3}; 6 | //int[] in = {3,4,-1,1}; 7 | System.out.println(firstMissingPositive(in)); 8 | } 9 | 10 | public static int firstMissingPositive1(int[] A) { 11 | if (A == null) { 12 | return 0; 13 | } 14 | 15 | int len = A.length; 16 | for (int i = 0; i < len; i++) { 17 | // 1. The number should be in the range. 18 | // 2. The number should be positive. 19 | while (A[i] <= len && A[i] > 0 && A[A[i] - 1] != A[i]) { 20 | swap(A, i, A[i] - 1); 21 | } 22 | } 23 | 24 | for (int i = 0; i < len; i++) { 25 | if (A[i] != i + 1) { 26 | return i + 1; 27 | } 28 | } 29 | 30 | return len + 1; 31 | } 32 | 33 | public static void swap(int[] A, int i, int j) { 34 | int tmp = A[i]; 35 | A[i] = A[j]; 36 | A[j] = tmp; 37 | } 38 | 39 | // SOLUTION 2: 40 | public static int firstMissingPositive(int[] A) { 41 | // bug 3: when length is 0, return 1; 42 | if (A == null) { 43 | return 0; 44 | } 45 | 46 | for (int i = 0; i < A.length; i++) { 47 | // 1: A[i] is in the range; 48 | // 2: A[i] > 0. 49 | // 3: The target is different; 50 | while (A[i] <= A.length && A[i] > 0 && A[A[i] - 1] != A[i]) { 51 | swap(A, i, A[i] - 1); 52 | } 53 | } 54 | 55 | for (int i = 0; i < A.length; i++) { 56 | if (A[i] != i + 1) { 57 | return i + 1; 58 | } 59 | } 60 | 61 | return A.length + 1; 62 | } 63 | } -------------------------------------------------------------------------------- /array/Interval.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class Interval { 4 | int start; 5 | int end; 6 | 7 | Interval() { 8 | start = 0; 9 | end = 0; 10 | } 11 | 12 | Interval(int s, int e) { 13 | start = s; 14 | end = e; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /array/LargestRectangleArea.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | import java.util.Stack; 4 | 5 | public class LargestRectangleArea { 6 | public static void main(String[] strs) { 7 | int[] height = {0}; 8 | System.out.println(largestRectangleArea(height)); 9 | } 10 | 11 | public static int largestRectangleArea(int[] height) { 12 | if (height == null || height.length == 0) { 13 | return 0; 14 | } 15 | 16 | Stack s = new Stack(); 17 | 18 | int max = 0; 19 | 20 | int len = height.length; 21 | int i = 0; 22 | 23 | while (i <= len) { 24 | // BUG 1: should use height[s.peek()] instead of s.peek(). 25 | // BUG 2: should put i < length after the s.isEmpty. 26 | // The last step: Length is also put into the stack and will break at last. 27 | if (s.isEmpty() || (i < len && height[i] >= height[s.peek()])) { 28 | s.push(i); 29 | i++; 30 | // Keep a Ascending sequence in the stack. 31 | } else { 32 | // Stack is not empty, and the current node is smaller than the one in the stack. 33 | // When we come to the end of the array, we will also should count all the solutions. 34 | // BUG 3: should use height[s.pop] instead of s.pop 35 | // When the i come to the end, the rectangle will be counted again. 36 | int h = height[s.pop()]; 37 | int width = s.isEmpty() ? i: i - s.peek() - 1; 38 | max = Math.max(max, h * width); 39 | } 40 | } 41 | 42 | return max; 43 | } 44 | } -------------------------------------------------------------------------------- /array/MaxSubArray.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class MaxSubArray { 4 | public int maxSubArray(int[] A) { 5 | if (A == null || A.length == 0) { 6 | return 0; 7 | } 8 | 9 | int len = A.length; 10 | int sum = 0; 11 | 12 | // 记录下最大值 13 | int max = Integer.MIN_VALUE; 14 | for (int i = 0; i < len; i++) { 15 | // 加上当前值 16 | sum += A[i]; 17 | max = Math.max(max, sum); 18 | 19 | // 如果和小于0,则可以丢弃之,下一个值重新计算即可。 20 | // 因为对于每一个值来说,有2处选择:加上前面的一些数,或是不加。如果是负数,可以不加。 21 | sum = Math.max(0, sum); 22 | } 23 | 24 | return max; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /array/MaxSubArray_1220_2014.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class MaxSubArray_1220_2014 { 4 | public int maxSubArray(int[] A) { 5 | if (A == null || A.length == 0) { 6 | return 0; 7 | } 8 | 9 | int max = Integer.MIN_VALUE; 10 | int sum = 0; 11 | 12 | int len = A.length; 13 | for (int i = 0; i < len; i++) { 14 | if (sum < 0) { 15 | sum = 0; 16 | } 17 | 18 | sum += A[i]; 19 | max = Math.max(max, sum); 20 | } 21 | 22 | return max; 23 | } 24 | } -------------------------------------------------------------------------------- /array/MaximalRectangle.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | import java.util.Stack; 4 | 5 | public class MaximalRectangle { 6 | public int maximalRectangle(char[][] matrix) { 7 | if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { 8 | return 0; 9 | } 10 | 11 | int rows = matrix.length; 12 | int cols = matrix[0].length; 13 | 14 | int[][] h = new int[rows][cols]; 15 | 16 | int max = 0; 17 | 18 | for (int i = 0; i < rows; i++) { 19 | for (int j = 0; j < cols; j++) { 20 | 21 | h[i][j] = matrix[i][j] == '1' ? 1: 0; 22 | 23 | if (i != 0 && h[i][j] != 0) { 24 | h[i][j] = h[i - 1][j] + 1; 25 | } 26 | 27 | if (j == cols - 1) { 28 | max = Math.max(max, maxArea(h[i])); 29 | } 30 | } 31 | } 32 | 33 | return max; 34 | } 35 | 36 | public int maxArea(int[] h) { 37 | Stack s = new Stack(); 38 | 39 | int max = 0; 40 | int i = 0; 41 | 42 | // 注意,这里使用<= 因为当i到达最后,需要计算一次。 43 | while (i <= h.length) { 44 | // 45 | if (s.isEmpty() || i < h.length && h[i] >= h[s.peek()]) { 46 | s.push(i); 47 | i++; 48 | } else { 49 | int height = h[s.pop()]; 50 | int width = s.isEmpty() ? i: i - s.peek() - 1; 51 | max = Math.max(max, height * width); 52 | } 53 | } 54 | 55 | return max; 56 | } 57 | } -------------------------------------------------------------------------------- /array/Merge.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.Iterator; 7 | import java.util.List; 8 | 9 | /** 10 | * Definition for an interval. 11 | * public class Interval { 12 | * int start; 13 | * int end; 14 | * Interval() { start = 0; end = 0; } 15 | * Interval(int s, int e) { start = s; end = e; } 16 | * } 17 | */ 18 | public class Merge { 19 | public List merge(List intervals) { 20 | List ret = new ArrayList(); 21 | if (intervals == null || intervals.size() == 0) { 22 | return ret; 23 | } 24 | 25 | Collections.sort(intervals, new Comparator() { 26 | public int compare(Interval o1, Interval o2) { 27 | // sort the intervals by the start. 28 | return o1.start - o2.start; 29 | } 30 | }); 31 | 32 | // 作为最后一个插入的区间 33 | Interval last = intervals.get(0); 34 | 35 | // 这里要考虑性能。使用iterator的话,对linkedlist会更快. 36 | Iterator itor = intervals.iterator(); 37 | while (itor.hasNext()) { 38 | Interval cur = itor.next(); 39 | // cur 在last的右边 40 | if (cur.start > last.end) { 41 | // 将cur作为新的last. 42 | ret.add(last); 43 | last = cur; 44 | // cur与last有重合的部分,合并之 45 | } else { 46 | int s = last.start; 47 | int e = Math.max(last.end, cur.end); 48 | last = new Interval(s, e); 49 | } 50 | } 51 | 52 | // 把最后一个区间加上 53 | ret.add(last); 54 | 55 | return ret; 56 | } 57 | } -------------------------------------------------------------------------------- /array/MergeSortedArray.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class MergeSortedArray { 4 | public void merge(int A[], int m, int B[], int n) { 5 | int cur = m + n - 1; 6 | 7 | // 指向A的尾部 8 | int pA = m - 1; 9 | 10 | // 指向B的尾部 11 | int pB = n - 1; 12 | 13 | while (cur >= 0) { 14 | if (pA < 0 || pB < 0) { 15 | break; 16 | } 17 | 18 | // 从尾部往前比较 19 | if (A[pA] > B[pB]) { 20 | A[cur] = A[pA--]; 21 | } else { 22 | A[cur] = B[pB--]; 23 | } 24 | 25 | cur--; 26 | } 27 | 28 | // copy the left over elements in B to A. 29 | System.arraycopy(B, 0, A, 0, pB + 1); 30 | 31 | return; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /array/PlusOne.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class PlusOne { 4 | public int[] plusOne(int[] digits) { 5 | if (digits == null) { 6 | return null; 7 | } 8 | 9 | int overFlow = 0; 10 | 11 | int len = digits.length; 12 | int[] ret = new int[len]; 13 | 14 | for (int i = len - 1; i >= 0; i--) { 15 | int sum = digits[i] + overFlow; 16 | if (i == len - 1) { 17 | // 只有最后一位需要加1 18 | sum++; 19 | } 20 | 21 | // 溢出的话,置溢出位。 22 | if (sum > 9) { 23 | overFlow = 1; 24 | } else { 25 | overFlow = 0; 26 | } 27 | 28 | // 把高位去掉,因为我们要0-9 29 | ret[i] = sum % 10; 30 | } 31 | 32 | if (overFlow == 1) { 33 | int[] retOver = new int[len + 1]; 34 | System.arraycopy(retOver, 1, ret, 0, len); 35 | retOver[0] = 1; 36 | return retOver; 37 | } 38 | 39 | return ret; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /array/RemoveDuplicates.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class RemoveDuplicates { 4 | public int removeDuplicates(int[] A) { 5 | if (A == null || A.length == 0) { 6 | return 0; 7 | } 8 | 9 | // A里至少有1个元素 10 | int len = 1; 11 | 12 | for (int i = 1; i < A.length; i++) { 13 | if (A[i] != A[i - 1]) { 14 | A[len++] = A[i]; 15 | } 16 | } 17 | 18 | return len; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /array/RemoveDuplicates2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class RemoveDuplicates2 { 4 | public static int removeDuplicates(int[] A) { 5 | if (A == null) { 6 | return 0; 7 | } 8 | 9 | if (A.length <= 1) { 10 | return A.length; 11 | } 12 | 13 | int len = 1; 14 | 15 | // 拷贝2次后就不再拷贝 16 | boolean canCopy = true; 17 | 18 | for (int i = 1; i < A.length; i++) { 19 | if (A[i] == A[i - 1]) { 20 | if (!canCopy) { 21 | continue; 22 | } 23 | canCopy = false; 24 | } else { 25 | canCopy = true; 26 | } 27 | 28 | A[len++] = A[i]; 29 | } 30 | 31 | return len; 32 | } 33 | 34 | public static void main(String[] strs) { 35 | int[] A = {1,1,1,2,2,3}; 36 | removeDuplicates(A); 37 | 38 | for (int i: A) { 39 | System.out.print(i + " "); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /array/RemoveElement.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class RemoveElement { 4 | public int removeElement(int[] A, int elem) { 5 | if (A == null || A.length == 0) { 6 | return 0; 7 | } 8 | 9 | int cur = 0; 10 | int len = 0; 11 | while (cur < A.length) { 12 | if (A[cur] != elem) { 13 | A[len++] = A[cur++]; 14 | } else { 15 | cur++; 16 | } 17 | } 18 | 19 | return len; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /array/Rotate.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class Rotate { 4 | public void rotate(int[][] matrix) { 5 | if (matrix == null || matrix.length == 0 6 | || matrix[0].length == 0) { 7 | return; 8 | } 9 | 10 | int n = matrix.length; 11 | int top = 0, down = n - 1, left = 0, right = n - 1; 12 | 13 | while (n > 1) { 14 | for (int i = 0; i < n - 1; i++) { 15 | int tmp = matrix[top][left + i]; 16 | // 另上边等于左边 17 | matrix[top][left + i] = matrix[down - i][left]; 18 | 19 | // 另左边等于下边 20 | matrix[down - i][left] = matrix[down][right - i]; 21 | 22 | // 另下边等于右边 23 | matrix[down][right - i] = matrix[top + i][right]; 24 | 25 | // 另右边等于上边 26 | matrix[top + i][right] = tmp; 27 | } 28 | top++; 29 | right--; 30 | left++; 31 | down--; 32 | 33 | n -= 2; 34 | } 35 | 36 | return; 37 | } 38 | } -------------------------------------------------------------------------------- /array/SpiralOrder_1201.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class SpiralOrder_1201 { 7 | public List spiralOrder(int[][] matrix) { 8 | List ret = new ArrayList(); 9 | if (matrix == null ||matrix.length == 0) { 10 | // 注意在非法的时候,应该返回空解,而不是一个NULL值 11 | return ret; 12 | } 13 | 14 | // Record how many rows and cols we still have. 15 | int rows = matrix.length; 16 | int cols = matrix[0].length; 17 | 18 | // The four coners. 19 | int top = 0; 20 | int left = 0; 21 | int bottom = rows - 1; 22 | int right = cols - 1; 23 | 24 | // every time we go through two rows and two cols. 25 | for (; rows > 0 && cols > 0; rows -= 2, cols -= 2, top++, left++, bottom--, right--) { 26 | // the first line. 27 | for (int i = left; i <= right; i++) { 28 | ret.add(matrix[top][i]); 29 | } 30 | 31 | // the right column. 32 | for (int i = top + 1; i < bottom; i++) { 33 | ret.add(matrix[i][right]); 34 | } 35 | 36 | // the down line; 37 | if (rows > 1) { 38 | for (int j = right; j >= left; j--) { 39 | ret.add(matrix[bottom][j]); 40 | } 41 | } 42 | 43 | // the left column. 44 | if (cols > 1) { 45 | for (int i = bottom - 1; i > top; i --) { 46 | ret.add(matrix[i][left]); 47 | } 48 | } 49 | } 50 | 51 | return ret; 52 | } 53 | } -------------------------------------------------------------------------------- /array/TierTree.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class TierTree { 4 | public static void main(String[] strs) { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /array/Trap.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | 3 | public class Trap { 4 | public int trap1(int[] A) { 5 | if (A == null) { 6 | return 0; 7 | } 8 | 9 | int max = 0; 10 | 11 | int len = A.length; 12 | int[] left = new int[len]; 13 | int[] right = new int[len]; 14 | 15 | // count the highest bar from the left to the current. 16 | for (int i = 0; i < len; i++) { 17 | left[i] = i == 0 ? A[i]: Math.max(left[i - 1], A[i]); 18 | } 19 | 20 | // count the highest bar from right to current. 21 | for (int i = len - 1; i >= 0; i--) { 22 | right[i] = i == len - 1 ? A[i]: Math.max(right[i + 1], A[i]); 23 | } 24 | 25 | // count the largest water which can contain. 26 | for (int i = 0; i < len; i++) { 27 | int height = Math.min(right[i], left[i]); 28 | if (height > A[i]) { 29 | max += height - A[i]; 30 | } 31 | } 32 | 33 | return max; 34 | } 35 | 36 | public int trap(int[] A) { 37 | // 2:37 38 | if (A == null) { 39 | return 0; 40 | } 41 | 42 | int len = A.length; 43 | int[] l = new int[len]; 44 | int[] r = new int[len]; 45 | 46 | for (int i = 0; i < len; i++) { 47 | if (i == 0) { 48 | l[i] = A[i]; 49 | } else { 50 | l[i] = Math.max(l[i - 1], A[i]); 51 | } 52 | } 53 | 54 | int water = 0; 55 | for (int i = len - 1; i >= 0; i--) { 56 | if (i == len - 1) { 57 | r[i] = A[i]; 58 | } else { 59 | // but: use Math, not max 60 | r[i] = Math.max(r[i + 1], A[i]); 61 | } 62 | 63 | water += Math.min(l[i], r[i]) - A[i]; 64 | } 65 | 66 | return water; 67 | } 68 | } -------------------------------------------------------------------------------- /array/TwoSum.java: -------------------------------------------------------------------------------- 1 | package Algorithms.array; 2 | import java.util.HashMap; 3 | 4 | 5 | public class TwoSum { 6 | public int[] twoSum(int[] numbers, int target) { 7 | int[] rst = new int[2]; 8 | 9 | int len = numbers.length; 10 | HashMap hm = new HashMap(); 11 | 12 | for (int i = 0; i< len; i++) { 13 | Integer j = hm.get(target-numbers[i]); 14 | if ((j = hm.get(target-numbers[i])) != null) { 15 | rst[0] = j+1; 16 | rst[1] = i+1; 17 | return rst; 18 | } 19 | 20 | hm.put(numbers[i], i); 21 | } 22 | 23 | return rst; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /bfs/LadderLength.java: -------------------------------------------------------------------------------- 1 | package Algorithms.bfs; 2 | 3 | import java.util.HashSet; 4 | import java.util.LinkedList; 5 | import java.util.Queue; 6 | import java.util.Set; 7 | 8 | public class LadderLength { 9 | public int ladderLength(String start, String end, Set dict) { 10 | if (start == null || end == null) { 11 | return 0; 12 | } 13 | 14 | // we use BFS to solve the problem. use a QUEUE to store all the solutions in one level. 15 | Queue q = new LinkedList(); 16 | 17 | int level = 0; 18 | 19 | q.offer(start); 20 | 21 | // 避免计算到重复的字符串 22 | HashSet set = new HashSet(); 23 | set.add(start); 24 | 25 | while (!q.isEmpty()) { 26 | int size = q.size(); 27 | 28 | level++; 29 | for (int i = 0; i < size; i++) { 30 | String s = q.poll(); 31 | 32 | int len = s.length(); 33 | for (int j = 0; j < len; j++) { 34 | StringBuilder sb = new StringBuilder(s); 35 | // 注意,这时是char 36 | for (char c = 'a'; c <= 'z'; c++) { 37 | sb.setCharAt(j, c); 38 | 39 | String tmp = sb.toString(); 40 | 41 | if (tmp.equals(end)) { 42 | return level + 1; 43 | } 44 | 45 | if (!set.contains(tmp) && dict.contains(tmp)) { 46 | set.add(tmp); 47 | q.offer(tmp); 48 | } 49 | } 50 | } 51 | 52 | } 53 | } 54 | 55 | return 0; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /binarySearch/Divide.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuzhangcmu/LeetCode/eb2aaeada59cf42ea26f4003f9709c4f1b05ac17/binarySearch/Divide.java -------------------------------------------------------------------------------- /binarySearch/FindMin2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.binarySearch; 2 | 3 | 4 | /* 5 | * Find Minimum in Rotated Sorted Array II Total Accepted: 2541 Total Submissions: 9558 My Submissions Question Solution 6 | Follow up for "Find Minimum in Rotated Sorted Array": 7 | What if duplicates are allowed? 8 | 9 | Would this affect the run-time complexity? How and why? 10 | Suppose a sorted array is rotated at some pivot unknown to you beforehand. 11 | 12 | (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). 13 | 14 | Find the minimum element. 15 | 16 | The array may contain duplicates. 17 | * */ 18 | public class FindMin2 { 19 | public int findMin(int[] num) { 20 | if (num == null || num.length == 0) { 21 | return 0; 22 | } 23 | 24 | int len = num.length; 25 | if (len == 1) { 26 | return num[0]; 27 | } else if (len == 2) { 28 | return Math.min(num[0], num[1]); 29 | } 30 | 31 | int left = 0; 32 | int right = len - 1; 33 | 34 | while (left < right - 1) { 35 | int mid = left + (right - left) / 2; 36 | // In this case, the array is sorted. 37 | // 这一句很重要,因为我们移除一些元素后,可能会使整个数组变得有序... 38 | if (num[left] < num[right]) { 39 | return num[left]; 40 | } 41 | 42 | // left side is sorted. CUT the left side. 43 | if (num[mid] > num[left]) { 44 | left = mid; 45 | // left side is unsorted, right side is sorted. CUT the right side. 46 | } else if (num[mid] < num[left]) { 47 | right = mid; 48 | } else { 49 | left++; 50 | } 51 | } 52 | 53 | return Math.min(num[left], num[right]); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /binarySearch/FindPeakElement.java: -------------------------------------------------------------------------------- 1 | package Algorithms.binarySearch; 2 | 3 | public class FindPeakElement { 4 | public int findPeakElement1(int[] num) { 5 | if (num == null) { 6 | return 0; 7 | } 8 | 9 | if (num.length == 1) { 10 | return 0; 11 | } 12 | 13 | for (int i = 0; i < num.length; i++) { 14 | if (i == 0) { 15 | if (num[i] > num[i + 1]) { 16 | return i; 17 | } 18 | continue; 19 | } 20 | 21 | if (i == num.length - 1) { 22 | if (num[i] > num[i - 1]) { 23 | return i; 24 | } 25 | continue; 26 | } 27 | 28 | if (num[i] > num[i + 1] && num[i] > num[i - 1]) { 29 | return i; 30 | } 31 | } 32 | 33 | return -1; 34 | } 35 | 36 | public int findPeakElement(int[] num) { 37 | if (num == null) { 38 | return 0; 39 | } 40 | 41 | if (num.length == 1) { 42 | return 0; 43 | } 44 | 45 | int l = 0; 46 | int r = num.length - 1; 47 | 48 | while (l < r - 1) { 49 | int mid = l + (r - l) / 2; 50 | if (num[mid] > num[mid + 1] && num[mid] > num[mid - 1]) { 51 | return mid; 52 | } 53 | 54 | if (num[mid] > num[mid - 1] && num[mid] < num[mid + 1]) { 55 | // rising area. move right; 56 | l = mid; 57 | } else if (num[mid] < num[mid - 1] && num[mid] > num[mid + 1]) { 58 | r = mid; 59 | } else { 60 | l = mid; 61 | } 62 | } 63 | 64 | return num[l] > num[r] ? l: r; 65 | } 66 | } -------------------------------------------------------------------------------- /binarySearch/searchInsert.java: -------------------------------------------------------------------------------- 1 | package Algorithms.binarySearch; 2 | 3 | public class searchInsert { 4 | public static void main(String[] args) { 5 | int[] A = {1,3,5,6}; 6 | int target = 0; 7 | 8 | System.out.println(searchInsert(A, target)); 9 | } 10 | 11 | public static int searchInsert(int[] A, int target) { 12 | int low = 0, high = A.length-1; 13 | int mid = low + (high-low)/2; 14 | 15 | while(low <= high){ 16 | mid = low + (high-low)/2; 17 | if(A[mid] == target){ 18 | return mid; 19 | }else if(target > A[mid]){ 20 | low = mid+1; 21 | }else{ 22 | high = mid-1; 23 | } 24 | } 25 | 26 | // 返回下限值,此时刚好为适合插入的位置 27 | return low; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /combination/CombinationSum.java: -------------------------------------------------------------------------------- 1 | package Algorithms.combination; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class CombinationSum { 8 | public List> combinationSum(int[] candidates, int target) { 9 | List> ret = new ArrayList>(); 10 | if (candidates == null || candidates.length == 0) { 11 | return ret; 12 | } 13 | 14 | List path = new ArrayList(); 15 | 16 | // we should sort the candidates than do it. in this case we can get a non-descending order. 17 | Arrays.sort(candidates); 18 | 19 | combinationSum(candidates, target, path, ret, 0); 20 | return ret; 21 | } 22 | 23 | public void combinationSum(int[] candidates, int target, List path, List> ret, int index) { 24 | if (target == 0) { 25 | // add the current set into the result. 26 | ret.add(new ArrayList(path)); 27 | return; 28 | } 29 | 30 | if (target < 0) { 31 | return; 32 | } 33 | 34 | int len = candidates.length; 35 | for (int i = index; i < len; i++) { 36 | int num = candidates[i]; 37 | path.add(num); 38 | combinationSum(candidates, target - num, path, ret, i); 39 | path.remove(path.size() - 1); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /combination/CombinationSum_1203.java: -------------------------------------------------------------------------------- 1 | package Algorithms.combination; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class CombinationSum_1203 { 8 | public List> combinationSum(int[] candidates, int target) { 9 | List> ret = new ArrayList>(); 10 | if (candidates == null || candidates.length == 0) { 11 | return ret; 12 | } 13 | 14 | // Sort to avoid duplicate solutions. 15 | Arrays.sort(candidates); 16 | 17 | dfs(candidates, target, new ArrayList(), ret, 0); 18 | return ret; 19 | } 20 | 21 | public void dfs(int[] candidates, int target, List path, List> ret, int index) { 22 | if (target < 0) { 23 | return; 24 | } 25 | 26 | if (target == 0) { 27 | ret.add(new ArrayList(path)); 28 | return; 29 | } 30 | 31 | // i 的起始值是跟排列的最主要区别。因为与顺序无关,所以我们必须只能是升序,也就是说下一个取值只能是i本身 32 | // 或是i的下一个。 33 | // 但是排列的话,可以再取前同的。1, 2 与2 1是不同的排列,但是同一个组合 34 | for (int i = index; i < candidates.length; i++) { 35 | int num = candidates[i]; 36 | path.add(num); 37 | 38 | // 注意,最后的参数是i,不是index!! 39 | dfs(candidates, target - num, path, ret, i); 40 | path.remove(path.size() - 1); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /combination/Combinations.java: -------------------------------------------------------------------------------- 1 | package Algorithms.combination; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Combinations { 7 | public List> combine(int n, int k) { 8 | List> ret = new ArrayList>(); 9 | 10 | if (n == 0 || k == 0) { 11 | return ret; 12 | } 13 | 14 | List path = new ArrayList(); 15 | 16 | combine(n, k, path, ret, 1); 17 | 18 | return ret; 19 | } 20 | 21 | // index means the position which I can choose from. 22 | // for example: when n = 4, 23 | // 1, 2, 3, 4, and index = 1, means now I can choose a number from 1 - 4 24 | // 25 | public void combine(int n, int k, List path, List> ret, int index) { 26 | if (0 == k) { 27 | ret.add(new ArrayList(path)); 28 | return; 29 | } 30 | 31 | // 注意这里的终止条件. 32 | // For example: N = 4的时候,K = 2的时候, 33 | // 这里还有2个可以取值,那么 1, 2, 3, 4中index最多可以从3取值,也就是4-2+1. 34 | // 就是 n - k + 1 35 | for (int i = index; i <= n - k + 1; i++) { 36 | path.add(i); 37 | combine(n, k - 1, path, ret, i + 1); 38 | path.remove(path.size() - 1); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /combination/Combine_1203.java: -------------------------------------------------------------------------------- 1 | package Algorithms.combination; 2 | import java.util.ArrayList; 3 | import java.util.List; 4 | 5 | public class Combine_1203 { 6 | public List> combine(int n, int k) { 7 | List> ret = new ArrayList>(); 8 | if (k == 0) { 9 | ret.add(new ArrayList()); 10 | return ret; 11 | } 12 | 13 | // 注意:start应该从1开始。因为我们的数字是1 14 | dfs(n, k, new ArrayList(), ret, 1); 15 | return ret; 16 | } 17 | 18 | // SOLUTION 1: 19 | // 注意,因为求的是组合,所以我们要考虑一下顺序问题,只需要考虑升序。这样的话就不会有重复的 20 | // 的组合。 21 | public void dfs1(int n, int k, List path, List> ret, int start) { 22 | if (path.size() == k) { 23 | ret.add(new ArrayList(path)); 24 | return; 25 | } 26 | 27 | // 注意这里的条件i <= n 取n也是合法的! 28 | // Example: 29 | for (int i = start; i <= n; i++) { 30 | path.add(i); 31 | 32 | // 注意,最后一个参数是i + 1,不是start + 1!! 33 | dfs(n, k, path, ret, i + 1); 34 | path.remove(path.size() - 1); 35 | } 36 | } 37 | 38 | // SOLUTION 2: 39 | public void dfs(int n, int k, List path, List> ret, int start) { 40 | if (0 == k) { 41 | ret.add(new ArrayList(path)); 42 | return; 43 | } 44 | 45 | // 注意这里的条件i <= n 取n也是合法的! 46 | // Example: 47 | for (int i = start; i <= (n - k + 1); i++) { 48 | path.add(i); 49 | 50 | // 注意,最后一个参数是i + 1,不是start + 1!! 51 | dfs(n, k - 1, path, ret, i + 1); 52 | path.remove(path.size() - 1); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /combination/LetterCombinations.java: -------------------------------------------------------------------------------- 1 | package Algorithms.combination; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class LetterCombinations { 7 | String[] map = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; 8 | 9 | public List letterCombinations(String digits) { 10 | List ret = new ArrayList(); 11 | if (digits == null) { 12 | return ret; 13 | } 14 | 15 | dfs(digits, new StringBuilder(), ret, 0); 16 | return ret; 17 | } 18 | 19 | public void dfs(String digits, StringBuilder sb, List ret, int index) { 20 | int len = digits.length(); 21 | if (index == len) { 22 | ret.add(sb.toString()); 23 | return; 24 | } 25 | 26 | // get the possiable selections. 27 | String s = map[digits.charAt(index) - '0']; 28 | for (int i = 0; i < s.length(); i++) { 29 | sb.append(s.charAt(i)); 30 | dfs(digits, sb, ret, index + 1); 31 | sb.deleteCharAt(sb.length() - 1); 32 | } 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /dfs/Permute.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dfs; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Permute { 7 | public List> permute(int[] num) { 8 | List> ret = new ArrayList>(); 9 | if (num == null || num.length == 0) { 10 | return ret; 11 | } 12 | 13 | dfs(num, new ArrayList(), ret); 14 | return ret; 15 | } 16 | 17 | public void dfs(int[] num, List path, List> ret) { 18 | int len = num.length; 19 | if (path.size() == len) { 20 | ret.add(new ArrayList(path)); 21 | return; 22 | } 23 | 24 | for (int i = 0; i < len; i++) { 25 | if (path.contains(num[i])) { 26 | continue; 27 | } 28 | 29 | path.add(num[i]); 30 | dfs(num, path, ret); 31 | path.remove(path.size() - 1); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /dfs/SubsetsWithDup.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dfs; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class SubsetsWithDup { 8 | public List> subsetsWithDup(int[] num) { 9 | List> ret = new ArrayList>(); 10 | 11 | if (num == null) { 12 | return ret; 13 | } 14 | 15 | Arrays.sort(num); 16 | 17 | dfs(num, new ArrayList(), ret, 0); 18 | 19 | return ret; 20 | } 21 | 22 | public void dfs(int[] num, List path, List> ret, int index) { 23 | ret.add(new ArrayList(path)); 24 | 25 | for (int i = index; i < num.length; i++) { 26 | // skip the duplicate. 27 | if (i > index && num[i] == num[i - 1]) { 28 | continue; 29 | } 30 | 31 | path.add(num[i]); 32 | // 注意:这里是i + 1不是index + 1!!! 33 | dfs(num, path, ret, i + 1); 34 | path.remove(path.size() - 1); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /dfs/TotalNQueens.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dfs; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class TotalNQueens { 6 | public int totalNQueens(int n) { 7 | if (n == 0) { 8 | return 0; 9 | } 10 | 11 | ArrayList cols = new ArrayList(); 12 | 13 | return dfs(n, cols, 0); 14 | } 15 | 16 | public int dfs(int n, ArrayList cols, int row) { 17 | // 如果row 超过范围,返回1 18 | // base case 已经完成任务,应该是1种解法 因为前面已经固定,现在也不能再放了 19 | if (row == n) { 20 | return 1; 21 | } 22 | 23 | int sum = 0; 24 | 25 | // 在当前行,尝试放置棋子 26 | for (int i = 0; i < n; i++) { 27 | // 不能放的位置 跳过 28 | if (!isValid(cols, i)) { 29 | continue; 30 | } 31 | 32 | cols.add(i); 33 | sum += dfs(n, cols, row + 1); 34 | cols.remove(cols.size() - 1); 35 | } 36 | 37 | return sum; 38 | } 39 | 40 | public boolean isValid(ArrayList cols, int col) { 41 | for (int i = 0; i < cols.size(); i++) { 42 | if (col == cols.get(i)) { 43 | // same column. 44 | return false; 45 | } 46 | 47 | // diagonal. From the left up to the right down. 48 | if (cols.size() - i == Math.abs(col - cols.get(i))) { 49 | return false; 50 | } 51 | } 52 | 53 | return true; 54 | } 55 | } -------------------------------------------------------------------------------- /dfs/totalNQueens_1218_2014.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dfs; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class TotalNQueens_1218_2014 { 6 | public int totalNQueens(int n) { 7 | if (n == 0) { 8 | return 0; 9 | } 10 | 11 | // Bug 1: forget to modify the parameters of the function. 12 | return dfs(n, 0, new ArrayList()); 13 | } 14 | 15 | public int dfs(int n, int row, ArrayList path) { 16 | if (row == n) { 17 | // The base case: 当最后一行,皇后只有1种放法(就是不放) 18 | return 1; 19 | } 20 | 21 | int num = 0; 22 | 23 | // The queen can select any of the slot. 24 | for (int i = 0; i < n; i++) { 25 | if (!isValid(path, i)) { 26 | continue; 27 | } 28 | path.add(i); 29 | 30 | // All the solutions is all the possibilities are add up. 31 | num += dfs(n, row + 1, path); 32 | path.remove(path.size() - 1); 33 | } 34 | 35 | return num; 36 | } 37 | 38 | public boolean isValid(ArrayList path, int col) { 39 | int size = path.size(); 40 | for (int i = 0; i < size; i++) { 41 | // The same column with any of the current queen. 42 | if (col == path.get(i)) { 43 | return false; 44 | } 45 | 46 | // diagonally lines. 47 | // Bug 2: forget to add a ')' 48 | if (size - i == Math.abs(col - path.get(i))) { 49 | return false; 50 | } 51 | } 52 | 53 | return true; 54 | } 55 | } -------------------------------------------------------------------------------- /divide2/Pow.java: -------------------------------------------------------------------------------- 1 | package Algorithms.divide2; 2 | 3 | public class Pow { 4 | public static void main(String[] strs) { 5 | System.out.println(pow(-3, -2147483648)); 6 | 7 | } 8 | 9 | public static double pow(double x, int n) { 10 | if (x == 0) { 11 | return 0; 12 | } 13 | 14 | if (x == 1 || n == 0) { 15 | return 1; 16 | } 17 | 18 | // Because when we deal with -2147483648, we can't get right -n 19 | // cause -n == n when it is -2147483648. 20 | if (n < 0) { 21 | double ret1 = x * pow(x, -(1 + n)); 22 | return 1/(double)ret1; 23 | } 24 | 25 | int m = n%2; 26 | 27 | // count 28 | double ret = pow(x, n/2); 29 | ret *= ret; 30 | if (m == 1) { 31 | ret *= x; 32 | } 33 | 34 | return ret; 35 | } 36 | } -------------------------------------------------------------------------------- /divide2/Pow_1219_2014.java: -------------------------------------------------------------------------------- 1 | package Algorithms.divide2; 2 | 3 | public class Pow_1219_2014 { 4 | public double pow(double x, int n) { 5 | if (x == 0) { 6 | return 0; 7 | } 8 | 9 | // base case: when n = 0, the result is 1; 10 | if (n == 0) { 11 | return 1; 12 | } 13 | 14 | /* 15 | 递归的主体部分 16 | */ 17 | 18 | // X^(-n) = X^(n + 1) * X 19 | // X^n = 1/(x^(-n)) 20 | if (n < 0) { 21 | double ret = x * pow(x, -(n + 1)); 22 | return (double)1/ret; 23 | } 24 | 25 | // 将求pow对半分。再将结果相乘 26 | double ret = pow(x, n / 2); 27 | ret = ret * ret; 28 | 29 | //如果有余数,再乘以x本身。 30 | if (n % 2 != 0) { 31 | ret = ret * x; 32 | } 33 | 34 | return ret; 35 | } 36 | } -------------------------------------------------------------------------------- /divide2/SearchInsert.java: -------------------------------------------------------------------------------- 1 | package Algorithms.divide2; 2 | 3 | public class SearchInsert { 4 | public int searchInsert1(int[] A, int target) { 5 | if (A == null || A.length == 0) { 6 | return 0; 7 | } 8 | 9 | int left = 0; 10 | int right = A.length - 1; 11 | 12 | while (left < right - 1) { 13 | int mid = left + (right - left) / 2; 14 | int num = A[mid]; 15 | 16 | if (num == target) { 17 | return mid; 18 | } else if (num < target) { 19 | left = mid + 1; 20 | } else { 21 | right = mid - 1; 22 | } 23 | } 24 | 25 | // bug 1: should use <= 26 | if (target <= A[left]) { 27 | return left; 28 | // bug 2: should use <= . consider that may the result exit in left or right. 29 | } else if (target <= A[right]) { 30 | return right; 31 | } 32 | 33 | return right + 1; 34 | } 35 | 36 | // sol 2: 37 | public int searchInsert(int[] A, int target) { 38 | if (A == null || A.length == 0) { 39 | return 0; 40 | } 41 | 42 | int left = 0; 43 | int right = A.length - 1; 44 | 45 | while (left <= right) { 46 | int mid = left + (right - left) / 2; 47 | int num = A[mid]; 48 | 49 | if (num == target) { 50 | return mid; 51 | } else if (num < target) { 52 | left = mid + 1; 53 | } else { 54 | right = mid - 1; 55 | } 56 | } 57 | 58 | return left; 59 | } 60 | } -------------------------------------------------------------------------------- /divide2/SearchMatrix.java: -------------------------------------------------------------------------------- 1 | package Algorithms.divide2; 2 | 3 | public class SearchMatrix { 4 | public boolean searchMatrix(int[][] matrix, int target) { 5 | if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { 6 | return false; 7 | } 8 | 9 | int rows = matrix.length; 10 | int cols = matrix[0].length; 11 | 12 | int num = rows * cols; 13 | 14 | int left = 0; 15 | int right = num - 1; 16 | 17 | while (left <= right) { 18 | int mid = left + (right - left) / 2; 19 | 20 | int row = mid / cols; 21 | int col = mid % cols; 22 | 23 | int n = matrix[row][col]; 24 | 25 | if (n == target) { 26 | return true; 27 | } else if (n < target) { 28 | left = mid + 1; 29 | } else { 30 | right = mid - 1; 31 | } 32 | } 33 | 34 | return false; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /divide2/SearchRange.java: -------------------------------------------------------------------------------- 1 | package Algorithms.divide2; 2 | 3 | public class SearchRange { 4 | public int[] searchRange(int[] A, int target) { 5 | int[] ret = {-1, -1}; 6 | if (A == null || A.length == 0) { 7 | return ret; 8 | } 9 | 10 | int l = 0; 11 | int r = A.length - 1; 12 | 13 | // Find the left bound. 14 | while (l < r - 1) { 15 | int mid = l + (r - l) / 2; 16 | if (A[mid] == target) { 17 | r = mid; 18 | } else if (A[mid] > target) { 19 | r = mid; 20 | } else { 21 | l = mid; 22 | } 23 | } 24 | 25 | if (A[l] == target) { 26 | ret[0] = l; 27 | } else if (A[r] == target) { 28 | ret[0] = r; 29 | } else { 30 | return ret; 31 | } 32 | 33 | l = 0; 34 | r = A.length - 1; 35 | // Find the right bound. 36 | while (l < r - 1) { 37 | int mid = l + (r - l) / 2; 38 | if (A[mid] == target) { 39 | l = mid; 40 | } else if (A[mid] > target) { 41 | r = mid; 42 | } else { 43 | l = mid; 44 | } 45 | } 46 | 47 | if (A[r] == target) { 48 | ret[1] = r; 49 | } else { 50 | ret[1] = l; 51 | } 52 | 53 | return ret; 54 | } 55 | } -------------------------------------------------------------------------------- /divide2/Sqrt.java: -------------------------------------------------------------------------------- 1 | package Algorithms.divide2; 2 | 3 | public class Sqrt { 4 | public static void main(String[] strs) { 5 | //System.out.println(sqrt(2)); 6 | 7 | int[] A = {1, 2, 3, 4}; 8 | System.out.println(find(A, 2)); 9 | } 10 | 11 | // return the index of the target, if not find, return -1; 12 | public static int find (int[] input, int target) { 13 | if (input == null) { 14 | return -1; 15 | } 16 | 17 | int left = 0; 18 | int right = input.length - 1; 19 | 20 | while (left < right) { 21 | int mid = left + (right - left) / 2; 22 | if (input[mid] == target) { 23 | return mid; 24 | } else if (input[mid] < target) { 25 | left = mid + 1; 26 | } else { 27 | right = mid - 1; 28 | } 29 | } 30 | 31 | return -1; 32 | } 33 | 34 | public static int sqrt(int x) { 35 | if (x == 1 || x == 0) { 36 | return x; 37 | } 38 | 39 | int left = 1; 40 | int right = x; 41 | 42 | while (left < right - 1) { 43 | int mid = left + (right - left) / 2; 44 | int quo = x / mid; 45 | 46 | if (quo == mid) { 47 | return quo; 48 | // mid is too big 49 | } else if (quo < mid) { 50 | right = mid; 51 | } else { 52 | left = mid; 53 | } 54 | System.out.println(left + " " + right); 55 | } 56 | 57 | 58 | return left; 59 | } 60 | } 61 | 62 | //We can use Car to implements the interfaces: 63 | //Gearbox, Engine. 64 | // 65 | //public class Car implements Geabox, Engine { 66 | // // the 67 | //} 68 | // 69 | //public interface Geabox { 70 | //} 71 | // 72 | //public interface Engine { 73 | //}【】22;。3 -------------------------------------------------------------------------------- /dp/Candy.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | public class Candy { 4 | public int candy(int[] ratings) { 5 | if (ratings == null || ratings.length == 0) { 6 | return 0; 7 | } 8 | 9 | 10 | int len = ratings.length; 11 | int[] num = new int[len]; 12 | 13 | // go from left to right; 14 | for (int i = 0; i < len; i++) { 15 | if (i > 0 && ratings[i] > ratings[i - 1]) { 16 | num[i] = num[i - 1] + 1; 17 | } else { 18 | num[i] = 1; 19 | } 20 | } 21 | 22 | // go from right to left; 23 | int sum = 0; 24 | for (int i = len - 1; i >= 0; i--) { 25 | if (i < len - 1 && ratings[i] > ratings[i + 1]) { 26 | num[i] = Math.max(num[i], num[i + 1] + 1); 27 | } 28 | sum += num[i]; 29 | } 30 | 31 | return sum; 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /dp/GetRow.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class GetRow { 7 | public List getRow1(int rowIndex) { 8 | List pre = new ArrayList(); 9 | List cur = new ArrayList(); 10 | 11 | if (rowIndex < 0) { 12 | return cur; 13 | } 14 | 15 | // 娉ㄦ剰杩欓噷鐨剅owIndex璺熶笂涓�鐨勬剰涔変笉涓�牱锛佽繖涓槸绱㈠紩锛宱rz... 16 | // 鎵�互鎴戜滑瑕佺敤<= 17 | for (int i = 0; i <= rowIndex; i++) { 18 | // 绗琲琛屾湁i + 1涓厓绱� 19 | cur = new ArrayList(); 20 | for (int j = 0; j < i + 1; j++) { 21 | if (j == 0 || j == i) { 22 | cur.add(1); 23 | } else { 24 | cur.add(pre.get(j) + pre.get(j - 1)); 25 | } 26 | } 27 | pre = cur; 28 | } 29 | 30 | return cur; 31 | } 32 | 33 | // SOLUTION 2: DO IT just inplace 34 | public List getRow(int rowIndex) { 35 | List ret = new ArrayList(); 36 | 37 | for (int i = 0; i <= rowIndex; i++) { 38 | for (int j = i; j >= 0; j--) { 39 | if (j == i) { 40 | ret.add(1); 41 | } else if (j != 0) { 42 | // ERROR: use add instead of set 43 | //ret.add(ret.get(j) + ret.get(j - 1)); 44 | ret.set(j, ret.get(j) + ret.get(j - 1)); 45 | } 46 | } 47 | } 48 | 49 | return ret; 50 | } 51 | } -------------------------------------------------------------------------------- /dp/LongestPalindrome.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | public class LongestPalindrome { 4 | public static void main(String[] args) { 5 | String s = "9cadfasdfsadfabaabaed"; 6 | System.out.println(longestPalindrome(s)); 7 | 8 | System.out.println(Character.toLowerCase('9')); 9 | 10 | } 11 | 12 | // Solution 1: Brute Force 13 | public static String longestPalindrome(String s) { 14 | if (s == null) { 15 | return null; 16 | } 17 | 18 | int len = s.length(); 19 | 20 | int max = 0; 21 | int begin = 0; 22 | int end = 0; 23 | for (int i = 0; i < len; i++) { 24 | for (int j = i; j < len; j++) { 25 | if (dfs(s, i, j)) { 26 | if (j - i + 1 > max) { 27 | max = j - i + 1; 28 | begin = i; 29 | end = j; 30 | } 31 | } 32 | } 33 | } 34 | 35 | return s.substring(begin, end + 1); 36 | } 37 | 38 | public static boolean dfs(String s, int i, int j) { 39 | if (i >= j) { 40 | return true; 41 | } 42 | 43 | if (s.charAt(i) == s.charAt(j)) { 44 | return dfs(s, i + 1, j - 1); 45 | } 46 | 47 | return false; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /dp/MaxProfit.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | public class MaxProfit { 4 | public int maxProfit(int[] prices) { 5 | if (prices == null) { 6 | return 0; 7 | } 8 | 9 | int len = prices.length; 10 | int maxProfit = 0; 11 | int minPrice = Integer.MAX_VALUE; 12 | for (int i = 0; i < len; i++) { 13 | minPrice = Math.min(minPrice, prices[i]); 14 | maxProfit = Math.max(maxProfit, prices[i] - minPrice); 15 | } 16 | 17 | return maxProfit; 18 | } 19 | 20 | public int maxProfit2(int[] prices) { 21 | if (prices == null) { 22 | return 0; 23 | } 24 | 25 | int maxProfit = 0; 26 | int minValue = Integer.MAX_VALUE; 27 | 28 | for (int i: prices) { 29 | minValue = Math.min(minValue, i); 30 | maxProfit = Math.max(maxProfit, i - minValue); 31 | } 32 | 33 | return maxProfit; 34 | } 35 | } -------------------------------------------------------------------------------- /dp/MaxProfit2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | public class MaxProfit2 { 4 | public int maxProfit(int[] prices) { 5 | if (prices == null) { 6 | return 0; 7 | } 8 | 9 | int profit = 0; 10 | for (int i = 1; i < prices.length; i++) { 11 | if (prices[i] - prices[i - 1] > 0) { 12 | profit += prices[i] - prices[i - 1]; 13 | } 14 | } 15 | 16 | return profit; 17 | } 18 | 19 | /* 20 | * 2015.1.3 21 | * */ 22 | public int maxProfit2(int[] prices) { 23 | if (prices == null) { 24 | return 0; 25 | } 26 | 27 | int maxProfit = 0; 28 | 29 | int len = prices.length; 30 | for (int i = 1; i < len; i++) { 31 | int dif = prices[i] - prices[i - 1]; 32 | 33 | if (dif > 0) { 34 | maxProfit += dif; 35 | } 36 | } 37 | 38 | return maxProfit; 39 | } 40 | } -------------------------------------------------------------------------------- /dp/MinCut.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | public class MinCut { 4 | public int minCut(String s) { 5 | if (s == null || s.length() == 0) { 6 | return 0; 7 | } 8 | 9 | int len = s.length(); 10 | 11 | // D[i] 的定义: 第i个字符到len - 1个字符的最小切割数。 12 | int[] D = new int[len]; 13 | 14 | boolean[][] isPalid = new boolean[len][len]; 15 | 16 | for (int i = len - 1; i >= 0; i--) { 17 | // the worst case is divide the word one by one. 18 | D[i] = len - 1 -i; 19 | for (int j = i; j <= len - 1; j++) { 20 | // init it to be false; 21 | isPalid[i][j] = false; 22 | 23 | if (s.charAt(i) == s.charAt(j) && (j - i <= 1 || isPalid[i + 1][j - 1])) { 24 | isPalid[i][j] = true; 25 | if (j == len - 1) { 26 | // 这里就是特殊处理的地方了。当整个字符串都是回文的时候,因为没有D[Len],所以这里直接 27 | // 将D[i]置为0,意思就是这时不需要任何的划分。 28 | D[i] = 0; 29 | } else { 30 | // 如果前半部分是回文,那么我们可以分解为第一个回文 + 后半部分的最小分割数 31 | D[i] = Math.min(D[i], D[j + 1] + 1); 32 | } 33 | } 34 | } 35 | } 36 | 37 | return D[0]; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dp/MinCut_1206.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | public class MinCut_1206 { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /dp/MinimumTotal.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | import java.util.List; 4 | 5 | public class MinimumTotal { 6 | /* 7 | REC, SOL 1: 8 | */ 9 | public int minimumTotal1(List> triangle) { 10 | if (triangle == null || triangle.size() == 0) { 11 | return 0; 12 | } 13 | 14 | int rows = triangle.size(); 15 | int[][] mem = new int[rows][rows]; 16 | for (int i = 0; i < rows; i++) { 17 | for (int j = 0; j < rows; j++) { 18 | mem[i][j] = Integer.MAX_VALUE; 19 | } 20 | } 21 | 22 | return dfs(triangle, 0, 0, mem); 23 | } 24 | 25 | public int dfs(List> triangle, int row, int col, int[][] mem) { 26 | if (mem[row][col] != Integer.MAX_VALUE) { 27 | return mem[row][col]; 28 | } 29 | 30 | if (row == triangle.size() - 1) { 31 | mem[row][col] = triangle.get(row).get(col); 32 | } else { 33 | int left = dfs(triangle, row + 1, col, mem); 34 | int right = dfs(triangle, row + 1, col + 1, mem); 35 | mem[row][col] = triangle.get(row).get(col) + Math.min(left, right); 36 | } 37 | 38 | return mem[row][col]; 39 | } 40 | 41 | /* 42 | DP, SOL 2: 43 | */ 44 | public int minimumTotal(List> triangle) { 45 | if (triangle == null || triangle.size() == 0) { 46 | return 0; 47 | } 48 | 49 | int rows = triangle.size(); 50 | int[] D = new int[rows]; 51 | 52 | for (int i = rows - 1; i >= 0; i--) { 53 | // 注意:边界条件是 j <= i 54 | for (int j = 0; j <= i; j++) { 55 | if (i == rows - 1) { 56 | D[j] = triangle.get(i).get(j); 57 | } else { 58 | D[j] = triangle.get(i).get(j) + Math.min(D[j], D[j + 1]); 59 | } 60 | } 61 | } 62 | 63 | return D[0]; 64 | } 65 | } -------------------------------------------------------------------------------- /dp/NQueens2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class NQueens2 { 6 | public static void main(String[] args) { 7 | NQueens2 nq = new NQueens2(); 8 | nq.totalNQueens(1); 9 | } 10 | 11 | public int totalNQueens(int n) { 12 | ArrayList cols = new ArrayList(); 13 | return totalNQueensHelp(n, cols, 0); 14 | } 15 | 16 | public boolean isValid(ArrayList cols, int col) { 17 | for (int i = 0; i < cols.size(); i++) { 18 | if (col == cols.get(i) || (cols.size() - i == Math.abs(col - cols.get(i)))) { 19 | return false; 20 | } 21 | } 22 | 23 | return true; 24 | } 25 | 26 | public int totalNQueensHelp(int n, ArrayList cols, int total) { 27 | if (cols.size() == n) { 28 | // get a new solution. 29 | return total + 1; 30 | } 31 | 32 | int newTotal = total; 33 | 34 | for (int i = 0; i < cols.size(); i ++) { 35 | if (!isValid(cols, i)) { // this is not a solution. 36 | continue; 37 | } 38 | 39 | cols.add(i); 40 | newTotal = totalNQueensHelp(n, cols, newTotal); 41 | cols.remove(cols.size() - 1); 42 | } 43 | 44 | return newTotal; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /dp/NumDecodings.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | public class NumDecodings { 4 | public int numDecodings(String s) { 5 | if (s == null || s.length() == 0) { 6 | return 0; 7 | } 8 | 9 | int len = s.length(); 10 | 11 | // D[i] 表示含有i个字符的子串的DECODE WAYS. 12 | int[] D = new int[len + 1]; 13 | 14 | D[0] = 1; 15 | 16 | for (int i = 1; i <= len; i++) { 17 | D[i] = 0; 18 | 19 | // 现在正在考察的字符的索引. 20 | int index = i - 1; 21 | // 最后一个字符独立解码 22 | if (isValidSingle(s.charAt(index))) { 23 | D[i] += D[i - 1]; 24 | } 25 | 26 | // 最后一个字符与上一个字符一起解码 27 | if (i > 1 && isValidTwo(s.substring(index - 1, index + 1))) { 28 | D[i] += D[i - 2]; 29 | } 30 | } 31 | 32 | return D[len]; 33 | } 34 | 35 | public boolean isValidSingle(char c) { 36 | if (c >= '1' && c <= '9') { 37 | return true; 38 | } 39 | 40 | return false; 41 | } 42 | 43 | public boolean isValidTwo(String s) { 44 | int num = Integer.parseInt(s); 45 | 46 | return (num >= 10 && num <= 26); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /dp/UniquePathsWithObstacles.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | public class UniquePathsWithObstacles { 4 | public int uniquePathsWithObstacles(int[][] obstacleGrid) { 5 | if (obstacleGrid == null || obstacleGrid.length == 0 6 | || obstacleGrid[0].length == 0) { 7 | return 0; 8 | } 9 | 10 | int rows = obstacleGrid.length; 11 | int cols = obstacleGrid[0].length; 12 | 13 | int[][] D = new int[rows][cols]; 14 | 15 | for (int i = 0; i < rows; i++) { 16 | for (int j = 0; j < cols; j++) { 17 | if (obstacleGrid[i][j] == 1) { 18 | D[i][j] = 0; 19 | continue; 20 | } 21 | 22 | if (i == 0 && j == 0) { 23 | D[i][j] = 1; 24 | } else if (i == 0) { 25 | D[i][j] = D[i][j - 1]; 26 | } else if (j == 0) { 27 | D[i][j] = D[i - 1][j]; 28 | } else { 29 | D[i][j] = D[i - 1][j] + D[i][j - 1]; 30 | } 31 | } 32 | } 33 | 34 | return D[rows - 1][cols - 1]; 35 | } 36 | } -------------------------------------------------------------------------------- /dp/WordBreak.java: -------------------------------------------------------------------------------- 1 | package Algorithms.dp; 2 | 3 | import java.util.Set; 4 | 5 | public class WordBreak { 6 | public boolean wordBreak(String s, Set dict) { 7 | if (s == null) { 8 | return false; 9 | } 10 | 11 | int len = s.length(); 12 | if (len == 0) { 13 | return true; 14 | } 15 | 16 | boolean[] D = new boolean[len + 1]; 17 | 18 | // initiate the DP. 注意,这里设置为true是不得已,因为当我们划分字串为左边为0,右边为n的时候, 19 | // 而右边的n是一个字典string,那么左边必然要设置为true,才能使结果为true。所以空字符串我们需要 20 | // 认为true 21 | D[0] = true; 22 | 23 | // D[i] 表示i长度的字符串能否被word break. 24 | for (int i = 1; i <= len; i++) { 25 | // 把子串划分为2部分,分别讨论, j 表示左边的字符串的长度 26 | // 成立的条件是:左边可以break, 而右边是一个字典单词 27 | D[i] = false; 28 | for (int j = 0; j < i; j++) { 29 | if (D[j] && dict.contains(s.substring(j, i))) { 30 | // 只要找到任意一个符合条件,我们就可以BREAK; 表示我们检查的 31 | // 这一个子串符合题意 32 | D[i] = true; 33 | break; 34 | } 35 | } 36 | } 37 | 38 | return D[len]; 39 | } 40 | } -------------------------------------------------------------------------------- /greedy/CanCompleteCircuit.java: -------------------------------------------------------------------------------- 1 | package Algorithms.greedy; 2 | 3 | public class CanCompleteCircuit { 4 | public int canCompleteCircuit(int[] gas, int[] cost) { 5 | if (gas == null || cost == null || gas.length == 0 || cost.length == 0) { 6 | // Bug 0: should not return false; 7 | return -1; 8 | } 9 | 10 | int total = 0; 11 | int sum = 0; 12 | 13 | int startIndex = 0; 14 | 15 | int len = gas.length; 16 | for (int i = 0; i < len; i++) { 17 | int dif = gas[i] - cost[i]; 18 | sum += dif; 19 | 20 | if (sum < 0) { 21 | // Means that from 0 to this gas station, none of them can be the solution. 22 | startIndex = i + 1; // Begin from the next station. 23 | sum = 0; // reset the sum. 24 | } 25 | 26 | total += dif; 27 | } 28 | 29 | if (total < 0) { 30 | return -1; 31 | } 32 | 33 | return startIndex; 34 | } 35 | } -------------------------------------------------------------------------------- /hash/LRUCache2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.hash; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | public class LRUCache2 { 7 | public static void main(String[] strs) { 8 | LRUCache2 lrc2 = new LRUCache2(2); 9 | lrc2.set(1,3); 10 | lrc2.set(2,2); 11 | lrc2.set(1,4); 12 | lrc2.set(4,2); 13 | 14 | System.out.println(lrc2.get(1)); 15 | } 16 | 17 | LinkedHashMap map; 18 | int capacity; 19 | 20 | public LRUCache2(final int capacity) { 21 | // create a map. 22 | map = new LinkedHashMap(capacity) { 23 | /** 24 | * 25 | */ 26 | private static final long serialVersionUID = 1L; 27 | 28 | protected boolean removeEldestEntry(Map.Entry eldest) { 29 | return size() > capacity; 30 | } 31 | }; 32 | this.capacity = capacity; 33 | } 34 | 35 | public int get(int key) { 36 | Integer ret = map.get(key); 37 | if (ret == null) { 38 | return -1; 39 | } else { 40 | map.remove(key); 41 | map.put(key, ret); 42 | } 43 | 44 | return ret; 45 | } 46 | 47 | public void set(int key, int value) { 48 | map.remove(key); 49 | map.put(key, value); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /hash/MaxPoints.java: -------------------------------------------------------------------------------- 1 | package Algorithms.hash; 2 | 3 | import java.awt.Point; 4 | import java.util.HashMap; 5 | 6 | public class MaxPoints { 7 | public int maxPoints(Point[] points) { 8 | int max = 0; 9 | 10 | if (points == null) { 11 | return 0; 12 | } 13 | 14 | int len = points.length; 15 | 16 | for (int i = 0; i < len; i++) { 17 | // Create a map to recode all the numbers of elements of every K. 18 | HashMap map = new HashMap(); 19 | 20 | // ItSelf. 21 | int dup = 0; 22 | 23 | for (int j = i; j < len; j++) { 24 | // the same point. 25 | if (points[i].x == points[j].x && points[i].y == points[j].y) { 26 | dup++; 27 | continue; 28 | } 29 | 30 | double k = Double.MAX_VALUE; 31 | if (points[i].x != points[j].x) { 32 | k = 0 + (double)(points[i].y - points[j].y)/(double)(points[i].x - points[j].x); 33 | } 34 | 35 | if (map.containsKey(k)) { 36 | map.put(k, map.get(k) + 1); 37 | } else { 38 | map.put(k, 1); 39 | } 40 | } 41 | 42 | max = Math.max(max, dup); 43 | for (int n: map.values()) { 44 | max = Math.max(max, n + dup); 45 | } 46 | } 47 | 48 | return max; 49 | } 50 | } -------------------------------------------------------------------------------- /lintcode/array/FindFirstBadVersion.java: -------------------------------------------------------------------------------- 1 | package Algorithms.lintcode.array; 2 | 3 | /** 4 | * public class VersionControl { 5 | * public static boolean isBadVersion(int k); 6 | * } 7 | * you can use VersionControl.isBadVersion(k) to judge wether 8 | * the kth code version is bad or not. 9 | */ 10 | class Solution { 11 | /** 12 | * @param n: An integers. 13 | * @return: An integer which is the first bad version. 14 | */ 15 | public int findFirstBadVersion(int n) { 16 | // write your code here 17 | if (n == 1) { 18 | return 1; 19 | } 20 | 21 | int left = 1; 22 | int right = n; 23 | 24 | while (left + 1 < right) { 25 | int mid = left + (right - left) / 2; 26 | if (VersionControl.isBadVersion(mid)) { 27 | right = mid; 28 | } else { 29 | left = mid; 30 | } 31 | } 32 | 33 | if (VersionControl.isBadVersion(left)) { 34 | return left; 35 | } 36 | 37 | return right; 38 | } 39 | 40 | // solution 2. 41 | public int findFirstBadVersion2(int n) { 42 | // write your code here 43 | if (n == 1) { 44 | return 1; 45 | } 46 | 47 | int left = 1; 48 | int right = n; 49 | 50 | while (left < right) { 51 | int mid = left + (right - left) / 2; 52 | if (VersionControl.isBadVersion(mid)) { 53 | right = mid; 54 | } else { 55 | left = mid + 1; 56 | } 57 | } 58 | 59 | return right; 60 | } 61 | } -------------------------------------------------------------------------------- /lintcode/array/MinSubArray.java: -------------------------------------------------------------------------------- 1 | package Algorithms.lintcode.array; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class MinSubArray { 6 | /** 7 | * @param nums: a list of integers 8 | * @return: A integer indicate the sum of minimum subarray 9 | */ 10 | public int minSubArray(ArrayList nums) { 11 | // write your code 12 | 13 | int len = nums.size(); 14 | 15 | int max = Integer.MIN_VALUE; 16 | int sum = 0; 17 | for (int i = 0; i < len; i++) { 18 | if (sum < 0) { 19 | sum = -nums.get(i); 20 | } else { 21 | sum += -nums.get(i); 22 | } 23 | 24 | max = Math.max(max, sum); 25 | } 26 | 27 | return -max; 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /lintcode/array/SubarraySum.java: -------------------------------------------------------------------------------- 1 | package Algorithms.lintcode.array; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | 6 | 7 | public class SubarraySum { 8 | /** 9 | * @param nums: A list of integers 10 | * @return: A list of integers includes the index of the first number 11 | * and the index of the last number 12 | */ 13 | public ArrayList subarraySum(int[] nums) { 14 | // write your code here 15 | int len = nums.length; 16 | 17 | ArrayList ret = new ArrayList(); 18 | 19 | HashMap map = new HashMap(); 20 | 21 | // We set the index -1 sum to be 0 to let us more convient to count. 22 | map.put(0, -1); 23 | 24 | int sum = 0; 25 | for (int i = 0; i < len; i++) { 26 | sum += nums[i]; 27 | 28 | if (map.containsKey(sum)) { 29 | // For example: 30 | // -3 1 2 -3 4 31 | // SUM: 0 -3 -2 0 -3 1 32 | // then we got the solution is : 0 - 2 33 | ret.add(map.get(sum) + 1); 34 | ret.add(i); 35 | return ret; 36 | } 37 | 38 | // Store the key:value of sum:index. 39 | map.put(sum, i); 40 | } 41 | 42 | return ret; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lintcode/array/VersionControl.java: -------------------------------------------------------------------------------- 1 | package Algorithms.lintcode.array; 2 | 3 | public class VersionControl { 4 | 5 | public static boolean isBadVersion(int mid) { 6 | // TODO Auto-generated method stub 7 | return false; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /lintcode/dp/LongestCommonSubsequence.java: -------------------------------------------------------------------------------- 1 | package Algorithms.lintcode.dp; 2 | 3 | public class LongestCommonSubsequence { 4 | /** 5 | * @param A, B: Two strings. 6 | * @return: The length of longest common subsequence of A and B. 7 | */ 8 | public int longestCommonSubsequence(String A, String B) { 9 | // write your code here 10 | if (A == null || B == null) { 11 | return 0; 12 | } 13 | 14 | int lenA = A.length(); 15 | int lenB = B.length(); 16 | int[][] D = new int[lenA + 1][lenB + 1]; 17 | 18 | for (int i = 0; i <= lenA; i++) { 19 | for (int j = 0; j <= lenB; j++) { 20 | if (i == 0 || j == 0) { 21 | D[i][j] = 0; 22 | } else { 23 | if (A.charAt(i - 1) == B.charAt(j - 1)) { 24 | D[i][j] = D[i - 1][j - 1] + 1; 25 | } else { 26 | D[i][j] = Math.max(D[i - 1][j], D[i][j - 1]); 27 | } 28 | } 29 | } 30 | } 31 | 32 | return D[lenA][lenB]; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /lintcode/dp/LongestCommonSubstring.java: -------------------------------------------------------------------------------- 1 | package Algorithms.lintcode.dp; 2 | 3 | public class LongestCommonSubstring { 4 | /** 5 | * @param A, B: Two string. 6 | * @return: the length of the longest common substring. 7 | */ 8 | public int longestCommonSubstring(String A, String B) { 9 | // write your code here 10 | if (A == null || B == null) { 11 | return 0; 12 | } 13 | 14 | int lenA = A.length(); 15 | int lenB = B.length(); 16 | 17 | // bug 1: use error init. 18 | int[][] D = new int[lenA + 1][lenB + 1]; 19 | 20 | int max = 0; 21 | 22 | // BUG 2: should use <= instead of < 23 | for (int i = 0; i <= lenA; i++) { 24 | for (int j = 0; j <= lenB; j++) { 25 | if (i == 0 || j == 0) { 26 | D[i][j] = 0; 27 | } else { 28 | if (A.charAt(i - 1) == B.charAt(j - 1)) { 29 | D[i][j] = D[i - 1][j - 1] + 1; 30 | } else { 31 | D[i][j] = 0; 32 | } 33 | } 34 | 35 | max = Math.max(max, D[i][j]); 36 | } 37 | } 38 | 39 | return max; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lintcode/math/MajorityNumber.java: -------------------------------------------------------------------------------- 1 | package Algorithms.lintcode.math; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class MajorityNumber { 6 | /** 7 | * @param nums: a list of integers 8 | * @return: find a majority number 9 | */ 10 | public int majorityNumber(ArrayList nums) { 11 | // write your code 12 | if (nums == null || nums.size() == 0) { 13 | // No majority number. 14 | return -1; 15 | } 16 | 17 | int candidate = nums.get(0); 18 | 19 | // The phase 1: Voting. 20 | int cnt = 1; 21 | for (int i = 1; i < nums.size(); i++) { 22 | if (nums.get(i) == candidate) { 23 | cnt++; 24 | } else { 25 | cnt--; 26 | if (cnt == 0) { 27 | candidate = nums.get(i); 28 | cnt = 1; 29 | } 30 | } 31 | } 32 | 33 | // The phase 2: Examing. 34 | cnt = 0; 35 | for (int i = 0; i < nums.size(); i++) { 36 | if (nums.get(i) == candidate) { 37 | cnt++; 38 | } 39 | } 40 | 41 | // No majory number. 42 | if (cnt <= nums.size() / 2) { 43 | return -1; 44 | } 45 | 46 | return candidate; 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /lintcode/math/MajorityNumber2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.lintcode.math; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class MajorityNumber2 { 6 | /** 7 | * @param nums: A list of integers 8 | * @return: The majority number that occurs more than 1/3 9 | */ 10 | public int majorityNumber(ArrayList nums) { 11 | // write your code 12 | // When there are only 1 or 2 elements in the array, 13 | // there is no solution. 14 | if (nums == null || nums.size() <= 2) { 15 | return -1; 16 | } 17 | 18 | int n1 = 0; 19 | int n2 = 0; 20 | 21 | int cnt1 = 0; 22 | int cnt2 = 0; 23 | 24 | int size = nums.size(); 25 | for (int i = 0; i < size; i++) { 26 | int num = nums.get(i); 27 | if (cnt1 != 0 && num == n1) { 28 | cnt1++; 29 | } else if (cnt2 != 0 && num == n2) { 30 | cnt2++; 31 | } else if (cnt1 == 0) { 32 | cnt1 = 1; 33 | n1 = num; 34 | } else if (cnt2 == 0) { 35 | cnt2 = 1; 36 | n2 = num; 37 | } else { 38 | cnt1--; 39 | cnt2--; 40 | } 41 | } 42 | 43 | // count the two candiates. 44 | cnt1 = 0; 45 | cnt2 = 0; 46 | for (int num: nums) { 47 | if (num == n1) { 48 | cnt1++; 49 | } else if (num == n2) { 50 | cnt2++; 51 | } 52 | } 53 | 54 | if (cnt1 < cnt2) { 55 | return n2; 56 | } 57 | 58 | return n1; 59 | } 60 | } 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /lintcode/stack/StackQueue.java: -------------------------------------------------------------------------------- 1 | package Algorithms.lintcode.stack; 2 | 3 | import java.util.Stack; 4 | 5 | public class StackQueue { 6 | private Stack stack1; 7 | private Stack stack2; 8 | 9 | public StackQueue() { 10 | // do initialization if necessary 11 | stack1 = new Stack(); 12 | stack2 = new Stack(); 13 | } 14 | 15 | public void push(int element) { 16 | // write your code here 17 | stack1.push(element); 18 | } 19 | 20 | public int pop() { 21 | // write your code here 22 | if (stack2.isEmpty()) { 23 | while (!stack1.isEmpty()) { 24 | stack2.push(stack1.pop()); 25 | } 26 | } 27 | 28 | return stack2.pop(); 29 | } 30 | 31 | public int top() { 32 | // write your code here 33 | // write your code here 34 | if (stack2.isEmpty()) { 35 | while (!stack1.isEmpty()) { 36 | stack2.push(stack1.pop()); 37 | } 38 | } 39 | 40 | return stack2.peek(); 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /list/DeleteDuplicates.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * public class ListNode { 8 | * int val; 9 | * ListNode next; 10 | * ListNode(int x) { 11 | * val = x; 12 | * next = null; 13 | * } 14 | * } 15 | */ 16 | public class DeleteDuplicates { 17 | public ListNode deleteDuplicates(ListNode head) { 18 | if (head == null) { 19 | return null; 20 | } 21 | 22 | ListNode dummy = new ListNode(0); 23 | dummy.next = head; 24 | 25 | ListNode cur = dummy; 26 | 27 | while (cur != null) { 28 | if (cur.next != null 29 | && cur.next.next != null 30 | && cur.next.val == cur.next.next.val) { 31 | // remove cur.next; 32 | cur.next = cur.next.next; 33 | } else { 34 | cur = cur.next; 35 | } 36 | } 37 | 38 | return dummy.next; 39 | } 40 | } -------------------------------------------------------------------------------- /list/DeleteDuplicates2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * public class ListNode { 8 | * int val; 9 | * ListNode next; 10 | * ListNode(int x) { 11 | * val = x; 12 | * next = null; 13 | * } 14 | * } 15 | * 16 | * Remove Duplicates from Sorted List II Total Accepted: 21701 Total Submissions: 87380 My Submissions 17 | Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. 18 | 19 | For example, 20 | Given 1->2->3->3->4->4->5, return 1->2->5. 21 | Given 1->1->1->2->3, return 2->3. 22 | */ 23 | public class DeleteDuplicates2 { 24 | public ListNode deleteDuplicates(ListNode head) { 25 | if (head == null) { 26 | return null; 27 | } 28 | 29 | // record the head. 30 | ListNode dummy = new ListNode(0); 31 | dummy.next = head; 32 | 33 | ListNode cur = dummy; 34 | 35 | // to delete the last node in the list of duplications. 36 | boolean del = false; 37 | 38 | while (cur != null) { 39 | if (cur.next != null 40 | && cur.next.next != null 41 | && cur.next.val == cur.next.next.val) { 42 | cur.next = cur.next.next; 43 | del = true; 44 | } else { 45 | // delete the last node in a duplicaions list. 46 | if (del) { 47 | cur.next = cur.next.next; 48 | 49 | // set back the flag to be false. 50 | del = false; 51 | } else { 52 | // move forward. 53 | cur = cur.next; 54 | } 55 | } 56 | } 57 | 58 | return dummy.next; 59 | } 60 | } -------------------------------------------------------------------------------- /list/DetectCycle.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * class ListNode { 8 | * int val; 9 | * ListNode next; 10 | * ListNode(int x) { 11 | * val = x; 12 | * next = null; 13 | * } 14 | * } 15 | */ 16 | public class DetectCycle { 17 | public ListNode detectCycle(ListNode head) { 18 | if (head == null) { 19 | return null; 20 | } 21 | 22 | ListNode s = head; 23 | ListNode f = head; 24 | 25 | ListNode cross = null; 26 | 27 | while (f != null && f.next != null) { 28 | s = s.next; 29 | f = f.next.next; 30 | 31 | if (s == f) { 32 | cross = s; 33 | 34 | // remember to break here, or you will get a loop. 35 | break; 36 | } 37 | } 38 | 39 | // don't detect any cycle. 40 | if (cross == null) { 41 | return null; 42 | } 43 | 44 | // place the slow to the start again. 45 | s = head; 46 | while (true) { 47 | if (s == f) { 48 | return s; 49 | } 50 | 51 | s = s.next; 52 | f = f.next; 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /list/Generate.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Generate { 7 | public List> generate(int numRows) { 8 | List> ret = new ArrayList>(); 9 | 10 | for (int i = 0; i < numRows; i++) { 11 | List list = new ArrayList(); 12 | for (int j = 0; j <= i; j++) { 13 | if (j == 0 || i == j) { 14 | list.add(1); 15 | } else { 16 | int sum = ret.get(i - 1).get(j - 1) + ret.get(i - 1).get(j); 17 | list.add(sum); 18 | } 19 | } 20 | 21 | // BUG 1: forget this statement. 22 | ret.add(list); 23 | } 24 | 25 | return ret; 26 | } 27 | } -------------------------------------------------------------------------------- /list/HasCycle.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * class ListNode { 8 | * int val; 9 | * ListNode next; 10 | * ListNode(int x) { 11 | * val = x; 12 | * next = null; 13 | * } 14 | * } 15 | */ 16 | public class HasCycle { 17 | public boolean hasCycle(ListNode head) { 18 | if (head == null) { 19 | return false; 20 | } 21 | 22 | ListNode slow = head; 23 | ListNode fast = head; 24 | 25 | while (fast != null && fast.next != null) { 26 | slow = slow.next; 27 | fast = fast.next.next; 28 | if (slow == fast) { 29 | return true; 30 | } 31 | } 32 | 33 | return false; 34 | } 35 | } -------------------------------------------------------------------------------- /list/InsertionSortList.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * public class ListNode { 8 | * int val; 9 | * ListNode next; 10 | * ListNode(int x) { 11 | * val = x; 12 | * next = null; 13 | * } 14 | * } 15 | */ 16 | public class InsertionSortList { 17 | public ListNode insertionSortList(ListNode head) { 18 | ListNode dummy = new ListNode(0); 19 | 20 | while (head != null) { 21 | ListNode pre = dummy; 22 | 23 | // 注意,这里要用<= 来保证算法的稳定性 24 | // 因为假如有2个数相同,后面的数后找到,也要插入到后面才可以。也就是说当=的时候,是继续往下走 25 | while (pre.next != null && pre.next.val <= head.val) { 26 | pre = pre.next; 27 | } 28 | 29 | // unlink the node from the original link. And record the next position. 30 | ListNode headNext = head.next; 31 | head.next = pre.next; 32 | 33 | pre.next = head; 34 | head = headNext; 35 | } 36 | 37 | return dummy.next; 38 | } 39 | } -------------------------------------------------------------------------------- /list/MergeKLists.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import java.util.Comparator; 4 | import java.util.List; 5 | import java.util.PriorityQueue; 6 | 7 | import Algorithms.algorithm.others.ListNode; 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * public class ListNode { 12 | * int val; 13 | * ListNode next; 14 | * ListNode(int x) { 15 | * val = x; 16 | * next = null; 17 | * } 18 | * } 19 | */ 20 | public class MergeKLists { 21 | public ListNode mergeKLists(List lists) { 22 | // 注意:lists.size() == 0 一定要处理,否则建立queue时 不能输入初始size为0 23 | if (lists == null || lists.size() == 0) { 24 | return null; 25 | } 26 | 27 | Comparator comparator = new Comparator() { 28 | public int compare(ListNode o1, ListNode o2) { 29 | return o1.val - o2.val; 30 | } 31 | }; 32 | 33 | // create a priority Queue. 34 | PriorityQueue q = new PriorityQueue(lists.size(), comparator); 35 | 36 | // add all the first nodes to the QUEUE. 37 | for (ListNode node: lists) { 38 | if (node != null) { 39 | // don't add EMPTY lists. 40 | q.offer(node); 41 | } 42 | } 43 | 44 | ListNode dummy = new ListNode(0); 45 | ListNode tail = dummy; 46 | 47 | while (!q.isEmpty()) { 48 | // get a list node from the queue. 49 | ListNode node = q.poll(); 50 | 51 | // add the node to the result link. 52 | tail.next = node; 53 | tail = tail.next; 54 | 55 | // add a new node from the lists to the priority queue. 56 | if (node.next != null) { 57 | q.offer(node.next); 58 | } 59 | } 60 | 61 | return dummy.next; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /list/MergeTwoLists.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | public class MergeTwoLists { 6 | public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 7 | if (l1 == null && l2 == null) { 8 | return null; 9 | } 10 | 11 | ListNode dummy = new ListNode(0); 12 | ListNode cur = dummy; 13 | while (l1 != null && l2 != null) { 14 | if (l1.val < l2.val) { 15 | cur.next = l1; 16 | l1 = l1.next; 17 | } else { 18 | cur.next = l2; 19 | l2 = l2.next; 20 | } 21 | 22 | cur = cur.next; 23 | } 24 | 25 | if (l1 != null) { 26 | cur.next = l1; 27 | } else { 28 | cur.next = l2; 29 | } 30 | 31 | return dummy.next; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /list/MergeTwoLists_1206.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * public class ListNode { 8 | * int val; 9 | * ListNode next; 10 | * ListNode(int x) { 11 | * val = x; 12 | * next = null; 13 | * } 14 | * } 15 | */ 16 | public class MergeTwoLists_1206 { 17 | public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 18 | ListNode dummy = new ListNode(0); 19 | ListNode cur = dummy; 20 | 21 | while (l1 != null && l2 != null) { 22 | if (l1.val < l2.val) { 23 | cur.next = l1; 24 | l1 = l1.next; 25 | } else { 26 | cur.next = l2; 27 | l2 = l2.next; 28 | } 29 | cur = cur.next; 30 | } 31 | 32 | if (l1 != null) { 33 | cur.next = l1; 34 | } else { 35 | cur.next = l2; 36 | } 37 | 38 | return dummy.next; 39 | } 40 | } -------------------------------------------------------------------------------- /list/Partition.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * public class ListNode { 8 | * int val; 9 | * ListNode next; 10 | * ListNode(int x) { 11 | * val = x; 12 | * next = null; 13 | * } 14 | * } 15 | */ 16 | public class Partition { 17 | public ListNode partition(ListNode head, int x) { 18 | if (head == null) { 19 | return null; 20 | } 21 | 22 | ListNode dummy = new ListNode(0); 23 | dummy.next = head; 24 | 25 | ListNode pre = dummy; 26 | ListNode cur = head; 27 | 28 | // Record the big list. 29 | ListNode bigDummy = new ListNode(0); 30 | ListNode bigTail = bigDummy; 31 | 32 | while (cur != null) { 33 | if (cur.val >= x) { 34 | // Unlink the cur; 35 | pre.next = cur.next; 36 | 37 | // Add the cur to the tail of the new link. 38 | bigTail.next = cur; 39 | cur.next = null; 40 | 41 | // Refresh the bigTail. 42 | bigTail = cur; 43 | 44 | // 移除了一个元素的时候,pre不需要修改,因为cur已经移动到下一个位置了。 45 | } else { 46 | pre = pre.next; 47 | } 48 | 49 | cur = pre.next; 50 | } 51 | 52 | // Link the Big linklist to the smaller one. 53 | pre.next = bigDummy.next; 54 | 55 | return dummy.next; 56 | } 57 | } -------------------------------------------------------------------------------- /list/PartitionList.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * public class ListNode { 8 | * int val; 9 | * ListNode next; 10 | * ListNode(int x) { 11 | * val = x; 12 | * next = null; 13 | * } 14 | * } 15 | */ 16 | public class PartitionList { 17 | public ListNode partition(ListNode head, int x) { 18 | // the list which is greater than or equal to x 19 | ListNode dummyGE = new ListNode(0); 20 | 21 | // the list which is less than x 22 | ListNode dummyLess = new ListNode(0); 23 | 24 | // link the dummy to the head; 25 | dummyGE.next = head; 26 | 27 | ListNode pre = dummyGE; 28 | 29 | ListNode tailLess = dummyLess; 30 | 31 | // go through the list and remove the small node to a new list. 32 | while (pre.next != null) { 33 | if (pre.next.val < x) { 34 | // Add this to the less list. 35 | tailLess.next = pre.next; 36 | tailLess = tailLess.next; 37 | 38 | // remove the node from the current list. 39 | pre.next = pre.next.next; 40 | } else { 41 | // move the pre node forward. 42 | pre = pre.next; 43 | } 44 | } 45 | 46 | // link the LESS list and the Large list. 47 | tailLess.next = dummyGE.next; 48 | 49 | return dummyLess.next; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /list/RemoveNthFromEnd.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * public class ListNode { 8 | * int val; 9 | * ListNode next; 10 | * ListNode(int x) { 11 | * val = x; 12 | * next = null; 13 | * } 14 | * } 15 | */ 16 | public class RemoveNthFromEnd { 17 | public ListNode removeNthFromEnd(ListNode head, int n) { 18 | if (head == null) { 19 | return null; 20 | } 21 | 22 | ListNode dummy = new ListNode(0); 23 | dummy.next = head; 24 | 25 | // move tail N nodes faster than pre. 26 | ListNode tail = dummy; 27 | // 注意,这里用for比较好一点,用while时,经常不记得将参量-- 28 | for (int i = n; i > 0; i--) { 29 | tail = tail.next; 30 | } 31 | 32 | ListNode pre = dummy; 33 | 34 | // get the node before the node we want to delete. 35 | while (tail != null && tail.next != null) { 36 | tail = tail.next; 37 | pre = pre.next; 38 | } 39 | 40 | // DELTE. 41 | if (pre.next != null) { 42 | pre.next = pre.next.next; 43 | } 44 | 45 | return dummy.next; 46 | } 47 | } -------------------------------------------------------------------------------- /list/ReverseBetween.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | public class ReverseBetween { 6 | public ListNode reverseBetween(ListNode head, int m, int n) { 7 | if (head == null || head.next == null) { 8 | return head; 9 | } 10 | 11 | if (m >= n) { 12 | return head; 13 | } 14 | 15 | ListNode dummy = new ListNode(0); 16 | dummy.next = head; 17 | 18 | ListNode pre = dummy; 19 | 20 | //1. get the pre node before m. 21 | for (int i = m; i > 1; i--) { 22 | pre = pre.next; 23 | } 24 | 25 | // record the tail of the reversed link. 26 | ListNode reverseTail = pre.next; 27 | pre.next = null; 28 | 29 | // reverse the link. 30 | ListNode cur = reverseTail; 31 | 32 | for (int i = n - m + 1; i > 0; i--) { 33 | if (i == 1) { 34 | // 这里是翻转段后的第一个元素 . 35 | reverseTail.next = cur.next; 36 | } 37 | 38 | ListNode tmp = cur.next; 39 | 40 | cur.next = pre.next; 41 | pre.next = cur; 42 | 43 | cur = tmp; 44 | } 45 | 46 | return dummy.next; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /list/ReverseLinkedList2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | public class ReverseLinkedList2 { 6 | public static void main(String[] args) { 7 | ReverseLinkedList2 rLL = new ReverseLinkedList2(); 8 | ListNode head = new ListNode(3); 9 | head.next = new ListNode(5); 10 | rLL.reverseBetween(head, 2, 2); 11 | } 12 | 13 | public ListNode reverseBetween(ListNode head, int m, int n) { 14 | if (head == null) { 15 | return null; 16 | } 17 | 18 | if (head.next == null) { 19 | return head; 20 | } 21 | 22 | ListNode dumyNode = new ListNode(0); 23 | dumyNode.next = head; 24 | 25 | ListNode tmpHead = dumyNode; 26 | 27 | // get the head before the reverse list; 28 | for (int i = m; i > 1; i--) { 29 | tmpHead = tmpHead.next; 30 | } 31 | 32 | 33 | // store the pre pointer 34 | ListNode pre = null; 35 | ListNode pst = tmpHead.next; 36 | 37 | // store the head for later use. 38 | ListNode reverseHead = pst; 39 | 40 | // reverse the specific linkedlist. 41 | for (int i = 0; i < n - m + 1; i++) { 42 | ListNode tmp = pst.next; 43 | pst.next = pre; 44 | pre = pst; 45 | pst = tmp; 46 | } 47 | 48 | tmpHead.next = pre; 49 | reverseHead.next = pst; 50 | 51 | if (m > 1) { 52 | return head; 53 | } else { 54 | return pre; 55 | } 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /list/RotateList.java: -------------------------------------------------------------------------------- 1 | package Algorithms.list; 2 | 3 | import Algorithms.algorithm.others.ListNode; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * public class ListNode { 8 | * int val; 9 | * ListNode next; 10 | * ListNode(int x) { 11 | * val = x; 12 | * next = null; 13 | * } 14 | * } 15 | */ 16 | public class RotateList { 17 | public static void main(String[] strs) { 18 | ListNode node1 = new ListNode(1); 19 | ListNode ret = rotateRight(node1, 0); 20 | System.out.println(ret.toString()); 21 | } 22 | 23 | public static ListNode rotateRight(ListNode head, int n) { 24 | if (head == null) { 25 | return null; 26 | } 27 | 28 | // when the list rotate n, it will go back. 29 | n = n % getlen(head); 30 | 31 | ListNode dummy = new ListNode(0); 32 | dummy.next = head; 33 | 34 | // get the pre node before the node which is the new head; 35 | // for example: Given 1->2->3->4->5->NULL and k = 2, 36 | // we should find 3 37 | // return 4->5->1->2->3->NULL. 38 | ListNode tail = dummy; 39 | while (n > 0) { 40 | tail = tail.next; 41 | n--; 42 | } 43 | 44 | ListNode pre = dummy; 45 | while (tail != null && tail.next != null) { 46 | tail = tail.next; 47 | pre = pre.next; 48 | } 49 | 50 | // cut the two list and connect the head to the tail. 51 | tail.next = dummy.next; 52 | 53 | ListNode headNew = pre.next; 54 | pre.next = null; 55 | 56 | return headNew; 57 | } 58 | 59 | // get the list lenght. 60 | public static int getlen(ListNode head) { 61 | int len = 0; 62 | while (head != null) { 63 | len++; 64 | head = head.next; 65 | } 66 | 67 | return len; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /math/Reverse.java: -------------------------------------------------------------------------------- 1 | package Algorithms.math; 2 | 3 | public class Reverse { 4 | public int reverse(int x) { 5 | long ret = 0; 6 | 7 | while (x != 0) { 8 | ret = ret * 10 + x % 10; 9 | x /= 10; 10 | } 11 | 12 | if (ret > Integer.MAX_VALUE || ret < Integer.MIN_VALUE) { 13 | return 0; 14 | } 15 | 16 | return (int)ret; 17 | } 18 | } -------------------------------------------------------------------------------- /new/IsPalindrome.java: -------------------------------------------------------------------------------- 1 | 2 | public class IsPalindrome { 3 | public static void main(String[] strs) { 4 | System.out.print(isPalindrome(12344321)); 5 | } 6 | 7 | public static boolean isPalindrome(int x) { 8 | long y = 0; 9 | 10 | if (x < 0) { 11 | return false; 12 | } 13 | 14 | int tmp = x; 15 | while (tmp > 0) { 16 | int a = tmp % 10; 17 | tmp /= 10; 18 | 19 | y *= 10; 20 | y += a; 21 | } 22 | 23 | return y == x; 24 | } 25 | } -------------------------------------------------------------------------------- /new/LengthOfLastWord.java: -------------------------------------------------------------------------------- 1 | public class LengthOfLastWord { 2 | public static void main(String[] strs) { 3 | System.out.println(lengthOfLastWord(" a")); 4 | } 5 | 6 | public static int lengthOfLastWord(String s) { 7 | if (s == null || s.length() == 0) { 8 | return 0; 9 | } 10 | 11 | String strNew = s.trim(); 12 | 13 | int len = strNew.length(); 14 | 15 | int start = 0; 16 | for (int i = len - 1; i >= 0; i--) { 17 | if (s.charAt(i) == ' ') { 18 | start = i + 1; 19 | break; 20 | } 21 | } 22 | 23 | return (len - start); 24 | } 25 | } -------------------------------------------------------------------------------- /new/MinWindow.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuzhangcmu/LeetCode/eb2aaeada59cf42ea26f4003f9709c4f1b05ac17/new/MinWindow.java -------------------------------------------------------------------------------- /new/ThreeSum.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Arrays; 3 | import java.util.List; 4 | 5 | 6 | public class ThreeSum { 7 | public static void main(String[] str) { 8 | int[] num = {0,0,0,0}; 9 | System.out.println(threeSum(num)); 10 | } 11 | 12 | public static List> threeSum(int[] num) { 13 | ArrayList> ret = new ArrayList>(); 14 | if (num == null || num.length == 0) { 15 | return ret; 16 | } 17 | 18 | int len = num.length; 19 | 20 | // sort the array to get unique solutions. 21 | Arrays.sort(num); 22 | for (int i = 0; i < len - 2; i++) { 23 | // skip the duplicate numbers. 24 | while (i != 0 && num[i] == num[i - 1]) { 25 | continue; 26 | } 27 | 28 | int n2 = i + 1; 29 | int n3 = len - 1; 30 | 31 | while (n2 < n3) { 32 | int sum = num[i] + num[n2] + num[n3]; 33 | if (sum == 0) { 34 | ArrayList list = new ArrayList(); 35 | list.add(i); 36 | list.add(n2); 37 | list.add(n3); 38 | ret.add(list); 39 | 40 | n2++; 41 | n3--; 42 | 43 | // skip the duplication. 44 | while (n2 < len - 1 && num[n2] == num[n2 - 1]) { 45 | n2++; 46 | } 47 | 48 | while (n3 > i && num[n3] == num[n3 + 1]) { 49 | n3--; 50 | } 51 | } else if (sum > 0) { 52 | n3--; 53 | } else { 54 | n2++; 55 | } 56 | } 57 | } 58 | 59 | return ret; 60 | } 61 | } -------------------------------------------------------------------------------- /permutation/Stopwatch.java: -------------------------------------------------------------------------------- 1 | package Algorithms.permutation; 2 | 3 | /***************************************** 4 | * Stopwatch class to be used as a timer 5 | *****************************************/ 6 | 7 | public class Stopwatch { 8 | 9 | 10 | private final long start; 11 | 12 | public Stopwatch() { 13 | start = System.currentTimeMillis(); 14 | } 15 | 16 | // return time (in milliseconds) since this object was created 17 | public double elapsedTime() { 18 | long now = System.currentTimeMillis(); 19 | return now - start; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /recursion/Factorial.java: -------------------------------------------------------------------------------- 1 | package Algorithms.recursion; 2 | 3 | import java.util.Stack; 4 | 5 | public class Factorial { 6 | public static void main(String[] strs) { 7 | System.out.println(factorial(10)); 8 | System.out.println(factorialIterator(10)); 9 | } 10 | 11 | public static int factorialIterator(Integer n) { 12 | int ret = 1; 13 | for (int i = n; i >= 1; i--) { 14 | ret *= i; 15 | } 16 | 17 | return ret; 18 | } 19 | 20 | 21 | public static int factorial(Integer n) { 22 | Stack s = new Stack(); 23 | 24 | s.push(n); 25 | 26 | int ret = 1; 27 | 28 | while (!s.isEmpty()) { 29 | int cur = s.pop(); 30 | 31 | if (cur == 1) { 32 | break; 33 | } 34 | 35 | ret *= cur; 36 | s.push(cur - 1); 37 | } 38 | 39 | return ret; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /recursion/GrayCode.java: -------------------------------------------------------------------------------- 1 | package Algorithms.recursion; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class GrayCode { 7 | public List grayCode(int n) { 8 | List ret = new ArrayList(); 9 | if (n == 0) { 10 | ret.add(0); 11 | return ret; 12 | } 13 | 14 | ret = grayCode(n - 1); 15 | 16 | for (int i = ret.size() - 1; i >= 0; i--) { 17 | int num = ret.get(i); 18 | num += 1 << (n - 1); 19 | ret.add(num); 20 | } 21 | 22 | return ret; 23 | } 24 | } -------------------------------------------------------------------------------- /sequence/Reverse.java: -------------------------------------------------------------------------------- 1 | package Algorithms.sequence; 2 | public class Reverse { 3 | public static void main(String[] args) { 4 | System.out.println(reverse(-1234)); 5 | System.out.println(reverse(100)); 6 | } 7 | 8 | public static int reverse(int x) { 9 | long n = x; 10 | 11 | long ret = 0; 12 | while (n != 0) { 13 | long left = n % 10; 14 | ret *= 10; 15 | ret += left; 16 | n /= 10; 17 | } 18 | 19 | return (int)ret; 20 | } 21 | } -------------------------------------------------------------------------------- /sequence/ThreeSum.java: -------------------------------------------------------------------------------- 1 | package Algorithms.sequence; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class ThreeSum { 8 | public List> threeSum(int[] num) { 9 | List> ret = new ArrayList>(); 10 | if (num == null) { 11 | return ret; 12 | } 13 | 14 | Arrays.sort(num); 15 | 16 | int len = num.length; 17 | for (int i = 0; i < len; i++) { 18 | // 跳过重复的元素,首个数字不需要选择重复的. 19 | if (i > 0 && num[i] == num[i - 1]) { 20 | continue; 21 | } 22 | 23 | // 创建二个指针,分别从2头查找,查目标值,它们2个加起来要等于0-num1 24 | int l = i + 1; 25 | int r = len - 1; 26 | while (l < r) { 27 | int sum = num[i] + num[l] + num[r]; 28 | if (sum == 0) { 29 | ArrayList list = new ArrayList(); 30 | list.add(num[i]); 31 | list.add(num[l]); 32 | list.add(num[r]); 33 | ret.add(list); 34 | 35 | // 跳过重复元素 36 | do { 37 | l++; 38 | } while (l < r && num[l] == num[l - 1]); 39 | 40 | do { 41 | r--; 42 | } while (l < r && num[r] == num[r + 1]); 43 | } else if (sum < 0) { 44 | l++; 45 | } else { 46 | r--; 47 | } 48 | } 49 | } 50 | 51 | return ret; 52 | } 53 | } -------------------------------------------------------------------------------- /sequence/ThreeSumClosest.java: -------------------------------------------------------------------------------- 1 | package Algorithms.sequence; 2 | 3 | public class ThreeSumClosest { 4 | public int threeSumClosest(int[] num, int target) { 5 | if (num == null) { 6 | return 0; 7 | } 8 | 9 | int len = num.length; 10 | 11 | int diffMin = Integer.MAX_VALUE; 12 | 13 | int ret = 0; 14 | for (int i = 0; i < len; i++) { 15 | 16 | int l = i + 1; 17 | int r = len - 1; 18 | 19 | while (l < r) { 20 | int diff = target - (num[i] + num[l] + num[r]); 21 | 22 | if (Math.abs(diff) < diffMin) { 23 | diffMin = Math.abs(diff); 24 | ret = num[i] + num[l] + num[r]; 25 | } 26 | 27 | if (diff > 0) { 28 | // move right; 29 | l++; 30 | } else if (diff < 0) { 31 | // move left; 32 | r--; 33 | } else { 34 | // We get the 0 now. There is no way that it would be less than 0. 35 | return ret; 36 | } 37 | } 38 | } 39 | 40 | return ret; 41 | } 42 | } -------------------------------------------------------------------------------- /sequence/TwoSum.java: -------------------------------------------------------------------------------- 1 | package Algorithms.sequence; 2 | 3 | import java.util.HashMap; 4 | 5 | /* 6 | * Two Sum Total Accepted: 36938 Total Submissions: 200732 My Submissions Question Solution 7 | Given an array of integers, find two numbers such that they add up to a specific target number. 8 | 9 | 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. 10 | 11 | You may assume that each input would have exactly one solution. 12 | 13 | Input: numbers={2, 7, 11, 15}, target=9 14 | Output: index1=1, index2=2 15 | * */ 16 | 17 | public class TwoSum { 18 | public int[] twoSum(int[] numbers, int target) { 19 | HashMap map = new HashMap(); 20 | int[] ret = new int[2]; 21 | 22 | for (int i = 0; i < numbers.length; i++) { 23 | if (map.containsKey(target - numbers[i])) { 24 | 25 | // As the index is not ZERO based, we should add one to the result. 26 | ret[0] = map.get(target - numbers[i]) + 1; 27 | ret[1] = i + 1; 28 | return ret; 29 | } 30 | map.put(numbers[i], i); 31 | } 32 | 33 | return ret; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /sort/BucketSorter.java: -------------------------------------------------------------------------------- 1 | package Algorithms.sort; 2 | 3 | 4 | /** 5 | * @author yovn 6 | * 7 | */ 8 | public class BucketSorter { 9 | public void sort(int[] keys,int from,int len,int max) 10 | { 11 | int[] count = new int[max]; 12 | int[] tmp = new int[len]; 13 | 14 | // count the keys. 15 | for (int i = 0; i < len; i++) { 16 | count[keys[from + i]]++; 17 | } 18 | 19 | // calculate the position. 20 | // BUG 1: i go from 1 not 0. 21 | for (int i = 1; i < max; i++) { 22 | count[i] = count[i] + count[i - 1]; 23 | } 24 | 25 | // back the array. 26 | System.arraycopy(keys, from, tmp, 0, len); 27 | 28 | // Place the objects into the right position. 29 | for (int i = len - 1; i >= 0; i--) { 30 | keys[--count[tmp[i]]] = tmp[i]; 31 | } 32 | } 33 | /** 34 | * @param args 35 | */ 36 | public static void main(String[] args) { 37 | 38 | int[] a={1,4,8,3,2,9,5,0,7,6,9,10,9,13,14,15,11,12,17,16}; 39 | BucketSorter sorter=new BucketSorter(); 40 | sorter.sort(a,0,a.length,20);//actually is 18, but 20 will also work 41 | 42 | 43 | for(int i=0;i s = new Stack(); 13 | 14 | for (int i = 0; i < len; i++) { 15 | String str = tokens[i]; 16 | if (str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/")) { 17 | // get out the two operation number. 18 | int n2 = s.pop(); 19 | int n1 = s.pop(); 20 | if (str.equals("+")) { 21 | s.push(n1 + n2); 22 | } else if (str.equals("-")) { 23 | s.push(n1 - n2); 24 | } else if (str.equals("*")) { 25 | s.push(n1 * n2); 26 | } else if (str.equals("/")) { 27 | s.push(n1 / n2); 28 | } 29 | } else { 30 | s.push(Integer.parseInt(str)); 31 | } 32 | } 33 | 34 | if (s.isEmpty()) { 35 | return 0; 36 | } 37 | 38 | return s.pop(); 39 | } 40 | } -------------------------------------------------------------------------------- /stack/MinStack.java: -------------------------------------------------------------------------------- 1 | package Algorithms.stack; 2 | 3 | import java.util.Stack; 4 | 5 | class MinStack { 6 | public static void main(String[] strs) { 7 | MinStack sta = new MinStack(); 8 | 9 | //push(512),push(-1024),push(-1024),push(512),pop,getminStack,pop,getminStack,pop,getminStack 10 | sta.push(512); 11 | sta.push(-1024); 12 | sta.push(-1024); 13 | sta.push(512); 14 | 15 | sta.pop(); 16 | sta.getminStack(); 17 | sta.pop(); 18 | sta.getminStack(); 19 | sta.pop(); 20 | sta.getminStack(); 21 | } 22 | 23 | Stack elements = new Stack(); 24 | Stack minStack = new Stack(); 25 | 26 | public void push(int x) { 27 | elements.push(x); 28 | if (minStack.isEmpty() || x <= minStack.peek()) { 29 | minStack.push(x); 30 | } 31 | } 32 | 33 | public void pop() { 34 | if (elements.isEmpty()) { 35 | return; 36 | } 37 | 38 | if (elements.peek().equals(minStack.peek())) { 39 | minStack.pop(); 40 | } 41 | elements.pop(); 42 | } 43 | 44 | public int top() { 45 | return elements.peek(); 46 | } 47 | 48 | public int getminStack() { 49 | return minStack.peek(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /string/Anagrams.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | 8 | public class Anagrams { 9 | public List anagrams(String[] strs) { 10 | // 1916. 11 | List ret = new ArrayList(); 12 | if (strs == null) { 13 | return ret; 14 | } 15 | 16 | HashMap> map = new HashMap>(); 17 | for (String str: strs) { 18 | char[] chars = str.toCharArray(); 19 | Arrays.sort(chars); 20 | String tmp = new String(chars); 21 | 22 | ArrayList list = map.get(tmp); 23 | if (list == null) { 24 | } else { 25 | list.add(str); 26 | } 27 | } 28 | 29 | for (List strList: map.values()) { 30 | if (strList.size() > 1) { 31 | //ret.addAll(strList); 32 | } 33 | } 34 | 35 | return ret; 36 | } 37 | } -------------------------------------------------------------------------------- /string/CompareVersion.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class CompareVersion { 4 | public static void main(String[] args) { 5 | compareVersion("1", "0"); 6 | } 7 | 8 | public static int compareVersion(String version1, String version2) { 9 | if (version1 == null || version2 == null || version1.length() == 0 10 | || version2.length() == 0) { 11 | return 0; 12 | } 13 | 14 | String[] strs1 = version1.split("\\."); 15 | String[] strs2 = version2.split("\\."); 16 | 17 | int size1 = strs1.length; 18 | int size2 = strs2.length; 19 | 20 | int minSize = Math.min(size1, size2); 21 | 22 | for (int i = 0; i < minSize; i++) { 23 | int v1 = Integer.parseInt(strs1[i]); 24 | int v2 = Integer.parseInt(strs2[i]); 25 | 26 | if (v1 > v2) { 27 | return 1; 28 | } else if (v1 < v2) { 29 | return -1; 30 | } 31 | } 32 | 33 | return 0; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /string/CompareVersion2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | public class CompareVersion2 { 3 | public static void main(String[] args) { 4 | 5 | 6 | System.out.println(compareVersion("01", "1.0.1")); 7 | } 8 | 9 | public static int compareVersion(String version1, String version2) { 10 | if (version1 == null || version2 == null) { 11 | return 0; 12 | } 13 | 14 | int len1 = version1.length(); 15 | int len2 = version2.length(); 16 | 17 | int p1 = 0; 18 | int p2 = 0; 19 | 20 | int v1 = 0; 21 | int v2 = 0; 22 | while (true) { 23 | v1 = 0; 24 | v2 = 0; 25 | 26 | // Like this: 1.3 VS 1.3.4 27 | // The length of the two version are not equal. 28 | if (p1 >= len1 && p2 >= len2) { 29 | return 0; 30 | } 31 | 32 | while (p1 < len1 && version1.charAt(p1) != '.') { 33 | v1 = v1 * 10 + ((int)version1.charAt(p1) - '0'); 34 | p1++; 35 | } 36 | 37 | while (p2 < len2 && version2.charAt(p2) != '.') { 38 | v2 = v2 * 10 + ((int)version2.charAt(p2) - '0'); 39 | p2++; 40 | } 41 | 42 | if (v1 > v2) { 43 | return 1; 44 | } else if (v1 < v2) { 45 | return -1; 46 | } 47 | 48 | p1++; 49 | p2++; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /string/Convert.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class Convert { 4 | public static void main(String[] strs) { 5 | System.out.println(convert("A", 1)); 6 | } 7 | 8 | public static String convert(String s, int nRows) { 9 | if (s == null) { 10 | return null; 11 | } 12 | 13 | // 第一个小部分的大小 14 | int size = 2 * nRows - 2; 15 | 16 | // 当行数为1的时候,不需要折叠。 17 | if (nRows <= 1) { 18 | return s; 19 | } 20 | 21 | StringBuilder ret = new StringBuilder(); 22 | 23 | int len = s.length(); 24 | for (int i = 0; i < nRows; i++) { 25 | // j代表第几个BLOCK 26 | for (int j = i; j < len; j += size) { 27 | ret.append(s.charAt(j)); 28 | 29 | // 即不是第一行,也不是最后一行,还需要加上中间的节点 30 | int mid = j + size - i * 2; 31 | if (i != 0 && i != nRows - 1 && mid < len) { 32 | char c = s.charAt(mid); 33 | ret.append(c); 34 | } 35 | } 36 | } 37 | 38 | return ret.toString(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /string/CountAndSay.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class CountAndSay { 4 | public String countAndSay(int n) { 5 | if (n == 0) { 6 | return null; 7 | } 8 | 9 | if (n == 1) { 10 | return "1"; 11 | } 12 | 13 | String s = countAndSay(n - 1); 14 | StringBuilder sb = new StringBuilder(); 15 | 16 | int len = s.length(); 17 | int cnt = 0; 18 | for (int i = 0; i < len; i++) { 19 | cnt++; 20 | 21 | if (i == len - 1 || (i < len - 1 && s.charAt(i) != s.charAt(i + 1))) { 22 | sb.append(cnt); 23 | sb.append(s.charAt(i)); 24 | cnt = 0; 25 | } 26 | } 27 | 28 | return sb.toString(); 29 | } 30 | } -------------------------------------------------------------------------------- /string/GenerateParenthesis.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class GenerateParenthesis { 7 | public List generateParenthesis(int n) { 8 | List ret = new ArrayList(); 9 | 10 | if (n == 0) { 11 | return ret; 12 | } 13 | 14 | dfs(n, n, new StringBuilder(), ret); 15 | 16 | return ret; 17 | } 18 | 19 | // left : the left Parentheses 20 | // right : the right Parentheses 21 | public void dfs(int left, int right, StringBuilder sb, List ret) { 22 | if (left == 0 && right == 0) { 23 | ret.add(sb.toString()); 24 | return; 25 | } 26 | 27 | // left < right means that we have more ( then we can add ). 28 | if (left < 0 || right < 0 || left > right) { 29 | return; 30 | } 31 | 32 | dfs(left - 1, right, sb.append('('), ret); 33 | sb.deleteCharAt(sb.length() - 1); 34 | 35 | dfs(left, right - 1, sb.append(')'), ret); 36 | sb.deleteCharAt(sb.length() - 1); 37 | } 38 | } -------------------------------------------------------------------------------- /string/IntToRoman.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class IntToRoman { 4 | public String intToRoman(int num) { 5 | int nums[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; 6 | String[] romans = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; 7 | 8 | StringBuilder sb = new StringBuilder(); 9 | 10 | int i = 0; 11 | // 使用贪心法。尽量拆分数字 12 | while (i < nums.length) { 13 | if (num >= nums[i]) { 14 | sb.append(romans[i]); 15 | num -= nums[i]; 16 | } else { 17 | i++; 18 | } 19 | } 20 | 21 | return sb.toString(); 22 | } 23 | } -------------------------------------------------------------------------------- /string/IsPalindrome.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class IsPalindrome { 4 | public boolean isPalindrome(String s) { 5 | // http://blog.csdn.net/fightforyourdream/article/details/12860445 6 | if (s == null) { 7 | return false; 8 | } 9 | 10 | int len = s.length(); 11 | 12 | s = s.toLowerCase(); 13 | 14 | int l = 0; 15 | int r = len - 1; 16 | while (l < r) { 17 | if (!isValid(s.charAt(l))) { 18 | l++; 19 | } else if (!isValid(s.charAt(r))) { 20 | r--; 21 | } else if (s.charAt(l) != s.charAt(r)) { 22 | return false; 23 | } else { 24 | l++; 25 | r--; 26 | } 27 | } 28 | 29 | return true; 30 | } 31 | 32 | public boolean isValid(char c) { 33 | return Character.isLetterOrDigit(c); 34 | // if (c <= 'z' && c >= 'a' || c <= 'Z' && c >= 'A' 35 | // || c <= '9' && c >= '0') { 36 | // return true; 37 | // } 38 | 39 | // return false; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /string/LengthOfLastWord.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class LengthOfLastWord { 4 | public static void main(String[] strs) { 5 | String s = " the book "; 6 | System.out.println(lengthOfLastWord1(s)); 7 | } 8 | 9 | // solution 1 10 | public static int lengthOfLastWord1(String s) { 11 | if (s == null || s.length() == 0) { 12 | return 0; 13 | } 14 | 15 | /* 16 | 这里有个规则,它乍看之下很古怪,但很少造成问题:Split会保留开头处的空字段,却舍去结尾处的空字段。例如: 17 | 18 | my @fields = split /:/, “:::a:b:c:::”; #得到(“”,“”,“”,“a”,“b”,“c”) 19 | */ 20 | String[] strs = s.split("\\s+"); 21 | 22 | int size = strs.length; 23 | if (size == 0) { 24 | return 0; 25 | } 26 | int len = strs[size - 1].length(); 27 | return len; 28 | } 29 | 30 | // solution 2 31 | public int lengthOfLastWord(String s) { 32 | if (s == null || s.length() == 0) { 33 | return 0; 34 | } 35 | 36 | // remove the spaces at the end. 37 | String strs = s.trim(); 38 | 39 | int len = strs.length(); 40 | 41 | int ret = 0; 42 | for (int i = len - 1; i >= 0; i--) { 43 | if (strs.charAt(i) == ' ') { 44 | return ret; 45 | } 46 | ret++; 47 | } 48 | 49 | return len; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /string/LongestCommonPrefix.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class LongestCommonPrefix { 4 | //http://blog.csdn.net/fightforyourdream/article/details/14642079 5 | public String longestCommonPrefix(String[] strs) { 6 | if (strs == null) { 7 | return null; 8 | } 9 | 10 | if (strs.length == 0) { 11 | return ""; 12 | } 13 | 14 | String s = strs[0]; 15 | int len = s.length(); 16 | 17 | for (int i = 0; i < len; i++) { 18 | char c = s.charAt(i); 19 | 20 | for (int j = 1; j < strs.length; j++) { 21 | if (strs[j].length() <= i || c != strs[j].charAt(i)) { 22 | // The char i is invalid. 因为读到i时退出,所以不应包含i本身。 23 | return s.substring(0, i); 24 | } 25 | } 26 | } 27 | 28 | // Didn't break, the whole String is valid. 29 | return s; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /string/LongestCommonPrefix_1221_2014.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class LongestCommonPrefix_1221_2014 { 4 | //http://blog.csdn.net/fightforyourdream/article/details/14642079 5 | public String longestCommonPrefix(String[] strs) { 6 | if (strs == null || strs.length == 0) { 7 | // bug 2: should not return null. 8 | return ""; 9 | } 10 | 11 | // Find out the shortest length. 12 | String s0 = strs[0]; 13 | int len = s0.length(); 14 | for (String s: strs) { 15 | len = Math.min(len, s.length()); 16 | } 17 | 18 | // The index of the character which is examing. 19 | // Bug 3: 当不会break的时候,结果是错的 20 | // Bug 4: forget to add int i = 0; 21 | for (int i = 0; i < len; i++) { 22 | // Bug 1: forget to write charAt(i); 23 | char c = s0.charAt(i); 24 | for (int j = 0; j < strs.length; j++) { 25 | if (strs[j].charAt(i) != c) { 26 | // Bug 5: write substring to substring 27 | return s0.substring(0, i); 28 | } 29 | } 30 | } 31 | 32 | // Never break, means strs[0].0-len is the solution. 33 | return s0.substring(0, len); 34 | } 35 | } -------------------------------------------------------------------------------- /string/Multiply.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class Multiply { 4 | public static void main(String[] strs) { 5 | multiply("9", "9"); 6 | } 7 | 8 | public static String multiply(String num1, String num2) { 9 | if (num1 == null || num2 == null) { 10 | return null; 11 | } 12 | 13 | int len1 = num1.length(); 14 | int len2 = num2.length(); 15 | 16 | int[] product = new int[len1 + len2]; 17 | 18 | // 计算相应位置的product. 19 | for (int i = 0; i < len1; i++) { 20 | for (int j = 0; j < len2; j++) { 21 | product[i + j] = (num1.charAt(len1 - 1 - i) - '0') * (num2.charAt(len2 - 1 - j) - '0'); 22 | } 23 | } 24 | 25 | StringBuilder ret = new StringBuilder(); 26 | 27 | int carry = 0; 28 | for (int i = 0; i < len1 + len2; i++) { 29 | product[i] = product[i] + carry; 30 | int digit = product[i] % 10; 31 | carry = digit / 10; 32 | ret.insert(0, digit); 33 | } 34 | 35 | while (ret.length() > 1 && ret.charAt(0) == '0') { 36 | ret.deleteCharAt(0); 37 | } 38 | 39 | return ret.toString(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /string/ReverseWords.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class ReverseWords { 4 | public static void main(String[] strs) { 5 | reverseWords(" I love cmu "); 6 | } 7 | 8 | /** 9 | * @param s : A string 10 | * @return : A string 11 | */ 12 | public static String reverseWords(String s) { 13 | // write your code 14 | if (s == null) { 15 | return null; 16 | } 17 | 18 | StringBuilder sb = new StringBuilder(); 19 | 20 | //System.out.println(s); 21 | 22 | // remove the leading and the tail space. 23 | String sTrim = s.trim(); 24 | String[] strs = sTrim.split("\\s+"); 25 | for (int i = strs.length - 1; i >= 0; i--) { 26 | System.out.println("word:" + strs[i]); 27 | if (strs[i].equals("")) { 28 | continue; 29 | } 30 | 31 | sb.append(strs[i]); 32 | if (i != 0) { 33 | sb.append(" "); 34 | } 35 | } 36 | 37 | return sb.toString(); 38 | } 39 | 40 | /** 41 | * @param s : A string 42 | * @return : A string 43 | */ 44 | public String reverseWords1(String s) { 45 | // write your code 46 | if (s == null) { 47 | return null; 48 | } 49 | 50 | StringBuilder sb = new StringBuilder(); 51 | 52 | // remove the leading and the tail space. 53 | String sTrim = s.trim(); 54 | String strs[] = sTrim.split("\\s+"); 55 | for (int i = strs.length - 1; i >= 0; i--) { 56 | sb.append(strs[i]); 57 | if (i != 0) { 58 | sb.append(" "); 59 | } 60 | } 61 | 62 | return sb.toString(); 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /string/SimplifyPath.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | import java.util.Stack; 4 | 5 | public class SimplifyPath { 6 | public static void main(String[] strs) { 7 | System.out.println(simplifyPath("//home")); 8 | } 9 | 10 | public static String simplifyPath(String path) { 11 | if (path == null || path.length() == 0) { 12 | return null; 13 | } 14 | 15 | /* 16 | path = "/home/", => "/home" --> Split to : 空格 home 17 | path = "/a/./b/../../c/", => "/c" --> splite to: 空格 a . b .. .. c 18 | */ 19 | // 注意 split的输入是一个字符串 20 | String[] strs = path.split("/"); 21 | 22 | Stack s = new Stack(); 23 | 24 | for (String str: strs) { 25 | if (str.equals("..")) { 26 | // we should pop out a element. 27 | if (!s.isEmpty()) { 28 | s.pop(); 29 | } 30 | // should skip the space and the '.' 31 | } else if (!str.equals(".") && !str.equals("")) { 32 | s.push(str); 33 | } 34 | } 35 | 36 | StringBuilder sb = new StringBuilder(); 37 | while (!s.isEmpty()) { 38 | sb.insert(0, s.pop()); 39 | sb.insert(0, '/'); 40 | } 41 | 42 | // if we get a empty string, should return / 43 | if (sb.length() ==0) { 44 | sb.append('/'); 45 | } 46 | 47 | return sb.toString(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /string/isMatch.java: -------------------------------------------------------------------------------- 1 | package Algorithms.string; 2 | 3 | public class isMatch { 4 | public boolean isMatch(String s, String p) { 5 | if (s == null || p == null) { 6 | return false; 7 | } 8 | 9 | return isMatchRec(s, p, 0, 0); 10 | } 11 | 12 | public boolean isMatchRec(String s, String p, int indexS, int indexP) { 13 | int lenS = s.length(); 14 | int lenP = p.length(); 15 | 16 | // we get to the end of the string. 17 | if (indexP == lenP) { 18 | return indexS == lenS; 19 | } 20 | 21 | // At lease 2 match character left 22 | if (indexP < lenP - 1 && p.charAt(indexP + 1) == '*') { 23 | // match 0; 24 | if (isMatchRec(s, p, indexS, indexP + 2)) { 25 | return true; 26 | } 27 | 28 | // we can match 0 or more. 29 | for (int i = indexS; i < lenS; i++) { 30 | // match once or more. 31 | if (!isMatchChar(s.charAt(i), p.charAt(indexP))) { 32 | return false; 33 | } 34 | 35 | if (isMatchRec(s, p, i + 1, indexP + 2)) { 36 | return true; 37 | } 38 | } 39 | 40 | // if any of them does not match, just return false. 41 | return false; 42 | } 43 | 44 | // match current character and the left string. 45 | return indexS < lenS 46 | && isMatchChar(s.charAt(indexS), p.charAt(indexP)) 47 | && isMatchRec(s, p, indexS + 1, indexP + 1); 48 | } 49 | 50 | public boolean isMatchChar(char s, char p) { 51 | if (p == '*') { 52 | return false; 53 | } 54 | 55 | if (s == p || p == '.') { 56 | return true; 57 | } 58 | 59 | return false; 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /tree/BuildTree.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | /** 4 | * Definition for binary tree 5 | * public class TreeNode { 6 | * int val; 7 | * TreeNode left; 8 | * TreeNode right; 9 | * TreeNode(int x) { val = x; } 10 | * } 11 | */ 12 | public class BuildTree { 13 | public static void main(String[] strs) { 14 | int[] pre = {1, 2}; 15 | int[] in = {2, 1}; 16 | 17 | buildTree(pre, in); 18 | } 19 | 20 | public static TreeNode buildTree(int[] preorder, int[] inorder) { 21 | // bug 3: consider when length is 0. 22 | if (preorder == null || inorder == null || preorder.length == 0 || preorder.length != inorder.length) { 23 | return null; 24 | } 25 | 26 | // bug 4: end index is length - 1. 27 | return buildTree(preorder, inorder, 0, preorder.length - 1, 0, preorder.length - 1); 28 | } 29 | 30 | public static TreeNode buildTree(int[] preorder, int[] inorder, int preStart, int preEnd, int inStart, int inEnd) { 31 | // base case; 32 | if (preStart > preEnd) { 33 | return null; 34 | } 35 | 36 | int rootVal = preorder[preStart]; 37 | TreeNode root = new TreeNode(rootVal); 38 | 39 | int pos = findTarget(inorder, rootVal, inStart, inEnd); 40 | 41 | // bug 5: left number is pos - instart can't add 1 42 | int leftNum = pos - inStart; 43 | 44 | root.left = buildTree(preorder, inorder, preStart + 1, preStart + leftNum, inStart, pos - 1); 45 | root.right = buildTree(preorder, inorder, preStart + leftNum + 1, preEnd, pos + 1, inEnd); 46 | 47 | return root; 48 | } 49 | 50 | // bug 1: return type required. 51 | public static int findTarget(int[] A, int target, int start, int end) { 52 | for (int i = start; i <= end; i++) { 53 | if (target == A[i]) { 54 | return i; 55 | } 56 | } 57 | 58 | return -1; 59 | } 60 | } -------------------------------------------------------------------------------- /tree/IsValidBST.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | /** 4 | * Definition for binary tree 5 | * public class TreeNode { 6 | * int val; 7 | * TreeNode left; 8 | * TreeNode right; 9 | * TreeNode(int x) { val = x; } 10 | * } 11 | */ 12 | public class IsValidBST { 13 | public boolean isValidBST(TreeNode root) { 14 | return isValidBSTHelp(root).isValidBST; 15 | } 16 | 17 | public ReturnType isValidBSTHelp(TreeNode root) { 18 | ReturnType ret = new ReturnType(Integer.MAX_VALUE, Integer.MIN_VALUE, true); 19 | if (root == null) { 20 | return ret; 21 | } 22 | 23 | ReturnType left = isValidBSTHelp(root.left); 24 | ReturnType right = isValidBSTHelp(root.right); 25 | 26 | /* the left tree and the right tree should both be Valid BST. 27 | And the value of the root should be in the middle. 28 | */ 29 | 30 | if (!left.isValidBST 31 | || !right.isValidBST 32 | || left.max >= root.val 33 | || right.min <= root.val 34 | ) { 35 | ret.isValidBST = false; 36 | return ret; 37 | } 38 | 39 | // get the min value of the tree; 40 | ret.min = Math.min(left.min, root.val); 41 | 42 | // get the max value of the tree, consider the right node may be null; 43 | ret.max = Math.max(right.max, root.val); 44 | 45 | return ret; 46 | } 47 | 48 | public class ReturnType { 49 | int min; 50 | int max; 51 | boolean isValidBST; 52 | 53 | ReturnType(int min, int max, boolean isValidBST) { 54 | this.min = min; 55 | this.max = max; 56 | this.isValidBST = isValidBST; 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /tree/LevelOrder.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | import java.util.Queue; 7 | 8 | /** 9 | * Definition for binary tree 10 | * public class TreeNode { 11 | * int val; 12 | * TreeNode left; 13 | * TreeNode right; 14 | * TreeNode(int x) { val = x; } 15 | * } 16 | */ 17 | public class LevelOrder { 18 | public List> levelOrder(TreeNode root) { 19 | List> ret = new ArrayList>(); 20 | if (root == null) { 21 | return ret; 22 | } 23 | 24 | Queue q = new LinkedList(); 25 | q.offer(root); 26 | 27 | while (!q.isEmpty()) { 28 | int size = q.size(); 29 | List list = new ArrayList(); 30 | for (int i = 0; i < size; i++) { 31 | TreeNode cur = q.poll(); 32 | list.add(cur.val); 33 | 34 | if (cur.left != null) { 35 | q.offer(cur.left); 36 | } 37 | 38 | if (cur.right != null) { 39 | q.offer(cur.right); 40 | } 41 | } 42 | 43 | ret.add(list); 44 | } 45 | 46 | return ret; 47 | } 48 | } -------------------------------------------------------------------------------- /tree/MaxPathSum.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | /** 4 | * Definition for binary tree 5 | * public class TreeNode { 6 | * int val; 7 | * TreeNode left; 8 | * TreeNode right; 9 | * TreeNode(int x) { val = x; } 10 | * } 11 | */ 12 | public class MaxPathSum { 13 | public static void main(String[] strs) { 14 | TreeNode root = new TreeNode(2); 15 | TreeNode left = new TreeNode(-1); 16 | 17 | root.left = left; 18 | 19 | System.out.println(maxPathSum(root)); 20 | } 21 | 22 | public static class ReturnType { 23 | int maxSingle; 24 | int max; 25 | ReturnType (int maxSingle, int max) { 26 | this.max = max; 27 | this.maxSingle = maxSingle; 28 | } 29 | } 30 | 31 | public static int maxPathSum(TreeNode root) { 32 | return dfs(root).max; 33 | } 34 | 35 | public static ReturnType dfs(TreeNode root) { 36 | ReturnType ret = new ReturnType(Integer.MIN_VALUE, Integer.MIN_VALUE); 37 | if (root == null) { 38 | return ret; 39 | } 40 | 41 | ReturnType left = dfs(root.left); 42 | ReturnType right = dfs(root.right); 43 | 44 | int cross = root.val; 45 | 46 | // if any of the path of left and right is below 0, don't add it. 47 | cross += Math.max(0, left.maxSingle); 48 | cross += Math.max(0, right.maxSingle); 49 | 50 | int maxSingle = root.val + Math.max(left.maxSingle, right.maxSingle); 51 | 52 | // may left.maxSingle and right.maxSingle are below 0 53 | maxSingle = Math.max(maxSingle, root.val); 54 | 55 | ret.maxSingle = maxSingle; 56 | ret.max = Math.max(right.max, left.max); 57 | ret.max = Math.max(ret.max, cross); 58 | 59 | return ret; 60 | } 61 | } -------------------------------------------------------------------------------- /tree/NumTrees.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | public class NumTrees { 4 | public int numTrees1(int n) { 5 | // cnt[n] = cnt[0]cnt[n - 1] + cnt[1]cnt[n - 2] ... cnt[n - 1]cnt[0] 6 | // cnt[n-1] = cnt[0]cnt[n - 2] + cnt[1]cnt[n - 3] ... cnt[n - 2]cnt[0] 7 | // For example: 8 | // when N = 3, 9 | // cnt[3] = cnt[0]cnt[2] + cnt[1]cnt[1] + cnt[2]cnt[1]; 10 | // so the Formula is : 11 | 12 | // F[n] = ∑ Cnt[j] * cnt[n-j-1] 0<=j<=n-1 13 | 14 | // base case: 15 | // when n = 0, cnt[0] = 1; 16 | 17 | int[] cnt = new int[n + 1]; 18 | cnt[0] = 1; 19 | 20 | for (int i = 1 ; i <= n; i++) { 21 | cnt[i] = 0; 22 | for (int j = 0; j <= i - 1; j++) { 23 | cnt[i] += cnt[j] * cnt[i - j - 1]; 24 | } 25 | } 26 | 27 | return cnt[n]; 28 | } 29 | 30 | public int numTrees(int n) { 31 | if (n == 0) { 32 | return 1; 33 | } 34 | 35 | // Get the results of all the trees which 36 | // has the root from 1 to n; 37 | int num = 0; 38 | for (int i = 0; i <= n - 1; i++) { 39 | num += numTrees(i) * numTrees(n - 1 - i); 40 | } 41 | 42 | return num; 43 | } 44 | } -------------------------------------------------------------------------------- /tree/PathSum2.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Definition for binary tree 8 | * public class TreeNode { 9 | * int val; 10 | * TreeNode left; 11 | * TreeNode right; 12 | * TreeNode(int x) { val = x; } 13 | * } 14 | */ 15 | public class PathSum2 { 16 | public List> pathSum(TreeNode root, int sum) { 17 | List> ret = new ArrayList>(); 18 | 19 | ArrayList path = new ArrayList(); 20 | 21 | pathSumHelp(root, sum, path, ret); 22 | 23 | return ret; 24 | } 25 | 26 | public void pathSumHelp(TreeNode root, int sum, ArrayList path, List> ret) { 27 | if (root == null) { 28 | return; 29 | } 30 | 31 | path.add(root.val); 32 | 33 | if (root.left == null 34 | && root.right == null 35 | && root.val == sum) { 36 | ret.add(new ArrayList(path)); 37 | } else { 38 | // 继续递归 39 | pathSumHelp(root.left, sum - root.val, path, ret); 40 | pathSumHelp(root.right, sum - root.val, path, ret); 41 | } 42 | 43 | // 注意,递归和回溯的特点就是 递归不可以改变path的值。也就是说,你返回时,这个path不能被改变 44 | // 所以在这里要执行remove操作。 45 | path.remove(path.size() - 1); 46 | } 47 | } -------------------------------------------------------------------------------- /tree/PostorderTraversal.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Stack; 6 | 7 | /** 8 | * Definition for binary tree 9 | * public class TreeNode { 10 | * int val; 11 | * TreeNode left; 12 | * TreeNode right; 13 | * TreeNode(int x) { val = x; } 14 | * } 15 | */ 16 | public class PostorderTraversal { 17 | public List postorderTraversal1(TreeNode root) { 18 | List ret = new ArrayList(); 19 | dfs(root, ret); 20 | return ret; 21 | } 22 | 23 | // Solution 1: rec 24 | public void dfs(TreeNode root, List ret) { 25 | if (root == null) { 26 | return; 27 | } 28 | 29 | dfs(root.left, ret); 30 | dfs(root.right, ret); 31 | ret.add(root.val); 32 | } 33 | 34 | // Solution 2: iterator 35 | public List postorderTraversal(TreeNode root) { 36 | List ret = new ArrayList(); 37 | if (root == null) { 38 | return ret; 39 | } 40 | 41 | Stack s = new Stack(); 42 | Stack out = new Stack(); 43 | 44 | s.push(root); 45 | 46 | while (!s.isEmpty()) { 47 | TreeNode cur = s.pop(); 48 | out.push(cur.val); 49 | 50 | if (cur.left != null) { 51 | s.push(cur.left); 52 | } 53 | 54 | if (cur.right != null) { 55 | s.push(cur.right); 56 | } 57 | } 58 | 59 | while (!out.isEmpty()) { 60 | ret.add(out.pop()); 61 | } 62 | 63 | return ret; 64 | } 65 | } -------------------------------------------------------------------------------- /tree/PreorderTraversal.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Stack; 6 | 7 | /** 8 | * Definition for binary tree 9 | * public class TreeNode { 10 | * int val; 11 | * TreeNode left; 12 | * TreeNode right; 13 | * TreeNode(int x) { val = x; } 14 | * } 15 | */ 16 | public class PreorderTraversal { 17 | // sol1: 18 | public List preorderTraversal1(TreeNode root) { 19 | List ret = new ArrayList(); 20 | 21 | rec(root, ret); 22 | return ret; 23 | } 24 | 25 | public void rec(TreeNode root, List ret) { 26 | if (root == null) { 27 | return; 28 | } 29 | 30 | ret.add(root.val); 31 | rec(root.left, ret); 32 | rec(root.right, ret); 33 | } 34 | 35 | public List preorderTraversal(TreeNode root) { 36 | List ret = new ArrayList(); 37 | 38 | if (root == null) { 39 | return ret; 40 | } 41 | 42 | Stack s = new Stack(); 43 | s.push(root); 44 | 45 | while (!s.isEmpty()) { 46 | TreeNode cur = s.pop(); 47 | ret.add(cur.val); 48 | 49 | if (cur.right != null) { 50 | s.push(cur.right); 51 | } 52 | 53 | if (cur.left != null) { 54 | s.push(cur.left); 55 | } 56 | } 57 | 58 | return ret; 59 | } 60 | } -------------------------------------------------------------------------------- /tree/SortedArrayToBST.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | /** 4 | * Definition for binary tree 5 | * public class TreeNode { 6 | * int val; 7 | * TreeNode left; 8 | * TreeNode right; 9 | * TreeNode(int x) { val = x; } 10 | * } 11 | */ 12 | public class SortedArrayToBST { 13 | public TreeNode sortedArrayToBST(int[] num) { 14 | if (num == null || num.length == 0) { 15 | return null; 16 | } 17 | 18 | return sortedArrayToBST(num, 0, num.length - 1); 19 | } 20 | 21 | public TreeNode sortedArrayToBST(int[] num, int left, int right) { 22 | // The base case: 23 | if (left > right) { 24 | return null; 25 | } 26 | 27 | int mid = left + (right - left) / 2; 28 | TreeNode root = new TreeNode(num[mid]); 29 | 30 | TreeNode leftNode = sortedArrayToBST(num, left, mid - 1); 31 | TreeNode rightNode = sortedArrayToBST(num, mid + 1, right); 32 | 33 | root.left = leftNode; 34 | root.right = rightNode; 35 | 36 | return root; 37 | } 38 | } -------------------------------------------------------------------------------- /tree/SumNumbers.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | import java.util.ArrayList; 4 | 5 | /* 6 | * 7 | * Sum Root to Leaf Numbers Total Accepted: 23940 Total Submissions: 80436 My Submissions 8 | Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. 9 | 10 | An example is the root-to-leaf path 1->2->3 which represents the number 123. 11 | 12 | Find the total sum of all root-to-leaf numbers. 13 | 14 | For example, 15 | 16 | 1 17 | / \ 18 | 2 3 19 | The root-to-leaf path 1->2 represents the number 12. 20 | The root-to-leaf path 1->3 represents the number 13. 21 | 22 | Return the sum = 12 + 13 = 25. 23 | * */ 24 | 25 | public class SumNumbers { 26 | public int sumNumbers(TreeNode root) { 27 | if (root == null) { 28 | return 0; 29 | } 30 | 31 | ArrayList ret = new ArrayList(); 32 | 33 | // 存储从根节点到当前节点的路径上的数字 34 | ArrayList path = new ArrayList(); 35 | 36 | dfs(root, path, ret); 37 | int sum = 0; 38 | for (int n: ret) { 39 | sum += n; 40 | } 41 | 42 | return sum; 43 | } 44 | 45 | public void dfs(TreeNode root, ArrayList path, ArrayList ret) { 46 | if (root == null) { 47 | return; 48 | } 49 | 50 | path.add(root.val); 51 | 52 | if (root.left == null && root.right == null) { 53 | int num = 0; 54 | for (int n: path) { 55 | num = num * 10 + n; 56 | } 57 | ret.add(num); 58 | } else { 59 | // 向左右子树递归 60 | dfs(root.left, path, ret); 61 | dfs(root.right, path, ret); 62 | } 63 | 64 | // 一定要记得回溯,也就是说递归不能修改Path本身,否则以上向左右子树分别递归时 path就会被改。 65 | path.remove(path.size() - 1); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tree/SumNumbers_1208_2014.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | /** 4 | * Definition for binary tree 5 | * public class TreeNode { 6 | * int val; 7 | * TreeNode left; 8 | * TreeNode right; 9 | * TreeNode(int x) { val = x; } 10 | * } 11 | */ 12 | public class SumNumbers_1208_2014 { 13 | public int sumNumbers(TreeNode root) { 14 | return dfs(root, 0); 15 | } 16 | 17 | public int dfs(TreeNode root, int pre) { 18 | if (root == null) { 19 | return 0; 20 | } 21 | 22 | int cur = pre * 10 + root.val; 23 | if (root.left == null && root.right == null) { 24 | return cur; 25 | } 26 | 27 | return dfs(root.left, cur) + dfs(root.right, cur); 28 | } 29 | } -------------------------------------------------------------------------------- /tree/TreeLinkNode.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | public class TreeLinkNode { 3 | int val; 4 | public TreeLinkNode left; 5 | public TreeLinkNode right; 6 | public TreeLinkNode next; 7 | public TreeLinkNode(int x) { val = x; } 8 | } -------------------------------------------------------------------------------- /tree/TreeNode.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | public class TreeNode { 4 | public int val; 5 | public TreeNode left; 6 | public TreeNode right; 7 | public TreeNode parent; 8 | 9 | public TreeNode(int x) { val = x; left = null; right = null;} 10 | 11 | public String toString() { 12 | return Integer.toString(val); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tree/hasPathSum.java: -------------------------------------------------------------------------------- 1 | package Algorithms.tree; 2 | 3 | public class HasPathSum { 4 | /** 5 | * Definition for binary tree public class TreeNode { int val; TreeNode 6 | * left; TreeNode right; TreeNode(int x) { val = x; } } 7 | */ 8 | public boolean hasPathSum(TreeNode root, int sum) { 9 | if (root == null) { 10 | return false; 11 | } 12 | 13 | if (root.left == null && root.right == null && sum == root.val) { 14 | return true; 15 | } 16 | 17 | return hasPathSum(root.left, sum - root.val) 18 | || hasPathSum(root.right, sum - root.val); 19 | } 20 | 21 | // Solution 2 22 | public boolean hasPathSum2(TreeNode root, int sum) { 23 | if (root == null) { 24 | return false; 25 | } 26 | 27 | if (root.left == null && root.right == null && root.val == sum) { 28 | return true; 29 | } 30 | 31 | sum -= root.val; 32 | 33 | return hasPathSum2(root.left, sum) || hasPathSum2(root.right, sum); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tree/readme.md: -------------------------------------------------------------------------------- 1 | Tree 2 | ================== 3 | 4 | About the Tree: 5 | full binary tree: A binary tree in which each node has exactly zero or two children. 6 | Perfect binary tree: A binary tree with all leaf nodes at the same depth. All internal nodes have degree 2 [1] 7 | 8 | The difference between Full Binary Tree & Complete Binary Tree: 9 | (1). a binary tree T is full if each node is either a leaf or possesses exactly two child nodes. 10 | (2). a binary tree T with n levels is complete if all levels except possibly the last are completely full, and the last level has all its 11 | nodes to the left side. [2] 12 | 13 | AVL Trees: AVL trees are self-balancing binary search trees. These trees are named after their two 14 | inventors G.M. Adel’son-Vel’skii and E.M. Landis. [3] 15 | 16 | The height/depth of a tree: 17 | The height of a node is the length of the longest downward path to a leaf from that node. 18 | The height of the root is the height of the tree. The depth of a node is the length of the path to its root (i.e., its root path). 19 | This is commonly needed in the manipulation of the various self-balancing trees, 20 | AVL Trees in particular. The root node has depth zero, leaf nodes have height zero, 21 | and a tree with only a single node (hence both a root and leaf) has depth and height zero. 22 | Conventionally, an empty tree (tree with no nodes, if such are allowed) has depth and height −1.[4] 23 | 24 | 25 | REF: 26 | [1] http://xlinux.nist.gov/dads//HTML/perfectBinaryTree.html 27 | [2] http://courses.cs.vt.edu/~cs3114/Fall09/wmcquain/Notes/T03a.BinaryTreeTheorems. 28 | [3] http://courses.csail.mit.edu/6.006/fall09/lecture_notes/lecture04.pdf 29 | [4] http://www.cs.cmu.edu/~adamchik/15-121/lectures/Trees/trees.html 30 | -------------------------------------------------------------------------------- /twoPoints/MaxArea.java: -------------------------------------------------------------------------------- 1 | package Algorithms.twoPoints; 2 | 3 | public class MaxArea { 4 | public int maxArea(int[] height) { 5 | if (height == null) { 6 | return 0; 7 | } 8 | 9 | int left = 0; 10 | int right = height.length - 1; 11 | int maxArea = 0; 12 | 13 | while (left < right) { 14 | int h = Math.min(height[left], height[right]); 15 | int area = h * (right - left); 16 | maxArea = Math.max(maxArea, area); 17 | 18 | if (height[left] < height[right]) { 19 | // 如果左边界比较低,尝试向右寻找更高的边界 20 | left++; 21 | } else { 22 | // 如果右边界比较低,尝试向左寻找更高的边界 23 | right--; 24 | } 25 | } 26 | 27 | return maxArea; 28 | } 29 | } --------------------------------------------------------------------------------