├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md └── src ├── AddBinary └── Solution.java ├── AddTwoNumbers └── Solution.java ├── Anagrams └── Solution.java ├── BalancedBinaryTree └── Solution.java ├── BinaryTreeInorderTraversal └── Solution.java ├── BinaryTreeLevelOrderTraversal └── Solution.java ├── BinaryTreeLevelOrderTraversalII └── Solution.java ├── BinaryTreeMaximumPathSum └── Solution.java ├── BinaryTreePostorderTraversal └── Solution.java ├── BinaryTreePreorderTraversal └── Solution.java ├── BinaryTreeZigzagLevelOrderTraversal └── Solution.java ├── ClimbingStairs └── Solution.java ├── CloneGraph └── Solution.java ├── Combinations └── Solution.java ├── ConstructBinaryTreefromInorderandPostorderTraversal └── Solution.java ├── ConstructBinaryTreefromPreorderandInorderTraversal └── Solution.java ├── ContainerWithMostWater └── Solution.java ├── ConvertSortedArraytoBinarySearchTree └── Solution.java ├── CountandSay └── Solution.java ├── DecodeWays └── Solution.java ├── DistinctSubsequences └── Solution.java ├── DivideTwoIntegers └── Solution.java ├── EditDistance └── Solution.java ├── FirstMissingPositive └── Solution.java ├── FlattenBinaryTreetoLinkedList └── Solution.java ├── FourSum └── Solution.java ├── GenerateParentheses └── Solution.java ├── ImplementstrStr └── Solution.java ├── InterleavingString └── Solution.java ├── JumpGame └── Solution.java ├── JumpGameII └── Solution.java ├── LengthofLastWord └── Solution.java ├── LetterCombinationsofaPhoneNumber └── Solution.java ├── LongestCommonPrefix └── Solution.java ├── LongestConsecutiveSequence └── Solution.java ├── LongestPalindromicSubstring └── Solution.java ├── LongestSubstringWithoutRepeatingCharacters └── Solution.java ├── LongestValidParentheses └── Solution.java ├── MaximalRectangle └── Solution.java ├── MaximumDepthofBinaryTree └── Solution.java ├── MaximumSubarray └── Solution.java ├── MedianofTwoSortedArrays └── Solution.java ├── MergeTwoSortedLists └── Solution.java ├── MergekSortedLists └── Solution.java ├── MinimumDepthofBinaryTree └── Solution.java ├── MinimumPathSum └── Solution.java ├── MinimumWindowSubstring └── Solution.java ├── PalindromeNumber └── Solution.java ├── PartitionList └── Solution.java ├── PathSum └── Solution.java ├── PathSumII └── Solution.java ├── Permutations └── Solution.java ├── PermutationsII └── Solution.java ├── PopulatingNextRightPointersinEachNode └── Solution.java ├── PopulatingNextRightPointersinEachNodeII └── Solution.java ├── PowXN └── Solution.java ├── RecoverBinarySearchTree └── Solution.java ├── RemoveDuplicatesfromSortedArray └── Solution.java ├── RemoveDuplicatesfromSortedArrayII └── Solution.java ├── RemoveElement └── Solution.java ├── RemoveNthNodeFromEndofList └── Solution.java ├── RestoreIPAddresses └── Solution.java ├── ReverseInteger └── Solution.java ├── ReverseWordsinaString └── Solution.java ├── RotateImage └── Solution.java ├── RotateList └── Solution.java ├── SameTree └── Solution.java ├── ScrambleString └── Solution.java ├── SimplifyPath └── Solution.java ├── Subsets └── Solution.java ├── SubstringwithConcatenationofAllWords └── Solution.java ├── SumRoottoLeafNumbers └── Solution.java ├── SwapNodesinPairs └── Solution.java ├── SymmetricTree └── Solution.java ├── ThreeSum └── Solution.java ├── ThreeSumClosest └── Solution.java ├── TrappingRainWater └── Solution.java ├── Triangle └── Solution.java ├── TwoSum └── Solution.java ├── UniqueBinarySearchTrees └── Solution.java ├── UniqueBinarySearchTreesII └── Solution.java ├── UniquePaths └── Solution.java ├── UniquePathsII └── Solution.java ├── ValidPalindrome └── Solution.java ├── ValidParentheses └── Solution.java ├── ValidateBinarySearchTree └── Solution.java ├── WordLadder └── Solution.java ├── WordSearch └── Solution.java ├── ZigZagConversion └── Solution.java └── commons └── datastructures ├── ListNode.java ├── TreeLinkNode.java ├── TreeNode.java └── UndirectedGraphNode.java /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | ############# 14 | ## Idea 15 | ############# 16 | .idea 17 | .idea/ 18 | *.eml 19 | *.iml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LeetCode-Java 2 | ============= 3 | 4 | LeetCode In Action (Java) 5 | 6 | #Langauge Level 7 | Java 8 8 | 9 | #Verbosity 10 | Java is more verbose than Python. Verbosity is not a elegant thing in Algorithm. 11 | This code is extremely verbose: [Triangle Path](https://github.com/algorhythms/LeetCode-Java/blob/master/src/Triangle/Solution.java) 12 | 13 | #Test 14 | Better to manual debug. 15 | Alternatively, feed `-ea` to JVM to enable assertions. 16 | -------------------------------------------------------------------------------- /src/AddBinary/Solution.java: -------------------------------------------------------------------------------- 1 | package AddBinary; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/28/2015 11 | * Time: 0:17 12 | * 13 | * Given two binary strings, return their sum (also a binary string). 14 | 15 | For example, 16 | a = "11" 17 | b = "1" 18 | Return "100". 19 | */ 20 | public class Solution { 21 | /** 22 | * Reverse 23 | * @param a 24 | * @param b 25 | * @return 26 | */ 27 | public String addBinary(String a, String b) { 28 | List ret = new ArrayList<>(); 29 | if(a.length()>b.length()) { 30 | String t = a; a = b; b = t; 31 | } 32 | List lst_a = a.chars().map(e -> e-'0').boxed().collect(Collectors.toList()); 33 | List lst_b = b.chars().map(e -> e-'0').boxed().collect(Collectors.toList()); 34 | Collections.reverse(lst_a); 35 | Collections.reverse(lst_b); 36 | int carry = 0; 37 | for(int i=0; i 4 -> 3) + (5 -> 6 -> 4) 14 | Output: 7 -> 0 -> 8 15 | */ 16 | 17 | public class Solution { 18 | public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 19 | ListNode c1 = l1; 20 | ListNode c2 = l2; 21 | ListNode head = new ListNode(0); 22 | ListNode c = head; 23 | int carry = 0; 24 | while(c1!=null && c2!=null) { 25 | int sum = c1.val+c2.val+carry; 26 | c.val = sum%10; 27 | 28 | carry = sum/10; 29 | if(c1.next!=null||c2.next!=null||carry>0) { 30 | c.next = new ListNode(0); 31 | } 32 | c = c.next; 33 | c1 = c1.next; 34 | c2 = c2.next; 35 | } 36 | if(c2!=null) 37 | c1 = c2; 38 | 39 | while(c1!=null) { 40 | int sum = c1.val+carry; 41 | c.val = sum%10; 42 | 43 | carry = sum/10; 44 | if(c1.next!=null||carry>0) { 45 | c.next = new ListNode(0); 46 | } 47 | c = c.next; 48 | c1 = c1.next; 49 | } 50 | if(carry!=0) { 51 | c.val = carry; 52 | } 53 | 54 | return head; 55 | } 56 | } -------------------------------------------------------------------------------- /src/Anagrams/Solution.java: -------------------------------------------------------------------------------- 1 | package Anagrams; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/20/2015 8 | * Time: 11:04 9 | * Given an array of strings, return all groups of strings that are anagrams. 10 | 11 | Note: All inputs will be in lower-case. 12 | */ 13 | public class Solution { 14 | /** 15 | * Map and String manipulation 16 | * @param strs 17 | * @return need to understand what to return 18 | */ 19 | public List anagrams(String[] strs) { 20 | Map> map = new HashMap<>(); 21 | for(int i=0; i lst = new ArrayList<>(); 25 | lst.add(i); 26 | map.put(s, lst); 27 | } 28 | else { 29 | map.get(s).add(i); 30 | } 31 | } 32 | 33 | List ret = new ArrayList<>(); 34 | for(Map.Entry> e: map.entrySet()) { 35 | if(e.getValue().size()>1) { 36 | for(Integer i: e.getValue()) 37 | ret.add(strs[i]); 38 | } 39 | } 40 | return ret; 41 | } 42 | 43 | public String sort(String s) { 44 | char [] cs = s.toCharArray(); 45 | Arrays.sort(cs); 46 | return new String(cs); 47 | } 48 | } -------------------------------------------------------------------------------- /src/BalancedBinaryTree/Solution.java: -------------------------------------------------------------------------------- 1 | package BalancedBinaryTree; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/27/2015 8 | * Time: 0:10 9 | * 10 | * Given a binary tree, determine if it is height-balanced. 11 | 12 | For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of 13 | every node never differ by more than 1. 14 | */ 15 | public class Solution { 16 | /** 17 | * O(n lgn)? 18 | * Actually it is O(n) 19 | * \sum_{i=0}^{h-1} 2^i (h-i) 20 | * @param root 21 | * @return 22 | */ 23 | public boolean isBalanced_suboptimal(TreeNode root) { 24 | if(root==null) 25 | return true; 26 | int depth_l = getDepth(root.left, 0); 27 | int depth_r = getDepth(root.right, 0); 28 | if(Math.abs(depth_l-depth_r)>1) 29 | return false; 30 | return isBalanced(root.left) && isBalanced(root.right); 31 | } 32 | 33 | int getDepth(TreeNode root, int depth) { 34 | if(root==null) 35 | return depth; 36 | return Math.max(getDepth(root.left, depth+1), getDepth(root.right, depth+1)); 37 | } 38 | 39 | /** 40 | * O(n) 41 | * @param root 42 | * @return 43 | */ 44 | public boolean isBalanced(TreeNode root) { 45 | int h = getHeightIfBalanced(root); 46 | if(h==-1) 47 | return false; 48 | return true; 49 | } 50 | 51 | /** 52 | * height and balanced simultaneously 53 | * Notice: 54 | * 1. -1 for not balanced 55 | * 2. return Math.max(l, r)+1; // notice +1 56 | * @param node 57 | * @return 58 | */ 59 | int getHeightIfBalanced(TreeNode node) { 60 | if(node==null) 61 | return 0; 62 | int l = getHeightIfBalanced(node.left); 63 | int r = getHeightIfBalanced(node.right); 64 | if(l==-1 || r==-1) 65 | return -1; 66 | if(Math.abs(r-l)>1) 67 | return -1; 68 | return Math.max(l, r)+1; 69 | } 70 | } -------------------------------------------------------------------------------- /src/BinaryTreeInorderTraversal/Solution.java: -------------------------------------------------------------------------------- 1 | package BinaryTreeInorderTraversal; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | /** 10 | * User: Danyang 11 | * Date: 1/27/2015 12 | * Time: 10:21 13 | * 14 | * Given a binary tree, return the inorder traversal of its nodes' values. 15 | 16 | For example: 17 | Given binary tree {1,#,2,3}, 18 | 1 19 | \ 20 | 2 21 | / 22 | 3 23 | return [1,3,2]. 24 | 25 | Note: Recursive solution is trivial, could you do it iteratively? 26 | */ 27 | public class Solution { 28 | /** 29 | * in-order: L c R 30 | * Notice: 31 | * 1. debugging 32 | * @param root 33 | * @return 34 | */ 35 | public List inorderTraversal_complicated(TreeNode root) { 36 | List ret = new ArrayList<>(); 37 | Stack stk = new Stack<>(); 38 | if(root==null) 39 | return ret; 40 | 41 | TreeNode cur = root; 42 | while(!stk.empty() || cur!=null) { 43 | // L 44 | while(cur!=null) { 45 | stk.add(cur); 46 | cur = cur.left; 47 | } 48 | 49 | // c R 50 | while(!stk.empty()) { 51 | cur = stk.pop(); 52 | ret.add(cur.val); 53 | if(cur.right!=null) { 54 | cur = cur.right; 55 | break; 56 | } 57 | else { 58 | cur = null; 59 | } 60 | } 61 | } 62 | return ret; 63 | } 64 | 65 | /** 66 | * Flatten the loop 67 | * @param root 68 | * @return 69 | */ 70 | public List inorderTraversal(TreeNode root) { 71 | List ret = new ArrayList<>(); 72 | Stack stk = new Stack<>(); 73 | if(root==null) 74 | return ret; 75 | 76 | TreeNode cur = root; 77 | while(!stk.empty() || cur!=null) { 78 | // L 79 | while(cur!=null) { 80 | stk.add(cur); 81 | cur = cur.left; 82 | } 83 | 84 | // c R 85 | cur = stk.pop(); 86 | ret.add(cur.val); 87 | cur = cur.right; 88 | } 89 | return ret; 90 | } 91 | } -------------------------------------------------------------------------------- /src/BinaryTreeLevelOrderTraversal/Solution.java: -------------------------------------------------------------------------------- 1 | package BinaryTreeLevelOrderTraversal; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/27/2015 11 | * Time: 14:56 12 | * 13 | * Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). 14 | 15 | For example: 16 | Given binary tree {3,9,20,#,#,15,7}, 17 | 3 18 | / \ 19 | 9 20 20 | / \ 21 | 15 7 22 | return its level order traversal as: 23 | [ 24 | [3], 25 | [9,20], 26 | [15,7] 27 | ] 28 | */ 29 | public class Solution { 30 | /** 31 | * bfs 32 | * @param root 33 | * @return 34 | */ 35 | public List> levelOrder(TreeNode root) { 36 | List> ret = new ArrayList<>(); 37 | if(root==null) 38 | return ret; 39 | 40 | TreeNode cur = root; 41 | List q = new ArrayList<>(); 42 | q.add(cur); 43 | while(!q.isEmpty()) { 44 | int l = q.size(); 45 | List currentLevel = new ArrayList<>(); 46 | for(int i=0; i> levelOrderBottom(TreeNode root) { 36 | List> ret = new ArrayList<>(); 37 | List q = new ArrayList<>(); 38 | if(root==null) 39 | return ret; 40 | 41 | TreeNode cur = root; 42 | q.add(cur); 43 | while(!q.isEmpty()) { 44 | int l = q.size(); 45 | List level = new ArrayList<>(); 46 | for(int i=0; i postorderTraversal(TreeNode root) { 34 | List ret = new ArrayList<>(); 35 | Stack stk = new Stack<>(); 36 | if(root==null) 37 | return ret; 38 | stk.add(root); 39 | while(!stk.empty()) { 40 | TreeNode cur = stk.pop(); 41 | ret.add(0, cur.val); 42 | if(cur.left!=null) 43 | stk.add(cur.left); 44 | if(cur.right!=null) 45 | stk.add(cur.right); 46 | } 47 | return ret; 48 | } 49 | } -------------------------------------------------------------------------------- /src/BinaryTreePreorderTraversal/Solution.java: -------------------------------------------------------------------------------- 1 | package BinaryTreePreorderTraversal; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | /** 10 | * User: Danyang 11 | * Date: 1/27/2015 12 | * Time: 10:34 13 | * Given a binary tree, return the preorder traversal of its nodes' values. 14 | 15 | For example: 16 | Given binary tree {1,#,2,3}, 17 | 1 18 | \ 19 | 2 20 | / 21 | 3 22 | return [1,2,3]. 23 | 24 | Note: Recursive solution is trivial, could you do it iteratively? 25 | */ 26 | public class Solution { 27 | /** 28 | * Pre-order: c L R 29 | * @param root 30 | * @return 31 | */ 32 | public List preorderTraversal(TreeNode root) { 33 | Stack stk = new Stack<>(); 34 | List ret = new ArrayList<>(); 35 | if(root==null) 36 | return ret; 37 | 38 | stk.add(root); 39 | while(!stk.empty()) { 40 | TreeNode cur = stk.pop(); 41 | ret.add(cur.val); 42 | if(cur.right!=null) 43 | stk.add(cur.right); 44 | if(cur.left!=null) 45 | stk.add(cur.left); 46 | } 47 | return ret; 48 | } 49 | } -------------------------------------------------------------------------------- /src/BinaryTreeZigzagLevelOrderTraversal/Solution.java: -------------------------------------------------------------------------------- 1 | package BinaryTreeZigzagLevelOrderTraversal; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/27/2015 11 | * Time: 16:37 12 | * 13 | * Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then 14 | * right to left for the next level and alternate between). 15 | 16 | For example: 17 | Given binary tree {3,9,20,#,#,15,7}, 18 | 3 19 | / \ 20 | 9 20 21 | / \ 22 | 15 7 23 | return its zigzag level order traversal as: 24 | [ 25 | [3], 26 | [20,9], 27 | [15,7] 28 | ] 29 | */ 30 | public class Solution { 31 | /** 32 | * bfs 33 | * @param root 34 | * @return 35 | */ 36 | public List> zigzagLevelOrder(TreeNode root) { 37 | List> ret = new ArrayList<>(); 38 | List q = new ArrayList<>(); 39 | if(root==null) 40 | return ret; 41 | TreeNode cur = root; 42 | q.add(cur); 43 | boolean obverse = true; 44 | while(!q.isEmpty()) { 45 | int l = q.size(); 46 | List level = new ArrayList<>(); 47 | for(int i=0; i=3) { 30 | int t = b; 31 | b = a+b; 32 | a = t; 33 | n--; 34 | } 35 | return b; 36 | } 37 | } -------------------------------------------------------------------------------- /src/CloneGraph/Solution.java: -------------------------------------------------------------------------------- 1 | package CloneGraph; 2 | 3 | import commons.datastructures.UndirectedGraphNode; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/27/2015 11 | * Time: 23:55 12 | * Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. 13 | */ 14 | public class Solution { 15 | public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { 16 | if(node==null) 17 | return null; 18 | Map cloned = new HashMap<>(); 19 | dfs(node, cloned); 20 | return cloned.get(node); 21 | } 22 | 23 | void dfs(UndirectedGraphNode node, Map cloned) { 24 | UndirectedGraphNode clone = new UndirectedGraphNode(node.label); 25 | cloned.put(node, clone); 26 | for(UndirectedGraphNode neighbor: node.neighbors) { 27 | if(!cloned.containsKey(neighbor)) 28 | dfs(neighbor, cloned); 29 | clone.neighbors.add(cloned.get(neighbor)); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Combinations/Solution.java: -------------------------------------------------------------------------------- 1 | package Combinations; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * User: Danyang 8 | * Date: 1/24/2015 9 | * Time: 11:05 10 | * 11 | * Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. 12 | 13 | For example, 14 | If n = 4 and k = 2, a solution is: 15 | 16 | [ 17 | [2,4], 18 | [3,4], 19 | [2,3], 20 | [1,2], 21 | [1,3], 22 | [1,4], 23 | ] 24 | */ 25 | public class Solution { 26 | /** 27 | * Notice: 28 | * 1. debug recursive 29 | * @param n 30 | * @param k 31 | * @return 32 | */ 33 | public List> combine(int n, int k) { 34 | List> ret = new ArrayList<>(); 35 | dfs(n, k, 1, new ArrayList<>(), ret); 36 | return ret; 37 | } 38 | 39 | void dfs(int n, int k, int next, List cur, List> ret) { 40 | if(cur.size()>k) 41 | return ; 42 | if(cur.size()==k) { 43 | ret.add(new ArrayList<>(cur)); 44 | return ; 45 | } 46 | for(int i=next; i<=n; i++) { 47 | cur.add(i); 48 | dfs(n, k, i+1, cur, ret); 49 | cur.remove(cur.size()-1); 50 | } 51 | } 52 | 53 | public static void main(String[] args) { 54 | List> ret = new Solution().combine(4, 2); 55 | System.out.println(ret); 56 | } 57 | } -------------------------------------------------------------------------------- /src/ConstructBinaryTreefromInorderandPostorderTraversal/Solution.java: -------------------------------------------------------------------------------- 1 | package ConstructBinaryTreefromInorderandPostorderTraversal; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/27/2015 8 | * Time: 17:10 9 | * 10 | * Given inorder and postorder traversal of a tree, construct the binary tree. 11 | 12 | Note: 13 | You may assume that duplicates do not exist in the tree. 14 | 15 | */ 16 | public class Solution { 17 | /** 18 | * inorder: L c R 19 | * postorder: L R c 20 | * @param inorder 21 | * @param postorder 22 | * @return 23 | */ 24 | public TreeNode buildTree(int[] inorder, int[] postorder) { 25 | return buildTree(inorder, 0, inorder.length, postorder, 0, postorder.length); 26 | } 27 | 28 | TreeNode buildTree(int[] in, int s1, int e1, int[] post, int s2, int e2) { 29 | if(s1>=e1 || s2>=e2) 30 | return null; 31 | TreeNode root = new TreeNode(post[e2-1]); 32 | int i; 33 | for(i=s1; i=e1 || s2>=e2) 29 | return null; 30 | TreeNode root = new TreeNode(preorder[s1]); 31 | int i = s2; 32 | for(; iheight[l]) 30 | l++; 31 | else 32 | r--; 33 | } 34 | return maxa; 35 | } 36 | } -------------------------------------------------------------------------------- /src/ConvertSortedArraytoBinarySearchTree/Solution.java: -------------------------------------------------------------------------------- 1 | package ConvertSortedArraytoBinarySearchTree; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/27/2015 8 | * Time: 16:46 9 | * 10 | * Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 11 | */ 12 | public class Solution { 13 | public TreeNode sortedArrayToBST(int[] num) { 14 | return toBST(num, 0, num.length); 15 | } 16 | 17 | TreeNode toBST(int[] num, int s, int e) { 18 | if(s>=e) 19 | return null; 20 | int m = (s+e)/2; 21 | TreeNode cur = new TreeNode(num[m]); 22 | TreeNode l = toBST(num, s, m); 23 | TreeNode r = toBST(num, m+1, e); 24 | cur.left = l; 25 | cur.right = r; 26 | return cur; 27 | } 28 | } -------------------------------------------------------------------------------- /src/CountandSay/Solution.java: -------------------------------------------------------------------------------- 1 | package CountandSay; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/28/2015 6 | * Time: 10:37 7 | * 8 | * The count-and-say sequence is the sequence of integers beginning as follows: 9 | 1, 11, 21, 1211, 111221, ... 10 | 11 | 1 is read off as "one 1" or 11. 12 | 11 is read off as "two 1s" or 21. 13 | 21 is read off as "one 2, then one 1" or 1211. 14 | Given an integer n, generate the nth sequence. 15 | 16 | Note: The sequence of integers will be represented as a string. 17 | */ 18 | public class Solution { 19 | public String countAndSay(int n) { 20 | String ret = "1"; 21 | for(int i=0; i cache = new HashMap<>(); 13 | 14 | /** 15 | * Notice: 16 | * 1. dp 17 | * @param s 18 | * @return 19 | */ 20 | public int numDecodings(String s) { 21 | if(s.length()<1) 22 | return 0; 23 | return getNumDecodings(s); 24 | } 25 | 26 | int getNumDecodings(String s) { 27 | if(s.length()<1) 28 | return 1; 29 | if(s.length()==1) 30 | if(s.equals("0")) 31 | return 0; 32 | else 33 | return 1; 34 | 35 | if(!cache.containsKey(s)) { 36 | int ways = 0; 37 | if(s.charAt(0)!='0') { 38 | ways += getNumDecodings(s.substring(1, s.length())); 39 | if(s.length()>1) { 40 | int num = Integer.parseInt(s.substring(0, 2)); 41 | if(num>0 && num<=26) 42 | ways += getNumDecodings(s.substring(2, s.length())); 43 | } 44 | } 45 | cache.put(s, ways); 46 | } 47 | return cache.get(s); 48 | } 49 | } -------------------------------------------------------------------------------- /src/DistinctSubsequences/Solution.java: -------------------------------------------------------------------------------- 1 | package DistinctSubsequences; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/28/2015 6 | * Time: 18:46 7 | * 8 | * Given a string S and a string T, count the number of distinct subsequences of T in S. 9 | 10 | A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of 11 | the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of 12 | "ABCDE" while "AEC" is not). 13 | 14 | Here is an example: 15 | S = "rabbbit", T = "rabbit" 16 | 17 | Return 3. 18 | */ 19 | public class Solution { 20 | /** 21 | * let f[i][j] represents the num of distinct subsequence of b[0..j] in a[0..i] 22 | * f[i][j] = f[i-1][j-1] + f[i-1][j] if a[i]=b[i] 23 | * = f[i-1][j] otherwise 24 | * @param S 25 | * @param T 26 | * @return 27 | */ 28 | public int numDistinct(String S, String T) { 29 | int m = S.length(); 30 | int n = T.length(); 31 | int[][] f = new int[m+1][n+1]; 32 | for(int i=0; i0 && divisor>0 || dividend<0 && divisor<0) 33 | sign = 1; 34 | 35 | // handle overflow 36 | if(divisor==1) 37 | return dividend; 38 | if(divisor==-1) 39 | if(dividend==Integer.MIN_VALUE) 40 | return Integer.MAX_VALUE; 41 | else 42 | return dividend*-1; 43 | 44 | if(dividend==Integer.MIN_VALUE){ 45 | if(divisor < 0) 46 | return divide(dividend-divisor, divisor)+1; 47 | else 48 | return divide(dividend+divisor, divisor)-1; 49 | } 50 | 51 | if(divisor==Integer.MIN_VALUE){ 52 | return dividend==divisor? 1: 0; 53 | } 54 | 55 | dividend = Math.abs(dividend); 56 | divisor = Math.abs(divisor); 57 | 58 | 59 | // main algorithm 60 | int ret = 0; 61 | while(divisor<=dividend) { // changing dividend 62 | int cur_divisor = divisor; 63 | int cur_ret = 1; 64 | while(cur_divisor<=dividend/2) { 65 | cur_divisor <<= 1; 66 | cur_ret <<= 1; 67 | } 68 | dividend -= cur_divisor; 69 | ret += cur_ret; 70 | } 71 | return ret*sign; 72 | } 73 | 74 | public static void main(String[] args) { 75 | int ret = new Solution().divide(-2147483648, -1); 76 | System.out.println(ret); 77 | } 78 | } -------------------------------------------------------------------------------- /src/EditDistance/Solution.java: -------------------------------------------------------------------------------- 1 | package EditDistance; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/26/2015 6 | * Time: 11:09 7 | * 8 | * Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation 9 | * is counted as 1 step.) 10 | 11 | You have the following 3 operations permitted on a word: 12 | 13 | a) Insert a character 14 | b) Delete a character 15 | c) Replace a character 16 | */ 17 | public class Solution { 18 | /** 19 | * from word1 to word2 20 | * f[i, j] the min distance from word1[0..i] tp word2[0..j] 21 | * if word1[i]==word2[j]: 22 | * f[i][j] = f[i-1][j-1] 23 | * 24 | * else: 25 | * delete: f[i, j] = f[i-1, j]+1 26 | * insert: f[i, j] = f[i, j-1]+1 27 | * replace f[i, j] = f[i-1, j-1]+1 28 | * 29 | * Notice: 30 | * 1. the INITIAL condition 31 | * 32 | * @param word1 33 | * @param word2 34 | * @return 35 | */ 36 | public int minDistance(String word1, String word2) { 37 | int m = word1.length(); 38 | int n = word2.length(); 39 | int[][] f = new int[m+1][n+1]; 40 | for(int j=0; j=0 && pos> fourSum(int[] num, int target) { 39 | Arrays.sort(num); 40 | Map>> sum2pairs = new HashMap<>(); 41 | for(int i=0; i pair = new ArrayList<>(); 45 | pair.add(i); 46 | pair.add(j); 47 | if(!sum2pairs.containsKey(sum)) { 48 | sum2pairs.put(sum, new ArrayList<>()); 49 | } 50 | sum2pairs.get(sum).add(pair); 51 | } 52 | } 53 | 54 | Set> ret = new HashSet<>(); 55 | for(int i=0; i pair: sum2pairs.get(sum_second)) { 61 | if(pair.get(0)>j) { 62 | ret.add(Arrays.asList(num[i], num[j], num[pair.get(0)], num[pair.get(1)])); 63 | } 64 | } 65 | } 66 | } 67 | } 68 | return ret.stream().collect(Collectors.toList()); 69 | } 70 | } -------------------------------------------------------------------------------- /src/GenerateParentheses/Solution.java: -------------------------------------------------------------------------------- 1 | package GenerateParentheses; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * User: Danyang 8 | * Date: 1/17/2015 9 | * Time: 16:29 10 | */ 11 | public class Solution { 12 | /** 13 | * Notice: 14 | * 1. reference to save space 15 | * @param n 16 | * @return 17 | */ 18 | public List generateParenthesis(int n) { 19 | List ret = new ArrayList<>(); 20 | dfs(n, 0, 0, new StringBuilder(), ret); 21 | return ret; 22 | } 23 | 24 | public void dfs(int n, int l, int r, StringBuilder cur, List ret) { 25 | if(r==n&&l==n) { 26 | ret.add(cur.toString()); 27 | return ; 28 | } 29 | if(l+1<=n) { 30 | dfs(n, l+1, r, cur.append("("), ret); 31 | cur.delete(l+r, l+r+1); 32 | } 33 | if(l<=n && r=0; 35 | 36 | int [] f = new int[A.length]; 37 | f[0] = A[0]; 38 | for(int i=1; i=A.length-1) 43 | return true; 44 | } 45 | return false; 46 | } 47 | public static void main(String[] args) { 48 | boolean ret = new Solution().canJump(new int[]{1, 0, 2}); 49 | assert ret; 50 | } 51 | } -------------------------------------------------------------------------------- /src/JumpGameII/Solution.java: -------------------------------------------------------------------------------- 1 | package JumpGameII; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/17/2015 6 | * Time: 23:50 7 | * 8 | * Given an array of non-negative integers, you are initially positioned at the first index of the array. 9 | 10 | Each element in the array represents your maximum jump length at that position. 11 | 12 | Your goal is to reach the last index in the minimum number of jumps. 13 | 14 | For example: 15 | Given array A = [2,3,1,1,4] 16 | 17 | The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.) 18 | */ 19 | public class Solution { 20 | /** 21 | * f[i] denotes the max reachable 22 | * f[i] = max(f[i-1], A[i]+i) if reachable from f[i-1] 23 | * d[i] denotes the min number of steps 24 | * d[i] = min(d[i-k]+1, d[i]) if reachable [forward] 25 | * --> d[i+k] = min(d[i]+1, d[i+k]) 26 | * 27 | * O(n^2) 28 | * @param A 29 | * @return 30 | */ 31 | public int jump_TLE(int[] A) { 32 | if(A.length==1) 33 | return A[0]>=0? 0: -1; 34 | 35 | int [] f = new int[A.length]; 36 | int [] d = new int[A.length]; 37 | f[0] = A[0]; 38 | d[0] = 0; 39 | for(int i=1; i=0? 0: -1; 67 | int f = A[0]; 68 | int l = 1; 69 | int r = f; 70 | int cnt = 1; 71 | while(f letterCombinations(String digits) { 23 | Map> map = new HashMap<>(); 24 | map.put(2, Arrays.asList("a", "b", "c")); 25 | map.put(3, Arrays.asList("d", "e", "f")); 26 | map.put(4, Arrays.asList("g", "h", "i")); 27 | map.put(5, Arrays.asList("j", "k", "l")); 28 | map.put(6, Arrays.asList("m", "n", "o")); 29 | map.put(7, Arrays.asList("p", "q", "r", "s")); 30 | map.put(8, Arrays.asList("t", "u", "v")); 31 | map.put(9, Arrays.asList("w", "x", "y", "z")); 32 | 33 | List ret = new ArrayList<>(); 34 | dfs(map, digits, "", ret); 35 | return ret; 36 | } 37 | 38 | void dfs(Map> map, String seq, String cur, List ret) { 39 | if(seq.length()==0) { 40 | ret.add(cur); 41 | return; 42 | } 43 | int d = seq.charAt(0)-'0'; 44 | for(String s: map.get(d)) { 45 | dfs(map, seq.substring(1), cur+s, ret); 46 | } 47 | } 48 | 49 | public static void main(String[] args) { 50 | List ret = new Solution().letterCombinations("23"); 51 | System.out.println(ret); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/LongestCommonPrefix/Solution.java: -------------------------------------------------------------------------------- 1 | package LongestCommonPrefix; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/17/2015 6 | * Time: 13:00 7 | * 8 | * Write a function to find the longest common prefix string amongst an array of strings. 9 | */ 10 | public class Solution { 11 | /** 12 | * Just iterate 13 | * @param strs 14 | * @return 15 | */ 16 | public String longestCommonPrefix(String[] strs) { 17 | StringBuilder sb = new StringBuilder(""); 18 | int i = 0; 19 | if(strs.length==0) 20 | return sb.toString(); 21 | 22 | while(true) { 23 | if(strs[0].length()-1 nums = new HashSet<>(); 27 | for(int i=0; i visited = new HashSet<>(); 30 | int gmax = 0; 31 | for(int i=0; i=j-1 || f[i+1][j-1]); // notice the loop order // notice the boolean short-circuiting 31 | if(f[i][j] && ml appeared = new HashSet<>(); 26 | for(; r stk = new Stack<>(); 29 | char[] cs = s.toCharArray(); 30 | for(int i=0; ij-horizontal[i+1][j+1]; l--) { 49 | height = Math.min(height, vertical[i+1][l+1]); 50 | maxa = Math.max(maxa, height*(j-l+1)); 51 | } 52 | } 53 | return maxa; 54 | } 55 | 56 | public int maximalRectangle_error(char[][] matrix) { 57 | int m = matrix.length; 58 | if(m==0) 59 | return 0; 60 | int n = matrix[0].length; 61 | if(n==0) 62 | return 0; 63 | int[][] vertical = new int[m+1][n+1]; 64 | int[][] horizontal = new int[m+1][n+1]; 65 | for(int i=1; ij-horizontal[i+1][j+1]; l--) 83 | height = Math.min(height, vertical[i+1][l+1]); 84 | for(int k=i; k>i-vertical[i+1][j+1]; k--) 85 | length = Math.min(length, horizontal[k+1][j+1]); 86 | maxa = Math.max(maxa, Math.max(horizontal[i+1][j+1]*height, vertical[i+1][j+1]*length)); // logic flaw 87 | } 88 | 89 | return maxa; 90 | } 91 | 92 | public static void main(String[] args) { 93 | int ret = new Solution().maximalRectangle(new char[][] { 94 | {'1', '1', '0', '1'}, 95 | {'1', '1', '0', '1'}, 96 | {'1', '1', '1', '1'}, 97 | 98 | }); 99 | assert ret==6; 100 | } 101 | } -------------------------------------------------------------------------------- /src/MaximumDepthofBinaryTree/Solution.java: -------------------------------------------------------------------------------- 1 | package MaximumDepthofBinaryTree; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/27/2015 8 | * Time: 15:17 9 | * 10 | * Given a binary tree, find its maximum depth. 11 | 12 | The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 13 | */ 14 | public class Solution { 15 | public int maxDepth(TreeNode root) { 16 | if(root==null) 17 | return 0; 18 | return getDepth(root, 1); 19 | } 20 | 21 | int getDepth(TreeNode cur, int depth) { 22 | if(cur==null) 23 | return Integer.MIN_VALUE; 24 | if(cur.left==null && cur.right==null) 25 | return depth; 26 | return Math.max(getDepth(cur.left, depth+1), getDepth(cur.right, depth+1)); 27 | } 28 | } -------------------------------------------------------------------------------- /src/MaximumSubarray/Solution.java: -------------------------------------------------------------------------------- 1 | package MaximumSubarray; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/22/2015 6 | * Time: 20:49 7 | * 8 | * Find the contiguous subarray within an array (containing at least one number) which has the largest sum. 9 | 10 | For example, given the array [−2,1,−3,4,−1,2,1,−5,4], 11 | the contiguous subarray [4,−1,2,1] has the largest sum = 6. 12 | 13 | More practice: 14 | If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle. 15 | 16 | */ 17 | public class Solution { 18 | /** 19 | * O(n) iterative is trivial 20 | * Divide and Conquer Approach 21 | * O(n lgn) 22 | * 1. divide in half 23 | * 2. left max sub 24 | * 3. right max sub 25 | * 4. max sub crossing the middle point 26 | * @param A 27 | * @return 28 | */ 29 | public int maxSubArray(int[] A) { 30 | return maxSubArray(A, 0, A.length); 31 | } 32 | 33 | int maxSubArray(int[] A, int s, int e) { 34 | if(s>=e) 35 | return Integer.MIN_VALUE; 36 | if(s==e-1) 37 | return A[s]; 38 | 39 | int m = (s+e)/2; 40 | int l = maxSubArray(A, s, m); 41 | int r = maxSubArray(A, m, e); 42 | int c = maxCross(A, s, e, m); 43 | return Math.max(Math.max(l, r), c); 44 | } 45 | 46 | int maxCross(int[] A, int s, int e, int m) { 47 | int max_l = A[m]; 48 | int max_r = A[m]; 49 | 50 | int acc = A[m]; 51 | for(int i=m-1; i>=s; i--) { 52 | acc += A[i]; 53 | max_l = Math.max(max_l, acc); 54 | } 55 | acc = A[m]; 56 | for(int i=m+1; iB[n/2]) { 32 | // if(k>(m+n)/2) 33 | if(k>m/2+n/2) 34 | return this.findKth(A, Arrays.copyOfRange(B, n/2+1, n), k-n/2-1); 35 | else 36 | return this.findKth(Arrays.copyOfRange(A, 0, m/2), B, k); 37 | } 38 | else { 39 | // if(k>(m+n)/2) 40 | if(k>m/2+n/2) 41 | return this.findKth(Arrays.copyOfRange(A, m/2+1, m), B, k-m/2-1); 42 | else 43 | return this.findKth(A, Arrays.copyOfRange(B, 0, n/2), k); 44 | } 45 | } 46 | 47 | public static void main(String[] args) { 48 | int [] A = {1}; 49 | int [] B = {1}; 50 | System.out.println(new Solution().findMedianSortedArrays(A, B)); 51 | } 52 | } -------------------------------------------------------------------------------- /src/MergeTwoSortedLists/Solution.java: -------------------------------------------------------------------------------- 1 | package MergeTwoSortedLists; 2 | 3 | import commons.datastructures.ListNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/20/2015 8 | * Time: 10:40 9 | * 10 | * Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. 11 | */ 12 | public class Solution { 13 | /** 14 | * Notice: 15 | * 1. importance of using pre 16 | * @param l1 17 | * @param l2 18 | * @return 19 | */ 20 | public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 21 | ListNode c1 = l1; 22 | ListNode c2 = l2; 23 | ListNode dummy = new ListNode(0); 24 | ListNode pre = dummy; 25 | while(c1!=null && c2!=null) { 26 | pre.next = new ListNode(0); 27 | ListNode c = pre.next; 28 | if(c1.val lists) { 32 | ListNode dummy = new ListNode(0); 33 | PriorityQueue pq = new PriorityQueue<>((o1, o2) -> Integer.compare(o1.val, o2.val)); 34 | for(ListNode cur: lists) { // stream may TLE 35 | if(cur!=null) 36 | pq.add(cur); 37 | } 38 | ListNode pre = dummy; 39 | while(pq.size()>0) { 40 | ListNode cur = pq.poll(); 41 | if(cur.next!=null) 42 | pq.add(cur.next); 43 | pre.next = cur; 44 | pre = pre.next; 45 | } 46 | return dummy.next; 47 | } 48 | } -------------------------------------------------------------------------------- /src/MinimumDepthofBinaryTree/Solution.java: -------------------------------------------------------------------------------- 1 | package MinimumDepthofBinaryTree; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/27/2015 8 | * Time: 15:11 9 | * 10 | * Given a binary tree, find its minimum depth. 11 | 12 | The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 13 | 14 | */ 15 | public class Solution { 16 | /** 17 | * Notice: 18 | * 1. must be leaf node 19 | * @param root 20 | * @return 21 | */ 22 | public int minDepth(TreeNode root) { 23 | if(root==null) 24 | return 0; 25 | return getDepth(root, 1); 26 | } 27 | 28 | int getDepth(TreeNode cur, int depth) { 29 | if(cur==null) 30 | return Integer.MAX_VALUE; 31 | if(cur.left==null && cur.right==null) 32 | return depth; 33 | return Math.min(getDepth(cur.left, depth+1), getDepth(cur.right, depth+1)); 34 | } 35 | } -------------------------------------------------------------------------------- /src/MinimumPathSum/Solution.java: -------------------------------------------------------------------------------- 1 | package MinimumPathSum; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/20/2015 6 | * Time: 10:51 7 | * 8 | * Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the 9 | * sum of all numbers along its path. 10 | 11 | Note: You can only move either down or right at any point in time. 12 | */ 13 | public class Solution { 14 | /** 15 | * f[i][j] represents the min path to i, j 16 | * f[i][j] = min(f[i-1][j], f[i][j-1])+grid[i][j] 17 | * @param grid 18 | * @return 19 | */ 20 | public int minPathSum(int[][] grid) { 21 | int m = grid.length; 22 | if(m==0) 23 | return 0; 24 | int n = grid[0].length; 25 | if(n==0) 26 | return 0; 27 | 28 | int[][] f = new int[m+1][n+1]; 29 | // initialize 30 | for(int i=0; i current = new HashMap<>(); 35 | Map required = new HashMap<>(); 36 | for(char c: T.toCharArray()) { 37 | current.put(c, 0); 38 | if(!required.containsKey(c)) 39 | required.put(c, 0); 40 | required.put(c, required.get(c)+1); 41 | } 42 | int min_s = -1; 43 | int min_e = S.length(); 44 | 45 | int i = 0; 46 | int j = 0; 47 | while(ij-i) { 56 | min_s = i; 57 | min_e = j; 58 | } 59 | if(current.containsKey(S.charAt(i))) { 60 | current.put(S.charAt(i), current.get(S.charAt(i))-1); 61 | } 62 | i++; 63 | } 64 | } 65 | if(min_s!=-1) 66 | return S.substring(min_s, min_e); 67 | else 68 | return ""; 69 | } 70 | 71 | boolean foundAll(Map cur, Map required) { 72 | for(Map.Entry e: cur.entrySet()) { 73 | if(e.getValue()0; i/=10) 21 | sig *= 10; 22 | sig /= 10; 23 | 24 | // for(int i=x; i>=10; i=i%(sig)/10, sig/=100) { 25 | // if(i%10!=i/sig) 26 | // return false; 27 | // } 28 | int acc = 10; 29 | for(int i=x; sig>=acc; sig/=10, acc*=10) { 30 | long l = i/sig%10; 31 | long r = i%acc/(acc/10); 32 | if(r!=l) 33 | return false; 34 | } 35 | return true; 36 | } 37 | 38 | public static void main(String[] args) { 39 | System.out.println(new Solution().isPalindrome(1000000001)); 40 | System.out.println(new Solution().isPalindrome(100031)); 41 | System.out.println(new Solution().isPalindrome(12321)); 42 | } 43 | } -------------------------------------------------------------------------------- /src/PartitionList/Solution.java: -------------------------------------------------------------------------------- 1 | package PartitionList; 2 | 3 | import commons.datastructures.ListNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/26/2015 8 | * Time: 15:26 9 | * 10 | * Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or 11 | * equal to x. 12 | 13 | You should preserve the original relative order of the nodes in each of the two partitions. 14 | 15 | For example, 16 | Given 1->4->3->2->5->2 and x = 3, 17 | return 1->2->2->4->3->5. 18 | */ 19 | public class Solution { 20 | /** 21 | * diagram 22 | * @param head 23 | * @param x 24 | * @return 25 | */ 26 | public ListNode partition(ListNode head, int x) { 27 | ListNode d1 = new ListNode(0); // dummy 28 | ListNode d2 = new ListNode(0); // dummy 29 | 30 | ListNode p1 = d1; 31 | ListNode p2 = d2; 32 | ListNode cur = head; 33 | while(cur!=null) { 34 | if(cur.val1) 27 | return true; 28 | else 29 | return false; 30 | } 31 | return dfs(cur.left, sum_cur+cur.val, sum, depth+1) || dfs(cur.right, sum_cur+cur.val, sum, depth+1); 32 | } 33 | 34 | 35 | public boolean hasPathSum(TreeNode root, int sum) { 36 | return dfs(root, sum); 37 | } 38 | 39 | /** 40 | * TreeNode val can be negative 41 | * @param c 42 | * @param remain 43 | * @return 44 | */ 45 | boolean dfs(TreeNode c, int remain) { 46 | if(c==null) 47 | return false; 48 | 49 | remain -= c.val; 50 | 51 | if(remain==0&&c.left==null&&c.right==null) 52 | return true; 53 | 54 | return dfs(c.left, remain) || dfs(c.right, remain); 55 | } 56 | } -------------------------------------------------------------------------------- /src/PathSumII/Solution.java: -------------------------------------------------------------------------------- 1 | package PathSumII; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/19/2015 11 | * Time: 19:51 12 | */ 13 | public class Solution { 14 | public List> pathSum(TreeNode root, int sum) { 15 | List> ret = new ArrayList<>(); 16 | dfs(root, new ArrayList<>(), sum, ret); 17 | return ret; 18 | } 19 | 20 | void dfs(TreeNode c, List cur, int remain, List> ret) { 21 | if(c==null) 22 | return; 23 | 24 | remain -= c.val; 25 | cur.add(c.val); 26 | if(remain==0 && c.left==null && c.right==null) { 27 | List t = new ArrayList<>(); 28 | t.addAll(cur); 29 | ret.add(t); 30 | } 31 | dfs(c.left, cur, remain, ret); 32 | dfs(c.right, cur, remain, ret); 33 | cur.remove(cur.size()-1); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Permutations/Solution.java: -------------------------------------------------------------------------------- 1 | package Permutations; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | import java.util.stream.IntStream; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/20/2015 11 | * Time: 11:35 12 | * 13 | * Given a collection of numbers, return all possible permutations. 14 | 15 | For example, 16 | [1,2,3] have the following permutations: 17 | [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. 18 | 19 | */ 20 | public class Solution { 21 | public List> permute(int[] num) { 22 | List> ret = new ArrayList<>(); 23 | dfs(IntStream.of(num).boxed().collect(Collectors.toList()), new ArrayList<>(), ret); 24 | return ret; 25 | } 26 | 27 | void dfs(List seq, List cur, List> ret) { 28 | if(seq.size()==0) 29 | ret.add(new ArrayList<>(cur)); 30 | 31 | // list manipulation is verbose 32 | for(int i=0; i next = new ArrayList<>(seq); 34 | int t = next.remove(i); 35 | cur.add(t); 36 | dfs(next, cur, ret); 37 | cur.remove(cur.size()-1); 38 | } 39 | } 40 | 41 | public static void main(String[] args) { 42 | List> ret = new Solution().permute(new int[]{0, 1}); 43 | System.out.println(ret); 44 | } 45 | } -------------------------------------------------------------------------------- /src/PermutationsII/Solution.java: -------------------------------------------------------------------------------- 1 | package PermutationsII; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | import java.util.stream.IntStream; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/22/2015 11 | * Time: 19:59 12 | * Given a collection of numbers that might contain duplicates, return all possible unique permutations. 13 | 14 | For example, 15 | [1,1,2] have the following unique permutations: 16 | [1,1,2], [1,2,1], and [2,1,1]. 17 | */ 18 | public class Solution { 19 | public List> permuteUnique(int[] num) { 20 | List seq = IntStream.of(num).boxed().sorted().collect(Collectors.toList()); 21 | List> ret = new ArrayList<>(); 22 | dfs(seq, new ArrayList<>(), ret); 23 | return ret; 24 | } 25 | 26 | void dfs(List seq, List cur, List> ret) { 27 | if(seq.size()==0) 28 | ret.add(new ArrayList<>(cur)); 29 | 30 | for(int i=0; i=0 && seq.get(i-1)==seq.get(i)) // jump 32 | continue; 33 | List next = new ArrayList<>(seq); 34 | Integer t = next.remove(i); 35 | cur.add(t); 36 | dfs(next, cur, ret); 37 | cur.remove(cur.size()-1); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/PopulatingNextRightPointersinEachNode/Solution.java: -------------------------------------------------------------------------------- 1 | package PopulatingNextRightPointersinEachNode; 2 | 3 | import commons.datastructures.TreeLinkNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/27/2015 8 | * Time: 21:49 9 | * 10 | * Given a binary tree 11 | 12 | Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be 13 | set to NULL. 14 | 15 | Initially, all next pointers are set to NULL. 16 | 17 | Note: 18 | 19 | You may only use constant extra space. 20 | You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two 21 | children). 22 | For example, 23 | Given the following perfect binary tree, 24 | 1 25 | / \ 26 | 2 3 27 | / \ / \ 28 | 4 5 6 7 29 | After calling your function, the tree should look like: 30 | 1 -> NULL 31 | / \ 32 | 2 -> 3 -> NULL 33 | / \ / \ 34 | 4->5->6->7 -> NULL 35 | */ 36 | public class Solution { 37 | /** 38 | * bfs is trivial 39 | * but require constant space thus can only dfs 40 | * 41 | * 42 | * Algorithm: 43 | * Since full binary tree, it relies on parent's next 44 | * 45 | * Notice: 46 | * 1. pre-order recursive traversal can be converted to iterative 47 | * 2. keep as few iterators as possible 48 | * @param root 49 | */ 50 | public void connect_recur(TreeLinkNode root) { 51 | if(root==null) 52 | return; 53 | if(root.left!=null) 54 | root.left.next = root.right; 55 | if(root.right!=null && root.next!=null) 56 | root.right.next = root.next.left; 57 | connect_recur(root.left); 58 | connect_recur(root.right); 59 | } 60 | 61 | public void connect(TreeLinkNode root) { 62 | if(root==null) 63 | return ; 64 | for(TreeLinkNode p=root; p!=null; p=p.left ) { // vertical 65 | for(TreeLinkNode cur=p; cur!=null; cur=cur.next) { // horizontal 66 | if(cur.left!=null) 67 | cur.left.next = cur.right; 68 | if(cur.right!=null && cur.next!=null) 69 | cur.right.next = cur.next.left; 70 | } 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /src/PopulatingNextRightPointersinEachNodeII/Solution.java: -------------------------------------------------------------------------------- 1 | package PopulatingNextRightPointersinEachNodeII; 2 | 3 | import commons.datastructures.TreeLinkNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/27/2015 8 | * Time: 22:51 9 | * Follow up for problem "Populating Next Right Pointers in Each Node". 10 | 11 | What if the given tree could be any binary tree? Would your previous solution still work? 12 | 13 | Note: 14 | 15 | You may only use constant extra space. 16 | For example, 17 | Given the following binary tree, 18 | 1 19 | / \ 20 | 2 3 21 | / \ \ 22 | 4 5 7 23 | After calling your function, the tree should look like: 24 | 1 -> NULL 25 | / \ 26 | 2 -> 3 -> NULL 27 | / \ \ 28 | 4-> 5 -> 7 -> NULL 29 | */ 30 | public class Solution { 31 | /** 32 | * more handling than Populating Next Right Pointers in Each Node 33 | * 34 | * Notice: 35 | * 1. must go to right sub-tree first; consider the example - bottom level only have two nodes: leftmost and rightmost 36 | * 2. recursive solution can be converted to iterative solution 37 | * 3. Is iterative solution not affected by traversing right subtree first as in recursive solution? Need 38 | * modification of the way of going to next level. 39 | * @param root 40 | */ 41 | public void connect_recur(TreeLinkNode root) { 42 | if(root==null) 43 | return; 44 | if(root.left!=null) { 45 | if(root.right!=null) 46 | root.left.next = root.right; 47 | else 48 | root.left.next = getNextParentNextChild(root); 49 | } 50 | if(root.right!=null) { 51 | root.right.next = getNextParentNextChild(root); 52 | } 53 | 54 | connect_recur(root.right); 55 | connect_recur(root.left); 56 | } 57 | 58 | TreeLinkNode getNextParentNextChild(TreeLinkNode p) { 59 | p = p.next; 60 | while(p!=null) { 61 | if(p.left!=null) 62 | return p.left; 63 | else if(p.right!=null) 64 | return p.right; 65 | p = p.next; 66 | } 67 | return null; 68 | } 69 | 70 | public void connect(TreeLinkNode root) { 71 | if(root==null) 72 | return; 73 | for(TreeLinkNode p=root; p!=null; p=nextLevel(p)) { 74 | for(TreeLinkNode c=p; c!=null; c=c.next) { 75 | if(c.left!=null) 76 | if(c.right!=null) 77 | c.left.next = c.right; 78 | else 79 | c.left.next = getNextParentNextChild(c); 80 | if(c.right!=null) 81 | c.right.next = getNextParentNextChild(c); 82 | } 83 | } 84 | } 85 | 86 | TreeLinkNode nextLevel(TreeLinkNode p) { 87 | while(p!=null) { 88 | if(p.left!=null) 89 | return p.left; 90 | if(p.right!=null) 91 | return p.right; 92 | p = p.next; 93 | } 94 | return null; 95 | } 96 | } -------------------------------------------------------------------------------- /src/PowXN/Solution.java: -------------------------------------------------------------------------------- 1 | package PowXN; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/22/2015 6 | * Time: 20:11 7 | * 8 | * Implement pow(x, n). 9 | */ 10 | public class Solution { 11 | /** 12 | * classical quick power algorithm 13 | * Notice 14 | * 1. walk through the steps of algorithm 15 | * 2. x<0 case, n<0 case 16 | * @param x 17 | * @param n 18 | * @return 19 | */ 20 | public double pow(double x, int n) { 21 | if(n==0) 22 | return 1; 23 | 24 | int sign = x>0 || (n&1)==0 ? 1: -1; // common bugs 25 | boolean inverted = n <= 0; 26 | x = Math.abs(x); 27 | n = Math.abs(n); 28 | 29 | 30 | double ret = 1; 31 | double fac = x; 32 | while(n>1) { 33 | if((n&1)==1) 34 | ret *= fac; 35 | fac *= fac; 36 | n /= 2; 37 | } 38 | ret *= fac; 39 | ret *= sign; 40 | if(inverted) 41 | ret = 1/ret; 42 | return ret; 43 | } 44 | } -------------------------------------------------------------------------------- /src/RecoverBinarySearchTree/Solution.java: -------------------------------------------------------------------------------- 1 | package RecoverBinarySearchTree; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/27/2015 11 | * Time: 21:30 12 | * 13 | * Two elements of a binary search tree (BST) are swapped by mistake. 14 | 15 | Recover the tree without changing its structure. 16 | 17 | Note: 18 | A solution using O(n) space is pretty straight forward. Could you devise a constant space solution? 19 | 20 | */ 21 | public class Solution { 22 | List pair = new ArrayList<>(); // O(2) 23 | TreeNode cur; 24 | TreeNode pre; 25 | /** 26 | * Flatten to In-order array to do the analysis 27 | * Global pointers 28 | * Notice: 29 | * 1. pointers 30 | * 2. case when the 2 swapped are neighbor in in-order array 31 | * 3. case when the 2 swapped are not neighbor in in-order array 32 | * @param root 33 | */ 34 | public void recoverTree(TreeNode root) { 35 | inorder(root); 36 | assert pair.size()==2; 37 | int t = pair.get(0).val; 38 | pair.get(0).val = pair.get(1).val; 39 | pair.get(1).val = t; 40 | } 41 | 42 | void inorder(TreeNode c) { 43 | if(c==null) 44 | return ; 45 | inorder(c.left); 46 | pre = cur; 47 | cur = c; 48 | if(pre != null) { 49 | if(pre.val>cur.val) { 50 | if(pair.size()==0) { 51 | pair.add(pre); 52 | pair.add(cur); 53 | } 54 | else { 55 | pair.remove(pair.size()-1); 56 | pair.add(cur); 57 | } 58 | assert pair.size()==2; 59 | } 60 | } 61 | inorder(c.right); 62 | } 63 | } -------------------------------------------------------------------------------- /src/RemoveDuplicatesfromSortedArray/Solution.java: -------------------------------------------------------------------------------- 1 | package RemoveDuplicatesfromSortedArray; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/26/2015 6 | * Time: 11:55 7 | * 8 | * Given a sorted array, remove the duplicates in place such that each element appear only once and return the new 9 | * length. 10 | 11 | Do not allocate extra space for another array, you must do this in place with constant memory. 12 | 13 | For example, 14 | Given input array A = [1,1,2], 15 | 16 | Your function should return length = 2, and A is now [1,2]. 17 | */ 18 | public class Solution { 19 | /** 20 | * Two Pointers 21 | * @param A 22 | * @return 23 | */ 24 | public int removeDuplicates(int[] A) { 25 | if(A.length==0) 26 | return 0; 27 | int i = 0; 28 | int j = 1; 29 | for(; i2->3->4->5, and n = 2. 15 | 16 | After removing the second node from the end, the linked list becomes 1->2->3->5. 17 | Note: 18 | Given n will always be valid. 19 | Try to do this in one pass. 20 | 21 | */ 22 | 23 | public class Solution { 24 | public ListNode removeNthFromEnd(ListNode head, int n) { 25 | int l = getLength(head); 26 | int pos = l-n; 27 | if(pos<0) 28 | return head; 29 | ListNode dummy = new ListNode(0); 30 | dummy.next = head; 31 | 32 | ListNode pre = dummy; 33 | int i = 0; 34 | while(pre.next!=null) { 35 | ListNode cur = pre.next; 36 | if(i==pos) { 37 | pre.next = cur.next; 38 | break; 39 | } 40 | pre = pre.next; 41 | i++; 42 | } 43 | return dummy.next; 44 | } 45 | 46 | int getLength(ListNode head) { 47 | ListNode cur = head; 48 | int cnt = 0; 49 | while(cur!=null) { 50 | cnt++; 51 | cur = cur.next; 52 | } 53 | return cnt; 54 | } 55 | } -------------------------------------------------------------------------------- /src/RestoreIPAddresses/Solution.java: -------------------------------------------------------------------------------- 1 | package RestoreIPAddresses; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * User: Danyang 9 | * Date: 1/28/2015 10 | * Time: 10:58 11 | * 12 | * Given a string containing only digits, restore it by returning all possible valid IP address combinations. 13 | 14 | For example: 15 | Given "25525511135", 16 | 17 | return ["255.255.11.135", "255.255.111.35"]. (Order does not matter) 18 | */ 19 | public class Solution { 20 | /** 21 | * Notice: 22 | * 1. zero heading 23 | * @param s 24 | * @return 25 | */ 26 | public List restoreIpAddresses(String s) { 27 | List ret = new ArrayList<>(); 28 | dfs(s, 4, new ArrayList<>(), ret); 29 | return ret; 30 | } 31 | 32 | void dfs(String seq, int n, List cur, List ret) { 33 | if(n==0) { 34 | if(seq.length()==0) 35 | ret.add(cur.stream().collect(Collectors.joining("."))); 36 | } 37 | else { 38 | for(int i=1; i<=seq.length() && i<=3; i++) { 39 | String sub = seq.substring(0, i); 40 | if(isValidSegment(sub)) { 41 | cur.add(sub); 42 | dfs(seq.substring(i, seq.length()), n-1, cur, ret); 43 | cur.remove(cur.size()-1); 44 | } 45 | } 46 | } 47 | 48 | } 49 | 50 | boolean isValidSegment(String s) { 51 | if(s.length()>3 || s.length()<1) 52 | return false; 53 | if(s.length()>1 && s.charAt(0)=='0') 54 | return false; 55 | if(Integer.parseInt(s)>255) 56 | return false; 57 | return true; 58 | } 59 | 60 | public static void main(String[] args) { 61 | List ret = new Solution().restoreIpAddresses("25525511135"); 62 | System.out.println(ret); 63 | } 64 | } -------------------------------------------------------------------------------- /src/ReverseInteger/Solution.java: -------------------------------------------------------------------------------- 1 | package ReverseInteger; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/15/2015 6 | * Time: 12:17 7 | * Reverse digits of an integer. 8 | Example1: x = 123, return 321 9 | Example2: x = -123, return -321 10 | */ 11 | public class Solution { 12 | /** 13 | * OVERFLOW 14 | * @param x 15 | * @return 16 | */ 17 | public int reverse(int x) { 18 | int sign = x>0? 1: -1; 19 | x *= sign; 20 | int ret = 0; 21 | while(x>0) { 22 | ret *= 10; 23 | if(ret<0 || x>10&&ret*10/10!=ret) // overflow 24 | return 0; 25 | 26 | ret += x%10; 27 | x /= 10; 28 | } 29 | return ret*sign; 30 | } 31 | 32 | public static void main(String[] args) { 33 | assert new Solution().reverse(-2147483412)==-2147483412; 34 | } 35 | } -------------------------------------------------------------------------------- /src/ReverseWordsinaString/Solution.java: -------------------------------------------------------------------------------- 1 | package ReverseWordsinaString; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/28/2015 11 | * Time: 12:19 12 | * 13 | * Given an input string, reverse the string word by word. 14 | 15 | For example, 16 | Given s = "the sky is blue", 17 | return "blue is sky the". 18 | */ 19 | public class Solution { 20 | public String reverseWords(String s) { 21 | List lst = Arrays.asList(s.trim().split("\\s+")); 22 | Collections.reverse(lst); 23 | return lst.stream().collect(Collectors.joining(" ")); 24 | } 25 | } -------------------------------------------------------------------------------- /src/RotateImage/Solution.java: -------------------------------------------------------------------------------- 1 | package RotateImage; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/19/2015 6 | * Time: 11:08 7 | * You are given an n x n 2D matrix representing an image. 8 | 9 | Rotate the image by 90 degrees (clockwise). 10 | */ 11 | public class Solution { 12 | /** 13 | * Drawing 14 | * flip horizontally 15 | * fli diagonally (left top to bottom right) 16 | * @param matrix 17 | */ 18 | public void rotate(int[][] matrix) { 19 | int m = matrix.length; 20 | if(m<=0) 21 | return ; 22 | int n = matrix[0].length; 23 | if(n<=0 || n!=m) 24 | return ; 25 | 26 | for(int i=0; i2->3->4->5->NULL and k = 2, 14 | return 4->5->1->2->3->NULL. 15 | */ 16 | public class Solution { 17 | /** 18 | * LinkedList, diagram 19 | * Notice: 20 | * 1. n = n%l; 21 | * @param head 22 | * @param n 23 | * @return 24 | */ 25 | public ListNode rotateRight(ListNode head, int n) { 26 | ListNode dummy = new ListNode(0); 27 | dummy.next = head; 28 | ListNode pre = dummy; 29 | 30 | int cnt = 0; 31 | int l = getLength(head); 32 | if(l==0) 33 | return head; 34 | n = n%l; 35 | ListNode pre_br = new ListNode(0); 36 | ListNode last = new ListNode(0); 37 | while(pre.next!=null) { 38 | cnt++; 39 | if(cnt==l-n) 40 | pre_br = pre.next; 41 | pre = pre.next; 42 | if(pre.next==null) 43 | last = pre; 44 | } 45 | 46 | last.next = dummy.next; 47 | dummy.next = pre_br.next; 48 | pre_br.next = null; 49 | return dummy.next; 50 | } 51 | 52 | int getLength(ListNode head) { 53 | ListNode cur = head; 54 | int l = 0; 55 | while(cur!=null) { 56 | l++; 57 | cur = cur.next; 58 | } 59 | return l; 60 | } 61 | } -------------------------------------------------------------------------------- /src/SameTree/Solution.java: -------------------------------------------------------------------------------- 1 | package SameTree; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/18/2015 8 | * Time: 13:23 9 | */ 10 | public class Solution { 11 | public boolean isSameTree(TreeNode p, TreeNode q) { 12 | if(!equal(p, q)) 13 | return false; 14 | if(q!=null && p!=null && (!isSameTree(p.left, q.left) || !isSameTree(p.right, q.right))) 15 | return false; 16 | return true; 17 | } 18 | 19 | boolean equal(TreeNode p, TreeNode q) { 20 | if(p==null && q==null) 21 | return true; 22 | if(p!=null && q!=null && p.val==q.val) 23 | return true; 24 | return false; 25 | } 26 | } -------------------------------------------------------------------------------- /src/ScrambleString/Solution.java: -------------------------------------------------------------------------------- 1 | package ScrambleString; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * User: Danyang 8 | * Date: 1/28/2015 9 | * Time: 19:06 10 | * 11 | * Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively. 12 | 13 | Below is one possible representation of s1 = "great": 14 | 15 | great 16 | / \ 17 | gr eat 18 | / \ / \ 19 | g r e at 20 | / \ 21 | a t 22 | To scramble the string, we may choose any non-leaf node and swap its two children. 23 | 24 | For example, if we choose the node "gr" and swap its two children, it produces a scrambled string "rgeat". 25 | 26 | rgeat 27 | / \ 28 | rg eat 29 | / \ / \ 30 | r g e at 31 | / \ 32 | a t 33 | We say that "rgeat" is a scrambled string of "great". 34 | 35 | Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string "rgtae". 36 | 37 | rgtae 38 | / \ 39 | rg tae 40 | / \ / \ 41 | r g ta e 42 | / \ 43 | t a 44 | We say that "rgtae" is a scrambled string of "great". 45 | 46 | Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1. 47 | */ 48 | public class Solution { 49 | /** 50 | * Algorithm: recursive 51 | * treat as set of chars 52 | * partition the string 53 | * 54 | * Notice: 55 | * 1. prune, otherwise TLE 56 | * @param s1 57 | * @param s2 58 | * @return 59 | */ 60 | public boolean isScramble(String s1, String s2) { 61 | if(s1.equals(s2)) 62 | return true; 63 | if(!relaxedEqual(s1, s2)) 64 | return false; 65 | 66 | for(int l=1; l bucket = new HashMap<>(); 77 | for(char c: s1.toCharArray()) { 78 | if(!bucket.containsKey(c)) 79 | bucket.put(c, 0); 80 | bucket.put(c, bucket.get(c)+1); 81 | } 82 | for(char c: s2.toCharArray()) { 83 | if(!bucket.containsKey(c) || bucket.get(c)<1) 84 | return false; 85 | bucket.put(c, bucket.get(c)-1); 86 | } 87 | for(Map.Entry e: bucket.entrySet()) { 88 | if(e.getValue()!=0) 89 | return false; 90 | } 91 | return true; 92 | } 93 | } -------------------------------------------------------------------------------- /src/SimplifyPath/Solution.java: -------------------------------------------------------------------------------- 1 | package SimplifyPath; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/28/2015 11 | * Time: 12:31 12 | * Given an absolute path for a file (Unix-style), simplify it. 13 | 14 | For example, 15 | path = "/home/", => "/home" 16 | path = "/a/./b/../../c/", => "/c" 17 | */ 18 | public class Solution { 19 | public String simplifyPath(String path) { 20 | List lst = Arrays.asList(path.split("/")); 21 | List stk = new ArrayList<>(); 22 | for(String elt: lst) { 23 | if(elt.equals(".")) { 24 | continue; 25 | } 26 | else if(elt.equals("..")) { 27 | if(!stk.isEmpty()) 28 | stk.remove(stk.size()-1); 29 | } 30 | else if(elt.length()>0) { 31 | stk.add(elt); 32 | } 33 | } 34 | return "/"+stk.stream().collect(Collectors.joining("/")); 35 | } 36 | 37 | public static void main(String[] args) { 38 | String ret = new Solution().simplifyPath("/.."); 39 | assert ret.equals("/"); 40 | } 41 | } -------------------------------------------------------------------------------- /src/Subsets/Solution.java: -------------------------------------------------------------------------------- 1 | package Subsets; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | /** 8 | * User: Danyang 9 | * Date: 1/26/2015 10 | * Time: 13:51 11 | * 12 | * Given a set of distinct integers, S, return all possible subsets. 13 | 14 | Note: 15 | Elements in a subset must be in non-descending order. 16 | The solution set must not contain duplicate subsets. 17 | For example, 18 | If S = [1,2,3], a solution is: 19 | 20 | [ 21 | [3], 22 | [1], 23 | [2], 24 | [1,2,3], 25 | [1,3], 26 | [2,3], 27 | [1,2], 28 | [] 29 | ] 30 | */ 31 | public class Solution { 32 | /** 33 | * Tree 34 | * Notice: 35 | * 1. add at leaves 36 | * @param S 37 | * @return 38 | */ 39 | public List> subsets(int[] S) { 40 | Arrays.sort(S); 41 | List> ret = new ArrayList<>(); 42 | dfs(S, 0, new ArrayList<>(), ret); 43 | return ret; 44 | } 45 | 46 | void dfs(int[] S, int i, List cur, List> ret) { 47 | if(i==S.length) 48 | ret.add(new ArrayList<>(cur)); 49 | if(i findSubstring(String S, String[] L) { 37 | List ret = new ArrayList<>(); 38 | if(L.length<1 || S.length()<1) 39 | return ret; 40 | 41 | Map Lmap_origin = Stream.of(L).collect( 42 | Collectors.groupingBy(e -> e, Collectors.counting()) 43 | ); 44 | 45 | Map Lmap = new HashMap<>(Lmap_origin); // copy constructor 46 | List workingWin = new ArrayList<>(); 47 | 48 | int i = 0; 49 | int k = L[0].length(); 50 | int win_e = -1; 51 | while(i(Lmap_origin); 60 | } 61 | } 62 | 63 | 64 | String word = S.substring(i, Math.min(i+k, S.length())); 65 | if(!Lmap.containsKey(word)) { 66 | if(workingWin.isEmpty()) 67 | i++; 68 | else 69 | i = win_e-workingWin.size()*k+1; 70 | workingWin.clear(); 71 | win_e = -1; 72 | Lmap = new HashMap<>(Lmap_origin); 73 | } 74 | else if(Lmap.get(word)>0) { // found remain 75 | win_e = i+k; 76 | Lmap.put(word, Lmap.get(word)-1); 77 | workingWin.add(word); 78 | i = win_e; 79 | } 80 | else { 81 | int indexOf = workingWin.indexOf(word); 82 | for(int j=0; j<=indexOf; j++) { 83 | String word2 = workingWin.get(j); 84 | Lmap.put(word2, Lmap.get(word2)+1); 85 | } 86 | win_e = i+k; 87 | Lmap.put(word, Lmap.get(word)-1); 88 | workingWin = workingWin.subList(indexOf+1, workingWin.size()); 89 | workingWin.add(word); 90 | i = win_e; 91 | } 92 | } 93 | if(workingWin.size()==L.length) // when reaching end: test case Input: "a", ["a"] 94 | ret.add(win_e-workingWin.size()*k); 95 | return ret; 96 | } 97 | 98 | public static void main(String[] args) { 99 | List ret = new Solution().findSubstring("aaaaaaaa", new String[]{"aa", "aa", "aa"}); 100 | List expected = Arrays.asList(new Integer[]{0, 1, 2}); 101 | assert ret.equals(expected); 102 | } 103 | } -------------------------------------------------------------------------------- /src/SumRoottoLeafNumbers/Solution.java: -------------------------------------------------------------------------------- 1 | package SumRoottoLeafNumbers; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/27/2015 11 | * Time: 15:22 12 | * 13 | * Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. 14 | 15 | An example is the root-to-leaf path 1->2->3 which represents the number 123. 16 | 17 | Find the total sum of all root-to-leaf numbers. 18 | 19 | For example, 20 | 21 | 1 22 | / \ 23 | 2 3 24 | The root-to-leaf path 1->2 represents the number 12. 25 | The root-to-leaf path 1->3 represents the number 13. 26 | 27 | Return the sum = 12 + 13 = 25. 28 | */ 29 | public class Solution { 30 | public int sumNumbers(TreeNode root) { 31 | List ret = new ArrayList<>(); 32 | dfs(root, 0, ret); 33 | return ret.stream().mapToInt(e->e).sum(); 34 | } 35 | 36 | void dfs(TreeNode c, int cur, List ret) { 37 | if(c==null) 38 | return ; 39 | cur = cur*10+c.val; 40 | if(c.right==null && c.left==null) 41 | ret.add(cur); 42 | if(c.right!=null) dfs(c.right, cur, ret); 43 | if(c.left!=null) dfs(c.left, cur, ret); 44 | } 45 | } -------------------------------------------------------------------------------- /src/SwapNodesinPairs/Solution.java: -------------------------------------------------------------------------------- 1 | package SwapNodesinPairs; 2 | 3 | import commons.datastructures.ListNode; 4 | 5 | 6 | /** 7 | * User: Danyang 8 | * Date: 1/17/2015 9 | * Time: 21:15 10 | */ 11 | public class Solution { 12 | /** 13 | * Draw a diagram 14 | * @param head 15 | * @return 16 | */ 17 | public ListNode swapPairs(ListNode head) { 18 | ListNode dummy = new ListNode(0); 19 | dummy.next = head; 20 | ListNode pre = dummy; 21 | while(pre.next!=null && pre.next.next!=null) { 22 | ListNode cur = pre.next; 23 | ListNode next = cur.next; 24 | ListNode nextNext = next.next; 25 | 26 | pre.next = next; 27 | next.next = cur; 28 | cur.next = nextNext; 29 | pre = pre.next.next; 30 | } 31 | return dummy.next; 32 | } 33 | } -------------------------------------------------------------------------------- /src/SymmetricTree/Solution.java: -------------------------------------------------------------------------------- 1 | package SymmetricTree; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/19/2015 8 | * Time: 19:21 9 | * 10 | * Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). 11 | */ 12 | public class Solution { 13 | /** 14 | * iterative: bfs, array sysmetric 15 | * recursive: drawing the tree 16 | * 1 17 | * 2 2 18 | * 3 4 4 3 19 | * 5 6 7 88 7 6 5 20 | * @param root 21 | * @return 22 | */ 23 | public boolean isSymmetric(TreeNode root) { 24 | if(root==null) 25 | return true; 26 | return isSymmetric(root.left, root.right); 27 | } 28 | 29 | boolean isSymmetric(TreeNode l, TreeNode r) { 30 | if(l==null&&r==null) 31 | return true; 32 | try { 33 | return l.val==r.val && isSymmetric(l.left, r.right) && isSymmetric(l.right, r.left); 34 | } 35 | catch(Exception e) { 36 | return false; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/ThreeSum/Solution.java: -------------------------------------------------------------------------------- 1 | package ThreeSum; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | /** 8 | * User: Danyang 9 | * Date: 1/17/2015 10 | * Time: 13:10 11 | * 12 | * Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in 13 | * the array which gives the sum of zero. 14 | 15 | Note: 16 | Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c) 17 | The solution set must not contain duplicate triplets. 18 | For example, given array S = {-1 0 1 2 -1 -4}, 19 | 20 | A solution set is: 21 | (-1, 0, 1) 22 | (-1, -1, 2) 23 | */ 24 | public class Solution { 25 | /** 26 | * Two Pointers 27 | * You need to ask a lots of questions 28 | * Notice: 29 | * 1. jump 30 | * 2. don't box num 31 | * 32 | * @param num 33 | * @return 34 | */ 35 | public List> threeSum(int[] num) { 36 | List> ret = new ArrayList<>(); 37 | Arrays.sort(num); 38 | int n = num.length; 39 | for(int i=0; i=0&&A.get(k)==A.get(k+1)) 49 | while(j0) 56 | k--; 57 | else 58 | j++; 59 | } 60 | i++; 61 | while(iMath.abs(sum-target)) 35 | sum_min = sum; 36 | 37 | if(sum==target) { 38 | return target; 39 | } 40 | else if(sum>target) 41 | k--; 42 | else 43 | j++; 44 | } 45 | i++; 46 | while(i-1; i--) 37 | max_r[i] = Math.max(max_r[i+1], A[i]); 38 | 39 | int ret = 0; 40 | for(int i=1; i> triangle) { 35 | List> f = triangle.stream() 36 | .map(e -> e.stream().map(e2->0).collect(Collectors.toList())) 37 | .collect(Collectors.toList()); 38 | for(int i=0; i-1; i--) { 42 | for(int j=0; j map = new HashMap<>(); 26 | for(int i=0; i generateTrees(int n) { 28 | return getSubs(1, n+1); 29 | } 30 | 31 | 32 | List getSubs(int l, int r) { 33 | List ret = new ArrayList<>(); 34 | if(l>=r) 35 | ret.add(null); 36 | else { 37 | for(int i=l; i subs_l = getSubs(l, i); 39 | List subs_r = getSubs(i+1, r); 40 | for(TreeNode sub_l: subs_l) { 41 | for (TreeNode sub_r : subs_r) { 42 | TreeNode cur = new TreeNode(i); 43 | cur.left = sub_l; 44 | cur.right = sub_r; 45 | ret.add(cur); 46 | } 47 | } 48 | } 49 | } 50 | return ret; 51 | } 52 | } -------------------------------------------------------------------------------- /src/UniquePaths/Solution.java: -------------------------------------------------------------------------------- 1 | package UniquePaths; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/19/2015 6 | * Time: 20:29 7 | * robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). 8 | 9 | The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner 10 | of the grid (marked 'Finish' in the diagram below). 11 | 12 | How many possible unique paths are there? 13 | */ 14 | public class Solution { 15 | /** 16 | * DP 17 | * f[i][j] = f[i-1][j] + f[i][j-1] 18 | * @param m 19 | * @param n 20 | * @return 21 | */ 22 | public int uniquePaths(int m, int n) { 23 | int [][] f = new int[m+1][n+1]; 24 | f[0][1] = 1; 25 | for(int i=1; i e>='a' && e<='z' || e>='0' && e<='9').toArray(); 22 | for(int i=0; i map = new HashMap<>(); 25 | map.put('(', ')'); 26 | map.put('{', '}'); 27 | map.put('[', ']'); 28 | Stack stk = new Stack<>(); 29 | for(char c: s.toCharArray()) { 30 | if(map.containsKey(c)) 31 | stk.push(c); 32 | else { 33 | if(stk.empty()) 34 | return false; 35 | char l = stk.pop(); 36 | if(!map.get(l).equals(c)) 37 | return false; 38 | } 39 | } 40 | if(stk.empty()) 41 | return true; 42 | else 43 | return false; 44 | } 45 | 46 | public static void main(String[] args) { 47 | boolean ret = new Solution().isValid("()"); 48 | assert ret==true; 49 | } 50 | } -------------------------------------------------------------------------------- /src/ValidateBinarySearchTree/Solution.java: -------------------------------------------------------------------------------- 1 | package ValidateBinarySearchTree; 2 | 3 | import commons.datastructures.TreeNode; 4 | 5 | /** 6 | * User: Danyang 7 | * Date: 1/27/2015 8 | * Time: 20:52 9 | * 10 | * Given a binary tree, determine if it is a valid binary search tree (BST). 11 | 12 | Assume a BST is defined as follows: 13 | 14 | The left subtree of a node contains only nodes with keys less than the node's key. 15 | The right subtree of a node contains only nodes with keys greater than the node's key. 16 | Both the left and right subtrees must also be binary search trees. 17 | */ 18 | public class Solution { 19 | /** 20 | * Complexity appears to be O(n lgn), but actually O(n) 21 | * @param root 22 | * @return 23 | */ 24 | public boolean isValidBST(TreeNode root) { 25 | if(root==null) 26 | return true; 27 | TreeNode l = getMax(root.left); 28 | TreeNode r = getMin(root.right); 29 | if(l!=null && l.val>=root.val || r!=null && r.val<=root.val) 30 | return false; 31 | return isValidBST(root.left) && isValidBST(root.right); 32 | } 33 | 34 | TreeNode getMax(TreeNode cur) { 35 | while(cur!=null && cur.right!=null) 36 | cur = cur.right; 37 | return cur; 38 | } 39 | 40 | TreeNode getMin(TreeNode cur) { 41 | while(cur!=null && cur.left!=null) 42 | cur = cur.left; 43 | return cur; 44 | } 45 | } -------------------------------------------------------------------------------- /src/WordLadder/Solution.java: -------------------------------------------------------------------------------- 1 | package WordLadder; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | /** 9 | * User: Danyang 10 | * Date: 1/30/2015 11 | * Time: 22:30 12 | * 13 | * Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to 14 | * end, such that: 15 | 16 | Only one letter can be changed at a time 17 | Each intermediate word must exist in the dictionary 18 | For example, 19 | 20 | Given: 21 | start = "hit" 22 | end = "cog" 23 | dict = ["hot","dot","dog","lot","log"] 24 | As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", 25 | return its length 5. 26 | 27 | Note: 28 | Return 0 if there is no such transformation sequence. 29 | All words have the same length. 30 | All words contain only lowercase alphabetic characters. 31 | */ 32 | public class Solution { 33 | /** 34 | * Algorithm bfs 35 | * 36 | * Notice: 37 | * 1. TLE due to the timing of remove the string from dict; 38 | * @param start 39 | * @param end 40 | * @param dict 41 | * @return 42 | */ 43 | public int ladderLength_TLE(String start, String end, Set dict) { 44 | List q = new ArrayList<>(); 45 | q.add(start); 46 | int level = 1; 47 | while(!q.isEmpty()) { 48 | int l = q.size(); 49 | level++; 50 | 51 | for(int i=0; i dict) { 74 | List q = new ArrayList<>(); 75 | q.add(start); 76 | dict.remove(start); 77 | int level = 1; 78 | while(!q.isEmpty()) { 79 | int l = q.size(); 80 | level++; 81 | 82 | for(int i=0; i dict = new HashSet<>(); 108 | dict.add("a"); 109 | dict.add("b"); 110 | dict.add("c"); 111 | int ret = new Solution().ladderLength("a", "c", dict); 112 | System.out.println(ret); 113 | } 114 | } -------------------------------------------------------------------------------- /src/WordSearch/Solution.java: -------------------------------------------------------------------------------- 1 | package WordSearch; 2 | 3 | /** 4 | * User: Danyang 5 | * Date: 1/26/2015 6 | * Time: 14:16 7 | * 8 | * Given a 2D board and a word, find if the word exists in the grid. 9 | 10 | The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally 11 | or vertically neighboring. The same letter cell may not be used more than once. 12 | 13 | For example, 14 | Given board = 15 | 16 | [ 17 | ["ABCE"], 18 | ["SFCS"], 19 | ["ADEE"] 20 | ] 21 | word = "ABCCED", -> returns true, 22 | word = "SEE", -> returns true, 23 | word = "ABCB", -> returns false. 24 | */ 25 | public class Solution { 26 | int[][] directions = new int[][] {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; 27 | /** 28 | * O(N*2)*O(N*2) 29 | * traverse + dfs 30 | * @param board 31 | * @param word 32 | * @return 33 | */ 34 | public boolean exist(char[][] board, String word) { 35 | int m = board.length; 36 | int n = board[0].length; 37 | boolean[][] visited = new boolean[m][n]; 38 | for(int i=0; i=0 && next_i=0 && next_j(n); // initialize array with length n, but not the object itself 28 | * @param s 29 | * @param nRows 30 | * @return 31 | */ 32 | public String convert(String s, int nRows) { 33 | List rows = new ArrayList<>(); 34 | for(int i=0; i