From 47e3fee32d6207982b0646a9c1297c2d6a973297 Mon Sep 17 00:00:00 2001 From: gouthampradhan Date: Fri, 15 Sep 2017 00:19:11 +0200 Subject: [PATCH] Code reformat --- problems/src/array/BattleshipsInABoard.java | 61 ++--- problems/src/array/CanPlaceFlowers.java | 47 ++-- problems/src/array/FirstMissingPositive.java | 27 +-- .../src/array/MaxProductOfThreeNumbers.java | 22 +- problems/src/array/MergeIntervals.java | 53 +++-- problems/src/array/MergeSortedArray.java | 14 +- problems/src/array/MissingNumber.java | 19 +- problems/src/array/PascalsTriangle.java | 35 ++- .../src/array/ProductOfArrayExceptSelf.java | 37 ++- problems/src/array/RotateArray.java | 27 +-- problems/src/array/RotateMatrix.java | 39 ++-- problems/src/array/SetMatrixZeroes.java | 47 ++-- problems/src/array/SortColors.java | 51 ++-- problems/src/array/ThirdMaximumNumber.java | 56 +++-- problems/src/array/TwoSum.java | 48 ++-- problems/src/array/TwoSumII.java | 35 ++- problems/src/backtracking/CombinationSum.java | 53 ++--- .../src/backtracking/CombinationSumII.java | 55 ++--- problems/src/backtracking/Combinations.java | 50 ++-- .../src/backtracking/GenerateParentheses.java | 37 ++- .../src/backtracking/LetterPhoneNumber.java | 46 ++-- .../backtracking/PalindromePartitioning.java | 59 ++--- problems/src/backtracking/Permutations.java | 49 ++-- problems/src/backtracking/PermutationsII.java | 47 ++-- problems/src/backtracking/Subsets.java | 51 ++-- problems/src/backtracking/SubsetsII.java | 49 ++-- problems/src/backtracking/WordSearch.java | 81 +++---- problems/src/backtracking/WordSearchII.java | 76 +++--- .../src/binary_search/FindPeakElement.java | 49 ++-- .../MedianOfTwoSortedArrays.java | 94 ++++---- .../binary_search/MinSortedRotatedArray.java | 37 ++- problems/src/binary_search/PowXN.java | 25 +- .../src/binary_search/SearchForARange.java | 47 ++-- .../binary_search/SearchInsertPosition.java | 36 ++- .../SearchRotatedSortedArray.java | 37 ++- problems/src/binary_search/SqrtX.java | 28 +-- problems/src/bit_manipulation/GrayCode.java | 47 ++-- .../BinarayTreeLevelOrderTraversal.java | 68 +++--- .../src/breadth_first_search/WordLadder.java | 73 +++--- .../breadth_first_search/WordLadderII.java | 116 ++++------ .../depth_first_search/CourseSchedule.java | 61 ++--- .../depth_first_search/CourseScheduleII.java | 58 ++--- .../src/depth_first_search/Minesweeper.java | 137 +++++------ .../depth_first_search/MovieRecommend.java | 40 ++-- .../depth_first_search/NumberOfIslands.java | 65 +++--- problems/src/design/AutocompleteSystem.java | 218 +++++++++--------- problems/src/design/BSTIterator.java | 36 +-- .../src/design/CopyListWithRandomPointer.java | 41 ++-- .../src/design/EncodeAndDecodeTinyURL.java | 21 +- problems/src/design/LFUCache.java | 142 +++++------- problems/src/design/LRUCache.java | 86 +++---- problems/src/design/RandomizedSet.java | 105 ++++----- .../SerializeDeserializeBinaryTree.java | 71 +++--- problems/src/design/TicTacToe.java | 169 +++++++------- problems/src/design/Trie.java | 56 +++-- problems/src/design/Twitter.java | 169 +++++++------- .../KthLargestElementInAnArray.java | 44 ++-- .../divide_and_conquer/SearchA2DMatrix.java | 67 +++--- .../BestTimeToBuyAndSellStocks.java | 46 ++-- problems/src/dynamic_programming/CanIWin.java | 70 +++--- .../dynamic_programming/ClimbingStairs.java | 26 +-- .../src/dynamic_programming/CoinChange.java | 70 +++--- .../src/dynamic_programming/CoinChange2.java | 77 +++---- .../ConcatenatedWords.java | 61 +++-- .../src/dynamic_programming/DecodeWays.java | 51 ++-- .../src/dynamic_programming/DungeonGame.java | 69 +++--- .../src/dynamic_programming/HouseRobber.java | 24 +- .../dynamic_programming/HouseRobberII.java | 31 ++- .../LongestIncreasingSubsequence.java | 38 ++- .../LongestPaliandromicSubstring.java | 64 +++-- .../LongestPalindromicSubsequence.java | 33 ++- .../MaximumProductSubarray.java | 25 +- .../dynamic_programming/MaximumSubarray.java | 16 +- .../PalindromePartitioningII.java | 47 ++-- .../dynamic_programming/TwoKeysKeyboard.java | 41 ++-- .../UniqueBinarySearchTrees.java | 40 ++-- .../UniqueBinarySearchTreesII.java | 89 +++---- .../src/dynamic_programming/WordBreak.java | 49 ++-- .../src/dynamic_programming/WordBreakII.java | 49 ++-- problems/src/greedy/BurstBalloons.java | 42 ++-- problems/src/greedy/CourseScheduleIII.java | 42 ++-- problems/src/greedy/GasStation.java | 32 +-- problems/src/greedy/JumpGame.java | 39 ++-- problems/src/greedy/JumpGameII.java | 42 ++-- .../src/greedy/NonOverlappingIntervals.java | 70 +++--- .../greedy/QueueReconstructionByHeight.java | 32 +-- problems/src/hashing/Anagrams.java | 89 ++++--- problems/src/hashing/GroupAnagrams.java | 52 ++--- problems/src/hashing/KdiffPairsInanArray.java | 77 +++---- problems/src/hashing/SortCharByFrequency.java | 109 +++++---- problems/src/hashing/TwoSum.java | 62 ++--- problems/src/hashing/ValidAnagram.java | 46 ++-- problems/src/heap/SlidingWindowMaximum.java | 62 +++-- problems/src/heap/TheSkylineProblem.java | 47 +++- problems/src/linked_list/DeleteNode.java | 14 +- .../linked_list/IntersectionOfTwoLists.java | 85 +++---- problems/src/linked_list/LinkedListCycle.java | 35 ++- .../src/linked_list/MergeKSortedLists.java | 46 ++-- .../src/linked_list/MergeTwoSortedList.java | 33 ++- problems/src/linked_list/PaliandromeList.java | 47 ++-- .../src/linked_list/ReverseLinkedList.java | 29 +-- .../src/linked_list/ReverseNodesKGroup.java | 71 +++--- .../src/linked_list/SwapNodesInPairs.java | 25 +- problems/src/math/AddDigits.java | 19 +- problems/src/math/AddTwoNumbers.java | 41 ++-- problems/src/math/CountPrimes.java | 36 ++- problems/src/math/ExcelSheetColumnTitle.java | 30 +-- problems/src/math/RomanToInteger.java | 15 +- problems/src/math/RotateFunction.java | 60 +++-- problems/src/math/WaterAndJugProblem.java | 36 +-- .../stack/LargestRectangleInHistogram.java | 41 ++-- problems/src/stack/MinStack.java | 67 +++--- problems/src/stack/MyQueue.java | 51 ++-- problems/src/stack/ValidParentheses.java | 28 +-- .../src/string/CompareVersionNumbers.java | 40 ++-- .../src/string/ExcelSheetColumnNumber.java | 27 +-- .../string/FirstUniqueCharacterInAString.java | 40 ++-- problems/src/string/ImplementStrStr.java | 26 +-- .../src/string/RepeatedSubstringPattern.java | 63 +++-- problems/src/string/ReverseWordsII.java | 71 +++--- .../src/string/ReverseWordsInAString.java | 34 +-- problems/src/string/SimplifyPath.java | 42 ++-- problems/src/string/StringToInteger.java | 58 ++--- problems/src/string/TextJustification.java | 79 +++---- problems/src/string/ValidPalindrome.java | 35 ++- problems/src/string/ZigZagConversion.java | 45 ++-- .../src/tree/BinarayTreeRightSideView.java | 50 ++-- .../src/tree/BinaryTreeInorderTraversal.java | 39 ++-- .../src/tree/BinaryTreeMaximumPathSum.java | 46 ++-- problems/src/tree/BoundaryOfBinaryTree.java | 154 ++++++------- .../tree/ClosestBinarySearchTreeValue.java | 42 ++-- .../tree/ConstructStringFromBinaryTree.java | 89 +++---- .../src/tree/ConvertSortedArrayToBST.java | 25 +- .../src/tree/FindBottomLeftTreeValue.java | 64 ++--- problems/src/tree/FlattenBinaryTree.java | 87 +++---- problems/src/tree/InorderSuccessorInBST.java | 49 ++-- problems/src/tree/LCA.java | 50 ++-- problems/src/tree/LargestBSTSubtree.java | 91 ++++---- .../src/tree/LowestCommonAncestorBST.java | 49 ++-- problems/src/tree/MaximumBinaryTree.java | 64 ++--- problems/src/tree/MostFrequentSubtreeSum.java | 71 +++--- problems/src/tree/NextRightPointer.java | 88 +++---- problems/src/tree/PathSumIII.java | 77 +++---- problems/src/tree/PostorderToBT.java | 39 ++-- problems/src/tree/PreorderToBT.java | 35 +-- problems/src/tree/SortedArrayToBST.java | 32 ++- problems/src/tree/SubtreeOfAnotherTree.java | 84 +++---- problems/src/tree/SymmetricTree.java | 41 ++-- problems/src/tree/ValidBinarySearchTree.java | 76 +++--- problems/src/tree/ZigZagTraversal.java | 48 ++-- problems/src/two_pointers/FourSum.java | 75 +++--- .../LongestSubstringWitoutRepeats.java | 37 ++- problems/src/two_pointers/MoveZeroes.java | 25 +- .../src/two_pointers/RemoveDuplicates.java | 25 +- problems/src/two_pointers/ThreeSum.java | 59 +++-- .../src/two_pointers/ThreeSumClosest.java | 32 ++- .../src/two_pointers/TrappingRainWater.java | 34 ++- 157 files changed, 4046 insertions(+), 4473 deletions(-) diff --git a/problems/src/array/BattleshipsInABoard.java b/problems/src/array/BattleshipsInABoard.java index 9da1e41d..c42fbbde 100644 --- a/problems/src/array/BattleshipsInABoard.java +++ b/problems/src/array/BattleshipsInABoard.java @@ -3,51 +3,52 @@ /** * Created by gouthamvidyapradhan on 12/08/2017. * Given an 2D board, count how many battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules: - - You receive a valid board, made of only battleships or empty slots. - Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size. - At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships. - Example: - X..X - ...X - ...X - In the above board there are 2 battleships. - Invalid Example: - ...X - XXXX - ...X - This is an invalid board that you will not receive - as battleships will always have a cell separating between them. - - Follow up: - Could you do it in one-pass, using only O(1) extra memory and without modifying the value of the board? - - Solution: - The below solution works in one pass using only O(1) memory. - Iterate through each cell and add one to count if and only if the current cell equals 'X' and its adjacent upper and - left cell does not contain 'X' + *

+ * You receive a valid board, made of only battleships or empty slots. + * Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size. + * At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships. + * Example: + * X..X + * ...X + * ...X + * In the above board there are 2 battleships. + * Invalid Example: + * ...X + * XXXX + * ...X + * This is an invalid board that you will not receive - as battleships will always have a cell separating between them. + *

+ * Follow up: + * Could you do it in one-pass, using only O(1) extra memory and without modifying the value of the board? + *

+ * Solution: + * The below solution works in one pass using only O(1) memory. + * Iterate through each cell and add one to count if and only if the current cell equals 'X' and its adjacent upper and + * left cell does not contain 'X' */ public class BattleshipsInABoard { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { char[][] board = {{'X', '.', '.', 'X'}, {'.', '.', '.', 'X'}, {'.', '.', '.', 'X'}}; System.out.println(new BattleshipsInABoard().countBattleships(board)); } public int countBattleships(char[][] board) { int count = 0; - for(int i = 0; i < board.length; i ++){ - for(int j = 0; j < board[0].length; j ++){ - if(board[i][j] == 'X'){ - if(i - 1 >= 0){ //check for the boundary condition - if(board[i - 1][j] == 'X') + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == 'X') { + if (i - 1 >= 0) { //check for the boundary condition + if (board[i - 1][j] == 'X') continue; } - if(j - 1 >= 0){ - if(board[i][j - 1] == 'X'){ + if (j - 1 >= 0) { + if (board[i][j - 1] == 'X') { continue; } } diff --git a/problems/src/array/CanPlaceFlowers.java b/problems/src/array/CanPlaceFlowers.java index f8442336..8b7e732e 100644 --- a/problems/src/array/CanPlaceFlowers.java +++ b/problems/src/array/CanPlaceFlowers.java @@ -3,48 +3,47 @@ /** * Created by gouthamvidyapradhan on 10/06/2017. * Accepted - * - Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. - - Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. - - Example 1: - Input: flowerbed = [1,0,0,0,1], n = 1 - Output: True - Example 2: - Input: flowerbed = [1,0,0,0,1], n = 2 - Output: False - Note: - The input array won't violate no-adjacent-flowers rule. - The input array size is in the range of [1, 20000]. - n is a non-negative integer which won't exceed the input array size. + *

+ * Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. + *

+ * Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. + *

+ * Example 1: + * Input: flowerbed = [1,0,0,0,1], n = 1 + * Output: True + * Example 2: + * Input: flowerbed = [1,0,0,0,1], n = 2 + * Output: False + * Note: + * The input array won't violate no-adjacent-flowers rule. + * The input array size is in the range of [1, 20000]. + * n is a non-negative integer which won't exceed the input array size. */ -public class CanPlaceFlowers -{ +public class CanPlaceFlowers { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] n = {1,0,0,0,1}; + public static void main(String[] args) throws Exception { + int[] n = {1, 0, 0, 0, 1}; System.out.println(new CanPlaceFlowers().canPlaceFlowers(n, 1)); } public boolean canPlaceFlowers(int[] flowerbed, int n) { int[] T = new int[flowerbed.length + 4]; - for(int i = 0, j = 2; i < flowerbed.length; i ++) + for (int i = 0, j = 2; i < flowerbed.length; i++) T[j++] = flowerbed[i]; T[0] = 1; T[T.length - 1] = 1; int total = 0, count = 0; - for(int i = 1; i < T.length; i ++) { - if(T[i] == 0) + for (int i = 1; i < T.length; i++) { + if (T[i] == 0) count++; else { - if((count % 2) == 0) + if ((count % 2) == 0) total += ((count / 2) - 1); else total += (count / 2); diff --git a/problems/src/array/FirstMissingPositive.java b/problems/src/array/FirstMissingPositive.java index 57d2c9c8..034a9bc1 100644 --- a/problems/src/array/FirstMissingPositive.java +++ b/problems/src/array/FirstMissingPositive.java @@ -3,40 +3,41 @@ /** * Created by gouthamvidyapradhan on 24/06/2017. * Given an unsorted integer array, find the first missing positive integer. - - For example, - Given [1,2,0] return 3, - and [3,4,-1,1] return 2. - - Your algorithm should run in O(n) time and uses constant space. + *

+ * For example, + * Given [1,2,0] return 3, + * and [3,4,-1,1] return 2. + *

+ * Your algorithm should run in O(n) time and uses constant space. */ public class FirstMissingPositive { private int L; - public static void main(String[] args) throws Exception{ + + public static void main(String[] args) throws Exception { int[] nums = {1, 3, 5, 9}; System.out.println(new FirstMissingPositive().firstMissingPositive(nums)); } public int firstMissingPositive(int[] nums) { L = nums.length; - for(int i = 0; i < L; i ++){ - if(nums[i] > 0 && nums[i] <= L && nums[i] != i + 1){ + for (int i = 0; i < L; i++) { + if (nums[i] > 0 && nums[i] <= L && nums[i] != i + 1) { int v = nums[i]; nums[i] = -1; replace(v, nums); } } - for(int i = 0; i < L; i ++){ - if(nums[i] != i + 1) + for (int i = 0; i < L; i++) { + if (nums[i] != i + 1) return i + 1; } return L + 1; } - private void replace(int i, int[] nums){ - if(i > 0 && i <= L && i != nums[i - 1]){ + private void replace(int i, int[] nums) { + if (i > 0 && i <= L && i != nums[i - 1]) { int v = nums[i - 1]; nums[i - 1] = i; replace(v, nums); diff --git a/problems/src/array/MaxProductOfThreeNumbers.java b/problems/src/array/MaxProductOfThreeNumbers.java index 8428e3dd..a61b5abe 100644 --- a/problems/src/array/MaxProductOfThreeNumbers.java +++ b/problems/src/array/MaxProductOfThreeNumbers.java @@ -5,20 +5,20 @@ /** * Created by gouthamvidyapradhan on 27/06/2017. * Given an integer array, find three numbers whose product is maximum and output the maximum product. - - Example 1: - Input: [1,2,3] - Output: 6 - Example 2: - Input: [1,2,3,4] - Output: 24 - Note: - The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000]. - Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer. + *

+ * Example 1: + * Input: [1,2,3] + * Output: 6 + * Example 2: + * Input: [1,2,3,4] + * Output: 24 + * Note: + * The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000]. + * Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer. */ public class MaxProductOfThreeNumbers { public static void main(String[] args) { - int[] A = {1,2,3}; + int[] A = {1, 2, 3}; System.out.println(new MaxProductOfThreeNumbers().maximumProduct(A)); } diff --git a/problems/src/array/MergeIntervals.java b/problems/src/array/MergeIntervals.java index 25e5c653..e16e1c56 100644 --- a/problems/src/array/MergeIntervals.java +++ b/problems/src/array/MergeIntervals.java @@ -1,33 +1,41 @@ package array; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Created by gouthamvidyapradhan on 13/06/2017. * Given a collection of intervals, merge all overlapping intervals. - - For example, - Given [1,3],[2,6],[8,10],[15,18], - return [1,6],[8,10],[15,18]. - - Solution: O(N log N) where N is the number of intervals - 1. Sort the intervals based on start index - 2. Mark the first interval as the current interval - 3. For every ith interval starting 1 -> N, if the ith interval overlaps with the current interval then create a new - current interval. Else, add the current interval to result set and begin a new current interval. - + *

+ * For example, + * Given [1,3],[2,6],[8,10],[15,18], + * return [1,6],[8,10],[15,18]. + *

+ * Solution: O(N log N) where N is the number of intervals + * 1. Sort the intervals based on start index + * 2. Mark the first interval as the current interval + * 3. For every ith interval starting 1 -> N, if the ith interval overlaps with the current interval then create a new + * current interval. Else, add the current interval to result set and begin a new current interval. */ -public class MergeIntervals -{ +public class MergeIntervals { public static class Interval { int start; int end; - Interval() { start = 0; end = 0; } - Interval(int s, int e) { start = s; end = e; } + + Interval() { + start = 0; + end = 0; + } + + Interval(int s, int e) { + start = s; + end = e; + } } - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { Interval i1 = new Interval(1, 2); Interval i2 = new Interval(3, 4); Interval i3 = new Interval(5, 6); @@ -37,16 +45,15 @@ public static void main(String[] args) throws Exception } public List merge(List intervals) { - if(intervals.isEmpty()) return new ArrayList<>(); + if (intervals.isEmpty()) return new ArrayList<>(); Collections.sort(intervals, (o1, o2) -> Integer.compare(o1.start, o2.start)); List result = new ArrayList<>(); Interval curr = intervals.get(0); - for(int i = 1, l = intervals.size(); i < l; i ++) { + for (int i = 1, l = intervals.size(); i < l; i++) { Interval I = intervals.get(i); - if(I.start >= curr.start && I.start <= curr.end) { //check if the new interval overlaps with the current + if (I.start >= curr.start && I.start <= curr.end) { //check if the new interval overlaps with the current curr.end = curr.end > I.end ? curr.end : I.end; - } - else { + } else { result.add(curr); curr = I; } diff --git a/problems/src/array/MergeSortedArray.java b/problems/src/array/MergeSortedArray.java index 75e088c2..82530e63 100644 --- a/problems/src/array/MergeSortedArray.java +++ b/problems/src/array/MergeSortedArray.java @@ -3,24 +3,24 @@ /** * Created by gouthamvidyapradhan on 29/07/2017. * Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. - - Note: - You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. + *

+ * Note: + * You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. */ public class MergeSortedArray { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] A = {0}; int[] B = {1}; new MergeSortedArray().merge(A, 0, B, 1); - for(int i : A) + for (int i : A) System.out.println(i); } public void merge(int[] nums1, int m, int[] nums2, int n) { int i = m + n - 1, j = m - 1, k = n - 1; - while(j >= 0 && k >= 0) + while (j >= 0 && k >= 0) nums1[i--] = (nums1[j] > nums2[k]) ? nums1[j--] : nums2[k--]; - while(k >= 0) + while (k >= 0) nums1[i--] = nums2[k--]; } diff --git a/problems/src/array/MissingNumber.java b/problems/src/array/MissingNumber.java index 512bc9fc..b874c83a 100644 --- a/problems/src/array/MissingNumber.java +++ b/problems/src/array/MissingNumber.java @@ -3,27 +3,28 @@ /** * Created by gouthamvidyapradhan on 04/07/2017. * Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. - - For example, - Given nums = [0, 1, 3] return 2. - - Note: - Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? + *

+ * For example, + * Given nums = [0, 1, 3] return 2. + *

+ * Note: + * Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? */ public class MissingNumber { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] nums = {0}; System.out.println(new MissingNumber().missingNumber(nums)); } - public int missingNumber(int[] nums){ + + public int missingNumber(int[] nums) { int sum = 0; int n = nums.length; for (int num : nums) { sum += num; } int arrSum = (((n + 1)) * n) / 2; - if(arrSum == sum) return 0; + if (arrSum == sum) return 0; else return arrSum - sum; } } diff --git a/problems/src/array/PascalsTriangle.java b/problems/src/array/PascalsTriangle.java index c1b00861..d12a2384 100644 --- a/problems/src/array/PascalsTriangle.java +++ b/problems/src/array/PascalsTriangle.java @@ -6,28 +6,25 @@ /** * Created by gouthamvidyapradhan on 25/03/2017. - * + *

* Given an index k, return the kth row of the Pascal's triangle. - - For example, given k = 3, - Return [1,3,3,1]. - - Note: - Could you optimize your algorithm to use only O(k) extra space? + *

+ * For example, given k = 3, + * Return [1,3,3,1]. + *

+ * Note: + * Could you optimize your algorithm to use only O(k) extra space? */ -public class PascalsTriangle -{ - public static void main(String[] args) throws Exception - { +public class PascalsTriangle { + public static void main(String[] args) throws Exception { System.out.println(new PascalsTriangle().getRow(3)); } - public List getRow(int rowIndex) - { - int k = rowIndex; - if(k == 0) + public List getRow(int rowIndex) { + int k = rowIndex; + if (k == 0) return Arrays.asList(1); - else if(k == 1) + else if (k == 1) return Arrays.asList(1, 1); else if (k == 2) return Arrays.asList(1, 2, 1); @@ -35,12 +32,10 @@ else if (k == 2) result.add(2); k = k - 2; int p, c; - while(k-- > 0) - { + while (k-- > 0) { p = 1; int i = 0; - for(int l = result.size(); i < l; i ++) - { + for (int l = result.size(); i < l; i++) { c = result.get(i); result.set(i, p + c); p = c; diff --git a/problems/src/array/ProductOfArrayExceptSelf.java b/problems/src/array/ProductOfArrayExceptSelf.java index fc380515..4ed21a77 100644 --- a/problems/src/array/ProductOfArrayExceptSelf.java +++ b/problems/src/array/ProductOfArrayExceptSelf.java @@ -1,38 +1,33 @@ package array; /** - Created by gouthamvidyapradhan on 04/05/2017. - - Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. - - Solve it without division and in O(n). - - For example, given [1,2,3,4], return [24,12,8,6]. - - Follow up: - Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.) + * Created by gouthamvidyapradhan on 04/05/2017. + *

+ * Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. + *

+ * Solve it without division and in O(n). + *

+ * For example, given [1,2,3,4], return [24,12,8,6]. + *

+ * Follow up: + * Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.) */ -public class ProductOfArrayExceptSelf -{ - public static void main(String[] args) - { - int[] nums = {1,2,3,4}; +public class ProductOfArrayExceptSelf { + public static void main(String[] args) { + int[] nums = {1, 2, 3, 4}; int[] result = new ProductOfArrayExceptSelf().productExceptSelf(nums); for (int r : result) System.out.print(r + " "); } - public int[] productExceptSelf(int[] nums) - { + public int[] productExceptSelf(int[] nums) { int[] result = new int[nums.length]; - for(int i = 0, temp = 1, l = nums.length; i < l; i++) - { + for (int i = 0, temp = 1, l = nums.length; i < l; i++) { result[i] = temp; temp *= nums[i]; } - for(int i = nums.length - 1, temp = 1; i >= 0; i--) - { + for (int i = nums.length - 1, temp = 1; i >= 0; i--) { result[i] = result[i] * temp; temp *= nums[i]; } diff --git a/problems/src/array/RotateArray.java b/problems/src/array/RotateArray.java index a1c04df0..f418a52b 100644 --- a/problems/src/array/RotateArray.java +++ b/problems/src/array/RotateArray.java @@ -3,27 +3,28 @@ /** * Created by gouthamvidyapradhan on 01/08/2017. * Rotate an array of n elements to the right by k steps. - - For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. - - Note: - Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. - - Hint: - Could you do it in-place with O(1) extra space? - Related problem: Reverse Words in a String II + *

+ * For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. + *

+ * Note: + * Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. + *

+ * Hint: + * Could you do it in-place with O(1) extra space? + * Related problem: Reverse Words in a String II */ public class RotateArray { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] A = {1, 2, 3, 4, 5, 6}; new RotateArray().rotate(A, 2); for (int i : A) - System.out.print(i + " "); + System.out.print(i + " "); } public void rotate(int[] nums, int k) { @@ -33,8 +34,8 @@ public void rotate(int[] nums, int k) { reverse(nums, k, nums.length - 1); } - private void reverse(int[] nums, int s, int e){ - for(int i = s, j = e; i < j; i ++, j --){ + private void reverse(int[] nums, int s, int e) { + for (int i = s, j = e; i < j; i++, j--) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; diff --git a/problems/src/array/RotateMatrix.java b/problems/src/array/RotateMatrix.java index aff6e5c8..6df275cf 100644 --- a/problems/src/array/RotateMatrix.java +++ b/problems/src/array/RotateMatrix.java @@ -3,39 +3,33 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. * You are given an n x n 2D matrix representing an image. - - Rotate the image by 90 degrees (clockwise). - - Follow up: - Could you do this in-place? + *

+ * Rotate the image by 90 degrees (clockwise). + *

+ * Follow up: + * Could you do this in-place? */ -public class RotateMatrix -{ +public class RotateMatrix { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[][] A = {{1,2,3}, {4,5,6}, {7,8,9}}; + public static void main(String[] args) throws Exception { + int[][] A = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; new RotateMatrix().rotate(A); - for (int i = 0; i < A.length; i ++) - { - for(int j = 0; j < A[0].length; j ++) - { + for (int i = 0; i < A.length; i++) { + for (int j = 0; j < A[0].length; j++) { System.out.println(A[i][j]); } } } - public void rotate(int[][] matrix) - { + public void rotate(int[][] matrix) { int lc = 0, tr = 0, rc = matrix[0].length - 1, br = matrix.length - 1; - while(tr < br) - { - for(int i = lc, j = tr, k = rc, l = br; i < rc && j < br && k > lc && l > tr; i ++, j ++, k--, l--) - { + while (tr < br) { + for (int i = lc, j = tr, k = rc, l = br; i < rc && j < br && k > lc && l > tr; i++, j++, k--, l--) { int temp1 = matrix[j][rc]; matrix[j][rc] = matrix[tr][i]; int temp2 = matrix[br][k]; @@ -44,7 +38,10 @@ public void rotate(int[][] matrix) matrix[l][lc] = temp2; matrix[tr][i] = temp1; } - lc ++; tr ++; rc --; br --; + lc++; + tr++; + rc--; + br--; } } } diff --git a/problems/src/array/SetMatrixZeroes.java b/problems/src/array/SetMatrixZeroes.java index c520bd69..43e8223e 100644 --- a/problems/src/array/SetMatrixZeroes.java +++ b/problems/src/array/SetMatrixZeroes.java @@ -6,59 +6,50 @@ /** * Created by pradhang on 3/28/2017. * Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. - - click to show follow up. - - Follow up: - Did you use extra space? - A straight forward solution using O(mn) space is probably a bad idea. - A simple improvement uses O(m + n) space, but still not the best solution. - Could you devise a constant space solution? + *

+ * click to show follow up. + *

+ * Follow up: + * Did you use extra space? + * A straight forward solution using O(mn) space is probably a bad idea. + * A simple improvement uses O(m + n) space, but still not the best solution. + * Could you devise a constant space solution? */ -public class SetMatrixZeroes -{ +public class SetMatrixZeroes { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[][] matrix = {{0, 8, 7}, {9, 0, 8}, {9, 9, 0}}; new SetMatrixZeroes().setZeroes(matrix); } - public void setZeroes(int[][] matrix) - { + public void setZeroes(int[][] matrix) { Set row = new HashSet<>(); Set col = new HashSet<>(); int m = matrix.length; int n = matrix[0].length; - for(int i = 0; i < m; i ++) - { - for(int j = 0; j < n; j ++) - { - if(matrix[i][j] == 0) - { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (matrix[i][j] == 0) { row.add(i); col.add(j); } } } - for(int r : row) - { - for(int j = 0; j < n; j++) - { + for (int r : row) { + for (int j = 0; j < n; j++) { matrix[r][j] = 0; } } - for(int c : col) - { - for(int i = 0; i < m; i++) - { + for (int c : col) { + for (int i = 0; i < m; i++) { matrix[i][c] = 0; } } diff --git a/problems/src/array/SortColors.java b/problems/src/array/SortColors.java index d049bdf0..cd9486e4 100644 --- a/problems/src/array/SortColors.java +++ b/problems/src/array/SortColors.java @@ -3,33 +3,33 @@ /** * Created by gouthamvidyapradhan on 06/08/2017. * Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. - - Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. - - Note: - You are not suppose to use the library's sort function for this problem. - - Follow up: - A rather straight forward solution is a two-pass algorithm using counting sort. - First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. - - Could you come up with an one-pass algorithm using only constant space? - - Solution: - The below solution works with one pass. The basic idea is to keep track of start and end index of - contiguous 1s and push the 0s to left of 1s and 2 to right of 1s. - + *

+ * Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. + *

+ * Note: + * You are not suppose to use the library's sort function for this problem. + *

+ * Follow up: + * A rather straight forward solution is a two-pass algorithm using counting sort. + * First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. + *

+ * Could you come up with an one-pass algorithm using only constant space? + *

+ * Solution: + * The below solution works with one pass. The basic idea is to keep track of start and end index of + * contiguous 1s and push the 0s to left of 1s and 2 to right of 1s. */ public class SortColors { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] nums = {2, 1, 0, 0, 1}; new SortColors().sortColors(nums); - for(int i : nums) + for (int i : nums) System.out.println(i); } @@ -37,20 +37,21 @@ public void sortColors(int[] nums) { int s = nums[0]; //save the first index value nums[0] = 1; //overwrite with 1 int l = 0, r = 0; //left and right index indicating the start and end index of 1s - for(int i = 1; i < nums.length; i ++){ - switch (nums[i]){ + for (int i = 1; i < nums.length; i++) { + switch (nums[i]) { case 0: nums[l] = 0; nums[r + 1] = 1; - if(r + 1 != i){ + if (r + 1 != i) { nums[i] = 2; } - l ++; r ++; + l++; + r++; break; case 1: nums[r + 1] = 1; - if(r + 1 != i){ + if (r + 1 != i) { nums[i] = 2; } r++; @@ -58,9 +59,9 @@ public void sortColors(int[] nums) { } } //replace the initial overwritten value with the original value - if(s == 0) + if (s == 0) nums[l] = 0; - else if(s == 2) + else if (s == 2) nums[r] = 2; } } diff --git a/problems/src/array/ThirdMaximumNumber.java b/problems/src/array/ThirdMaximumNumber.java index 6438ad20..3de8137b 100644 --- a/problems/src/array/ThirdMaximumNumber.java +++ b/problems/src/array/ThirdMaximumNumber.java @@ -2,44 +2,42 @@ /** * Created by gouthamvidyapradhan on 25/03/2017. - Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). - - Example 1: - Input: [3, 2, 1] - - Output: 1 - - Explanation: The third maximum is 1. - Example 2: - Input: [1, 2] - - Output: 2 - - Explanation: The third maximum does not exist, so the maximum (2) is returned instead. - Example 3: - Input: [2, 2, 3, 1] - - Output: 1 - - Explanation: Note that the third maximum here means the third maximum distinct number. - Both numbers with value 2 are both considered as second maximum. + * Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). + *

+ * Example 1: + * Input: [3, 2, 1] + *

+ * Output: 1 + *

+ * Explanation: The third maximum is 1. + * Example 2: + * Input: [1, 2] + *

+ * Output: 2 + *

+ * Explanation: The third maximum does not exist, so the maximum (2) is returned instead. + * Example 3: + * Input: [2, 2, 3, 1] + *

+ * Output: 1 + *

+ * Explanation: Note that the third maximum here means the third maximum distinct number. + * Both numbers with value 2 are both considered as second maximum. */ -public class ThirdMaximumNumber -{ +public class ThirdMaximumNumber { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] a = {1, 2}; System.out.println(new ThirdMaximumNumber().thirdMax(a)); } - public int thirdMax(int[] nums) - { - long[] max = {Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE}; + public int thirdMax(int[] nums) { + long[] max = {Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE}; int count = 0; for (int num : nums) { for (int j = 0; j < 3; j++) { @@ -59,6 +57,6 @@ public int thirdMax(int[] nums) } } System.out.println(Integer.MIN_VALUE); - return (count >= 3)? (int)max[2] : (int)max[0]; + return (count >= 3) ? (int) max[2] : (int) max[0]; } } diff --git a/problems/src/array/TwoSum.java b/problems/src/array/TwoSum.java index 6fd0cc2f..1333f950 100644 --- a/problems/src/array/TwoSum.java +++ b/problems/src/array/TwoSum.java @@ -6,25 +6,25 @@ /** * Created by gouthamvidyapradhan on 11/07/2017. * Given an array of integers, return indices of the two numbers such that they add up to a specific target. - - You may assume that each input would have exactly one solution, and you may not use the same element twice. - - Example: - Given nums = [2, 7, 11, 15], target = 9, - - Because nums[0] + nums[1] = 2 + 7 = 9, - return [0, 1]. - - Solution: O(n log n). Wrap index and element in a class and sort in increasing order. Do a two pointer sum and compare. - An alternative solution is to use hashing which is a O(n) solution - For each element e check if element (target - e) - is already found in hashset, if yes return their index, else add this to hash-set and continue. + *

+ * You may assume that each input would have exactly one solution, and you may not use the same element twice. + *

+ * Example: + * Given nums = [2, 7, 11, 15], target = 9, + *

+ * Because nums[0] + nums[1] = 2 + 7 = 9, + * return [0, 1]. + *

+ * Solution: O(n log n). Wrap index and element in a class and sort in increasing order. Do a two pointer sum and compare. + * An alternative solution is to use hashing which is a O(n) solution - For each element e check if element (target - e) + * is already found in hashset, if yes return their index, else add this to hash-set and continue. */ public class TwoSum { - class NumIndex - { + class NumIndex { int i, e; - NumIndex(int i, int e){ + + NumIndex(int i, int e) { this.i = i; this.e = e; } @@ -39,26 +39,24 @@ public static void main(String[] args) { public int[] twoSum(int[] nums, int target) { List list = new ArrayList<>(); - for(int i = 0; i < nums.length; i ++){ + for (int i = 0; i < nums.length; i++) { NumIndex n = new NumIndex(i, nums[i]); list.add(n); } list.sort((o1, o2) -> Integer.compare(o1.e, o2.e)); int[] ans = new int[2]; - for(int i = 0, j = nums.length - 1; i < j; ){ - NumIndex numi = list.get(i); - NumIndex numj = list.get(j); + for (int i = 0, j = nums.length - 1; i < j; ) { + NumIndex numi = list.get(i); + NumIndex numj = list.get(j); int sum = numi.e + numj.e; - if(sum == target){ + if (sum == target) { ans[0] = numi.i; ans[1] = numj.i; return ans; - } - else if(sum > target){ - j --; - } - else i++; + } else if (sum > target) { + j--; + } else i++; } return ans; } diff --git a/problems/src/array/TwoSumII.java b/problems/src/array/TwoSumII.java index c69928b9..d8a338d7 100644 --- a/problems/src/array/TwoSumII.java +++ b/problems/src/array/TwoSumII.java @@ -2,44 +2,39 @@ /** * Created by gouthamvidyapradhan on 18/03/2017. - Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. - - The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. - - You may assume that each input would have exactly one solution and you may not use the same element twice. - - Input: numbers={2, 7, 11, 15}, target=9 - Output: index1=1, index2=2 + * Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. + *

+ * The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. + *

+ * You may assume that each input would have exactly one solution and you may not use the same element twice. + *

+ * Input: numbers={2, 7, 11, 15}, target=9 + * Output: index1=1, index2=2 */ -public class TwoSumII -{ +public class TwoSumII { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] nums = {2, 7, 11, 15}; int[] result = new TwoSumII().twoSum(nums, 23); for (int i : result) System.out.println(i); } - public int[] twoSum(int[] numbers, int target) - { + public int[] twoSum(int[] numbers, int target) { int i = 0, j = numbers.length - 1; - while(i < j) - { + while (i < j) { int x = (numbers[i] + numbers[j]); - if(x == target) - { + if (x == target) { int[] result = new int[2]; result[0] = i + 1; result[1] = j + 1; return result; - } - else if(x < target) + } else if (x < target) i++; else j--; } diff --git a/problems/src/backtracking/CombinationSum.java b/problems/src/backtracking/CombinationSum.java index f426adec..b9c87cbe 100644 --- a/problems/src/backtracking/CombinationSum.java +++ b/problems/src/backtracking/CombinationSum.java @@ -5,55 +5,48 @@ /** * Created by pradhang on 3/14/2017. - Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. - - The same repeated number may be chosen from C unlimited number of times. - - Note: - All numbers (including target) will be positive integers. - The solution set must not contain duplicate combinations. - For example, given candidate set [2, 3, 6, 7] and target 7, - A solution set is: - [ - [7], - [2, 2, 3] - ] + * Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. + *

+ * The same repeated number may be chosen from C unlimited number of times. + *

+ * Note: + * All numbers (including target) will be positive integers. + * The solution set must not contain duplicate combinations. + * For example, given candidate set [2, 3, 6, 7] and target 7, + * A solution set is: + * [ + * [7], + * [2, 2, 3] + * ] */ -public class CombinationSum -{ +public class CombinationSum { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] candidates = {2,3,6,7}; + public static void main(String[] args) throws Exception { + int[] candidates = {2, 3, 6, 7}; List> result = new CombinationSum().combinationSum(candidates, 7); } - public List> combinationSum(int[] candidates, int target) - { + public List> combinationSum(int[] candidates, int target) { List> result = new ArrayList<>(); List subList = new ArrayList<>(); doNext(0, result, 0, candidates, target, subList); return result; } - private void doNext(int i, List> result, int count, int[] candidates, int target, List subArr) - { - if(target == 0) - { + private void doNext(int i, List> result, int count, int[] candidates, int target, List subArr) { + if (target == 0) { List subList = new ArrayList<>(); - for(int k = 0; k < count; k ++) + for (int k = 0; k < count; k++) subList.add(subArr.get(k)); result.add(subList); - } - else if(target > 0) - { - for(int j = i, l = candidates.length; j < l; j ++) - { + } else if (target > 0) { + for (int j = i, l = candidates.length; j < l; j++) { subArr.add(candidates[j]); doNext(j, result, count + 1, candidates, target - candidates[j], subArr); subArr.remove(subArr.size() - 1); diff --git a/problems/src/backtracking/CombinationSumII.java b/problems/src/backtracking/CombinationSumII.java index 091c2d45..857137ce 100644 --- a/problems/src/backtracking/CombinationSumII.java +++ b/problems/src/backtracking/CombinationSumII.java @@ -6,55 +6,48 @@ /** * Created by gouthamvidyapradhan on 14/03/2017. - Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. - - Each number in C may only be used once in the combination. - - Note: - All numbers (including target) will be positive integers. - The solution set must not contain duplicate combinations. - For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, - A solution set is: - [ - [1, 7], - [1, 2, 5], - [2, 6], - [1, 1, 6] - ] + * Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. + *

+ * Each number in C may only be used once in the combination. + *

+ * Note: + * All numbers (including target) will be positive integers. + * The solution set must not contain duplicate combinations. + * For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, + * A solution set is: + * [ + * [1, 7], + * [1, 2, 5], + * [2, 6], + * [1, 1, 6] + * ] */ -public class CombinationSumII -{ +public class CombinationSumII { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] candidates = {1, 1, 2, 2}; List> result = new CombinationSumII().combinationSum2(candidates, 4); } - public List> combinationSum2(int[] candidates, int target) - { + public List> combinationSum2(int[] candidates, int target) { Arrays.sort(candidates); List> result = new ArrayList<>(); combination(0, target, candidates, new ArrayList<>(), result); return result; } - private void combination(int i, int target, int[] candidates, List row, List> result) - { - if(target == 0) - { + private void combination(int i, int target, int[] candidates, List row, List> result) { + if (target == 0) { result.add(new ArrayList<>(row)); - } - else if(target > 0) - { - for(int j = i, l = candidates.length; j < l; j ++) - { - if(j > i && candidates[j] == candidates[j - 1]) continue; + } else if (target > 0) { + for (int j = i, l = candidates.length; j < l; j++) { + if (j > i && candidates[j] == candidates[j - 1]) continue; row.add(candidates[j]); combination(j + 1, target - candidates[j], candidates, row, result); row.remove(row.size() - 1); diff --git a/problems/src/backtracking/Combinations.java b/problems/src/backtracking/Combinations.java index 5d11932d..1d1c2ded 100644 --- a/problems/src/backtracking/Combinations.java +++ b/problems/src/backtracking/Combinations.java @@ -5,30 +5,27 @@ /** * Created by pradhang on 3/8/2017. - Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. - - For example, - If n = 4 and k = 2, a solution is: - - [ - [2,4], - [3,4], - [2,3], - [1,2], - [1,3], - [1,4], - ] + * Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. + *

+ * For example, + * If n = 4 and k = 2, a solution is: + *

+ * [ + * [2,4], + * [3,4], + * [2,3], + * [1,2], + * [1,3], + * [1,4], + * ] */ -public class Combinations -{ +public class Combinations { - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List> result = new Combinations().combine(3, 3); } - public List> combine(int n, int k) - { + public List> combine(int n, int k) { int[] subArr = new int[k]; List> result = new ArrayList<>(); getNext(0, 0, n, k, subArr, result); @@ -36,19 +33,14 @@ public List> combine(int n, int k) } private void getNext(int i, int count, - int n, int k, int[] subArr, List> result) - { - if(k == 0) - { + int n, int k, int[] subArr, List> result) { + if (k == 0) { List subList = new ArrayList<>(); - for(int a : subArr) + for (int a : subArr) subList.add(a); result.add(subList); - } - else - { - for(int j = i + 1; j <= n; j++) - { + } else { + for (int j = i + 1; j <= n; j++) { subArr[count] = j; getNext(j, count + 1, n, k - 1, subArr, result); } diff --git a/problems/src/backtracking/GenerateParentheses.java b/problems/src/backtracking/GenerateParentheses.java index 764945ec..5c20329c 100644 --- a/problems/src/backtracking/GenerateParentheses.java +++ b/problems/src/backtracking/GenerateParentheses.java @@ -1,24 +1,24 @@ package backtracking; -import java.util.*; +import java.util.ArrayList; +import java.util.List; /** * Created by gouthamvidyapradhan on 24/06/2017. * Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. - - For example, given n = 3, a solution set is: - - [ - "((()))", - "(()())", - "(())()", - "()(())", - "()()()" - ] - + *

+ * For example, given n = 3, a solution set is: + *

+ * [ + * "((()))", + * "(()())", + * "(())()", + * "()(())", + * "()()()" + * ] */ public class GenerateParentheses { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new GenerateParentheses().generateParenthesis(4)); } @@ -28,14 +28,13 @@ public List generateParenthesis(int n) { return list; } - private void backTrack(List list, String str, int open, int close, int n){ - if(str.length() == n * 2){ + private void backTrack(List list, String str, int open, int close, int n) { + if (str.length() == n * 2) { list.add(str); - } - else { - if(open < n) + } else { + if (open < n) backTrack(list, str.concat("("), open + 1, close, n); - if(close < open) //number of close should be less than open or else it can result in unbalanced parentheses + if (close < open) //number of close should be less than open or else it can result in unbalanced parentheses backTrack(list, str.concat(")"), open, close + 1, n); } } diff --git a/problems/src/backtracking/LetterPhoneNumber.java b/problems/src/backtracking/LetterPhoneNumber.java index 1712396c..dda5d638 100644 --- a/problems/src/backtracking/LetterPhoneNumber.java +++ b/problems/src/backtracking/LetterPhoneNumber.java @@ -5,47 +5,43 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a digit string, return all possible letter combinations that the number could represent. - - A mapping of digit to letters (just like on the telephone buttons) is given below. - 1 2(abc) 3(def) - 4(ghi) 5(jkl) 6(mno) - 7(pqrs) 8(tuv) 9(wxyz) - - - Input:Digit string "23" - Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. - Note: - Although the above answer is in lexicographical order, your answer could be in any order you want. + * Given a digit string, return all possible letter combinations that the number could represent. + *

+ * A mapping of digit to letters (just like on the telephone buttons) is given below. + * 1 2(abc) 3(def) + * 4(ghi) 5(jkl) 6(mno) + * 7(pqrs) 8(tuv) 9(wxyz) + *

+ *

+ * Input:Digit string "23" + * Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. + * Note: + * Although the above answer is in lexicographical order, your answer could be in any order you want. */ -public class LetterPhoneNumber -{ +public class LetterPhoneNumber { private String[] NUMBER_ALPHA = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List result = new LetterPhoneNumber().letterCombinations("23"); result.forEach(System.out::println); } - private List letterCombinations(String digits) - { - if(digits == null || digits.isEmpty() || digits.contains("1") || digits.contains("0")) return new ArrayList<>(); + private List letterCombinations(String digits) { + if (digits == null || digits.isEmpty() || digits.contains("1") || digits.contains("0")) + return new ArrayList<>(); List prev = new ArrayList<>(); prev.add(""); - for(int i = digits.length() - 1; i >= 0; i --) - { + for (int i = digits.length() - 1; i >= 0; i--) { String str = NUMBER_ALPHA[Integer.parseInt(String.valueOf(digits.charAt(i)))]; List newList = new ArrayList<>(); - for(int j = 0, l = str.length(); j < l; j ++) - { - for(String s : prev) - { + for (int j = 0, l = str.length(); j < l; j++) { + for (String s : prev) { s = str.charAt(j) + s; newList.add(s); } diff --git a/problems/src/backtracking/PalindromePartitioning.java b/problems/src/backtracking/PalindromePartitioning.java index 008aa5c7..822d1fd8 100644 --- a/problems/src/backtracking/PalindromePartitioning.java +++ b/problems/src/backtracking/PalindromePartitioning.java @@ -5,51 +5,43 @@ /** * Created by pradhang on 3/15/2017. - Given a string s, partition s such that every substring of the partition is a palindrome. - - Return all possible palindrome partitioning of s. - - For example, given s = "aab", - Return - - [ - ["aa","b"], - ["a","a","b"] - ] + * Given a string s, partition s such that every substring of the partition is a palindrome. + *

+ * Return all possible palindrome partitioning of s. + *

+ * For example, given s = "aab", + * Return + *

+ * [ + * ["aa","b"], + * ["a","a","b"] + * ] */ -public class PalindromePartitioning -{ +public class PalindromePartitioning { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List> result = new PalindromePartitioning().partition("aaaaaaaaaaaaaaaaaa"); } - public List> partition(String s) - { + public List> partition(String s) { List> result = new ArrayList<>(); doNext(0, new ArrayList<>(), s, result); return result; } - private void doNext(int i, List row, String s, List> result) - { - if(i == s.length()) - { + private void doNext(int i, List row, String s, List> result) { + if (i == s.length()) { List list = new ArrayList<>(row); result.add(list); - } - else - { - for(int j = i, l = s.length(); j < l; j++) - { + } else { + for (int j = i, l = s.length(); j < l; j++) { String sbStr = s.substring(i, j + 1); - if(isPalindrome(sbStr)) - { + if (isPalindrome(sbStr)) { row.add(sbStr); doNext(j + 1, row, s, result); row.remove(row.size() - 1); @@ -58,14 +50,13 @@ private void doNext(int i, List row, String s, List> result } } - private boolean isPalindrome(String s) - { + private boolean isPalindrome(String s) { int i = 0, j = s.length() - 1; - while(i <= j) - { - if(s.charAt(i) != s.charAt(j)) + while (i <= j) { + if (s.charAt(i) != s.charAt(j)) return false; - i++; j--; + i++; + j--; } return true; } diff --git a/problems/src/backtracking/Permutations.java b/problems/src/backtracking/Permutations.java index c74674d2..5f5ebc32 100644 --- a/problems/src/backtracking/Permutations.java +++ b/problems/src/backtracking/Permutations.java @@ -5,52 +5,45 @@ /** * Created by gouthamvidyapradhan on 15/03/2017. - Given a collection of distinct numbers, return all possible permutations. - - For example, - [1,2,3] have the following permutations: - [ - [1,2,3], - [1,3,2], - [2,1,3], - [2,3,1], - [3,1,2], - [3,2,1] - ] + * Given a collection of distinct numbers, return all possible permutations. + *

+ * For example, + * [1,2,3] have the following permutations: + * [ + * [1,2,3], + * [1,3,2], + * [2,1,3], + * [2,3,1], + * [3,1,2], + * [3,2,1] + * ] */ -public class Permutations -{ +public class Permutations { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] nums = {1, 2, 3}; List> result = new Permutations().permute(nums); } - public List> permute(int[] nums) - { + public List> permute(int[] nums) { List> result = new ArrayList<>(); nextPermutation(0, nums, result); return result; } - private void nextPermutation(int i, int[] nums, List> result) - { - if(i == nums.length - 1) - { + private void nextPermutation(int i, int[] nums, List> result) { + if (i == nums.length - 1) { List list = new ArrayList<>(); - for(int n : nums) + for (int n : nums) list.add(n); result.add(list); - } - else - { - for(int j = i, l = nums.length; j < l; j++) - { + } else { + for (int j = i, l = nums.length; j < l; j++) { int temp = nums[j]; nums[j] = nums[i]; nums[i] = temp; diff --git a/problems/src/backtracking/PermutationsII.java b/problems/src/backtracking/PermutationsII.java index 80829241..a2656886 100644 --- a/problems/src/backtracking/PermutationsII.java +++ b/problems/src/backtracking/PermutationsII.java @@ -6,54 +6,45 @@ /** * Created by gouthamvidyapradhan on 12/04/2017. - Given a collection of numbers that might contain duplicates, return all possible unique permutations. - - For example, - [1,1,2] have the following unique permutations: - [ - [1,1,2], - [1,2,1], - [2,1,1] - ] - + * Given a collection of numbers that might contain duplicates, return all possible unique permutations. + *

+ * For example, + * [1,1,2] have the following unique permutations: + * [ + * [1,1,2], + * [1,2,1], + * [2,1,1] + * ] */ -public class PermutationsII -{ - public static void main(String[] args) - { +public class PermutationsII { + public static void main(String[] args) { int[] A = {1, 2, 2}; System.out.println(new PermutationsII().permuteUnique(A)); } - public List> permuteUnique(int[] nums) - { + public List> permuteUnique(int[] nums) { List> result = new ArrayList<>(); Arrays.sort(nums); nextPermutation(0, nums, result); return result; } - private void nextPermutation(int i, int[] nums, List> result) - { - if(i == nums.length - 1) - { + private void nextPermutation(int i, int[] nums, List> result) { + if (i == nums.length - 1) { List list = new ArrayList<>(); - for(int n : nums) + for (int n : nums) list.add(n); result.add(list); - } - else - { - for(int j = i, l = nums.length; j < l; j++) - { - if(j > i && nums[j] == nums[i]) continue; + } else { + for (int j = i, l = nums.length; j < l; j++) { + if (j > i && nums[j] == nums[i]) continue; swap(nums, i, j); nextPermutation(i + 1, Arrays.copyOf(nums, nums.length), result); } } } - private void swap(int[] a, int i , int j){ + private void swap(int[] a, int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; diff --git a/problems/src/backtracking/Subsets.java b/problems/src/backtracking/Subsets.java index bbfef2a4..de74ac7a 100644 --- a/problems/src/backtracking/Subsets.java +++ b/problems/src/backtracking/Subsets.java @@ -5,46 +5,41 @@ /** * Created by gouthamvidyapradhan on 14/03/2017. - Given a set of distinct integers, nums, return all possible subsets. - - Note: The solution set must not contain duplicate subsets. - - For example, - If nums = [1,2,3], a solution is: - - [ - [3], - [1], - [2], - [1,2,3], - [1,3], - [2,3], - [1,2], - [] - ] - + * Given a set of distinct integers, nums, return all possible subsets. + *

+ * Note: The solution set must not contain duplicate subsets. + *

+ * For example, + * If nums = [1,2,3], a solution is: + *

+ * [ + * [3], + * [1], + * [2], + * [1,2,3], + * [1,3], + * [2,3], + * [1,2], + * [] + * ] */ -public class Subsets -{ +public class Subsets { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] n = {1, 2, 3}; List> result = new Subsets().subsets(n); } - public List> subsets(int[] nums) - { + public List> subsets(int[] nums) { List> result = new ArrayList<>(); result.add(new ArrayList<>()); //empty subset - for(int i = 0, l = nums.length; i < l; i ++) - { - for(int j = 0, resLen = result.size(); j < resLen; j++) - { + for (int i = 0, l = nums.length; i < l; i++) { + for (int j = 0, resLen = result.size(); j < resLen; j++) { List newList = new ArrayList<>(result.get(j)); newList.add(nums[i]); result.add(newList); diff --git a/problems/src/backtracking/SubsetsII.java b/problems/src/backtracking/SubsetsII.java index bfd93ecd..65a90795 100644 --- a/problems/src/backtracking/SubsetsII.java +++ b/problems/src/backtracking/SubsetsII.java @@ -6,50 +6,45 @@ /** * Created by gouthamvidyapradhan on 14/03/2017. - Given a collection of integers that might contain duplicates, nums, return all possible subsets. - - Note: The solution set must not contain duplicate subsets. - - For example, - If nums = [1,2,2], a solution is: - - [ - [2], - [1], - [1,2,2], - [2,2], - [1,2], - [] - ] + * Given a collection of integers that might contain duplicates, nums, return all possible subsets. + *

+ * Note: The solution set must not contain duplicate subsets. + *

+ * For example, + * If nums = [1,2,2], a solution is: + *

+ * [ + * [2], + * [1], + * [1,2,2], + * [2,2], + * [1,2], + * [] + * ] */ -public class SubsetsII -{ +public class SubsetsII { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] n = {1, 2, 3}; List> result = new SubsetsII().subsetsWithDup(n); } - public List> subsetsWithDup(int[] nums) - { + public List> subsetsWithDup(int[] nums) { List> result = new ArrayList<>(); result.add(new ArrayList<>()); //empty subset int start = 0, newStart = 0; Arrays.sort(nums); - for(int i = 0, l = nums.length; i < l; i ++) - { + for (int i = 0, l = nums.length; i < l; i++) { newStart = result.size(); - if(i == 0 || nums[i] != nums[i - 1]) - { + if (i == 0 || nums[i] != nums[i - 1]) { start = 0; } - for(int j = start, resLen = result.size(); j < resLen; j++) - { + for (int j = start, resLen = result.size(); j < resLen; j++) { List newList = new ArrayList<>(result.get(j)); newList.add(nums[i]); result.add(newList); diff --git a/problems/src/backtracking/WordSearch.java b/problems/src/backtracking/WordSearch.java index 3e4b409a..7032b201 100644 --- a/problems/src/backtracking/WordSearch.java +++ b/problems/src/backtracking/WordSearch.java @@ -2,55 +2,51 @@ /** * Created by PRADHANG on 4/13/2017. - Given a 2D board and a word, find if the word exists in the grid. - - The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once. - - For example, - Given board = - - [ - ['A','B','C','E'], - ['S','F','C','S'], - ['A','D','E','E'] - ] - word = "ABCCED", -> returns true, - word = "SEE", -> returns true, - word = "ABCB", -> returns false. + * Given a 2D board and a word, find if the word exists in the grid. + *

+ * The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once. + *

+ * For example, + * Given board = + *

+ * [ + * ['A','B','C','E'], + * ['S','F','C','S'], + * ['A','D','E','E'] + * ] + * word = "ABCCED", -> returns true, + * word = "SEE", -> returns true, + * word = "ABCB", -> returns false. */ -public class WordSearch -{ - private static final int[] R = {0,0,1,-1}; - private static final int[] C = {1,-1,0,0}; +public class WordSearch { + private static final int[] R = {0, 0, 1, -1}; + private static final int[] C = {1, -1, 0, 0}; private static boolean[][] visited; private static int length = 0, N, M; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { char[][] board = { {'A'} }; System.out.println(new WordSearch().exist(board, "A")); } - public boolean exist(char[][] board, String word) - { + public boolean exist(char[][] board, String word) { N = board.length; M = board[0].length; - if(N * M < word.length()) return false; + if (N * M < word.length()) return false; visited = new boolean[N][M]; length = word.length(); - for (int i = 0 ; i < N; i ++) - { - for (int j = 0 ; j < M; j ++) - { - if(board[i][j] == word.charAt(0)) - { - if(dfs(i, j, board, word, 1)) return true; + for (int i = 0; i < N; i++) { + for (int j = 0; j < M; j++) { + if (board[i][j] == word.charAt(0)) { + if (dfs(i, j, board, word, 1)) return true; visited[i][j] = false; } } @@ -58,29 +54,22 @@ public boolean exist(char[][] board, String word) return false; } - private boolean dfs(int r, int c, char[][] board, String word, int pos) - { - if(pos < length) - { + private boolean dfs(int r, int c, char[][] board, String word, int pos) { + if (pos < length) { visited[r][c] = true; - for(int i = 0; i < 4; i ++) - { + for (int i = 0; i < 4; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >= 0 && newR < N && newC >= 0 && newC < M) - { - if(!visited[newR][newC]) - { - if(board[newR][newC] == word.charAt(pos)) - { - if(dfs(newR, newC, board, word, pos + 1)) return true; + if (newR >= 0 && newR < N && newC >= 0 && newC < M) { + if (!visited[newR][newC]) { + if (board[newR][newC] == word.charAt(pos)) { + if (dfs(newR, newC, board, word, pos + 1)) return true; visited[newR][newC] = false; } } } } - } - else return true; + } else return true; return false; } } diff --git a/problems/src/backtracking/WordSearchII.java b/problems/src/backtracking/WordSearchII.java index bf4333e2..bbd2b453 100644 --- a/problems/src/backtracking/WordSearchII.java +++ b/problems/src/backtracking/WordSearchII.java @@ -5,21 +5,21 @@ /** * Created by pradhang on 7/4/2017. * Given a 2D board and a list of words from the dictionary, find all words in the board. - - Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word. - - For example, - Given words = ["oath","pea","eat","rain"] and board = - - [ - ['o','a','a','n'], - ['e','t','a','e'], - ['i','h','k','r'], - ['i','f','l','v'] - ] - Return ["eat","oath"]. - Note: - You may assume that all inputs are consist of lowercase letters a-z. + *

+ * Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word. + *

+ * For example, + * Given words = ["oath","pea","eat","rain"] and board = + *

+ * [ + * ['o','a','a','n'], + * ['e','t','a','e'], + * ['i','h','k','r'], + * ['i','f','l','v'] + * ] + * Return ["eat","oath"]. + * Note: + * You may assume that all inputs are consist of lowercase letters a-z. */ public class WordSearchII { private final int[] R = {0, 0, -1, 1}; @@ -27,41 +27,41 @@ public class WordSearchII { boolean[][] visited; private Set dictionary; - public static void main(String[] args) throws Exception{ - char[][] board = {{'o','a','a','n'},{'e','t','a','e'},{'i','h','k','r'},{'i','f','l','v'}}; - String[] words = {"oath","pea","eat","rain"}; + public static void main(String[] args) throws Exception { + char[][] board = {{'o', 'a', 'a', 'n'}, {'e', 't', 'a', 'e'}, {'i', 'h', 'k', 'r'}, {'i', 'f', 'l', 'v'}}; + String[] words = {"oath", "pea", "eat", "rain"}; System.out.println(new WordSearchII().findWords(board, words)); } public List findWords(char[][] board, String[] words) { dictionary = new HashSet<>(); Trie trie = new Trie(); - for(String w : words){ + for (String w : words) { trie.insert(w); dictionary.add(w); } visited = new boolean[board.length][board[0].length]; Set resultSet = new HashSet<>(); - for(int i = 0; i < board.length; i ++){ - for(int j = 0; j < board[0].length; j++){ + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { dfs(i, j, board, resultSet, trie, String.valueOf(board[i][j])); } } return new ArrayList<>(resultSet); } - private void dfs(int r, int c, char[][] board, Set result, Trie trie, String s){ + private void dfs(int r, int c, char[][] board, Set result, Trie trie, String s) { char newChar = board[r][c]; Trie subTrie = trie.next(newChar); - if(subTrie == null) return; + if (subTrie == null) return; visited[r][c] = true; - if(dictionary.contains(s)) + if (dictionary.contains(s)) result.add(s); - for(int i = 0; i < 4; i ++){ + for (int i = 0; i < 4; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length){ - if(!visited[newR][newC]){ + if (newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length) { + if (!visited[newR][newC]) { dfs(newR, newC, board, result, subTrie, s + board[newR][newC]); } } @@ -73,37 +73,41 @@ private class Trie { private Map map; - /** Initialize your data structure here. */ + /** + * Initialize your data structure here. + */ public Trie() { map = new HashMap<>(); } - /** Inserts a word into the trie. */ + /** + * Inserts a word into the trie. + */ public void insert(String word) { - if(word != null){ + if (word != null) { add(0, word, word.length()); } } - private void add(int i, String word, int length){ - if(i < length){ + private void add(int i, String word, int length) { + if (i < length) { char c = word.charAt(i); Trie subTrie = map.get(c); - if(subTrie == null){ + if (subTrie == null) { subTrie = new Trie(); map.put(c, subTrie); } subTrie.add(i + 1, word, length); - } - else map.put(null, new Trie()); //use null to indicate end of string + } else map.put(null, new Trie()); //use null to indicate end of string } /** * Get next Trie node + * * @param c char c * @return return Trie */ - public Trie next(char c){ + public Trie next(char c) { return this.map.get(c); } } diff --git a/problems/src/binary_search/FindPeakElement.java b/problems/src/binary_search/FindPeakElement.java index ae6e8ba2..6421f86b 100644 --- a/problems/src/binary_search/FindPeakElement.java +++ b/problems/src/binary_search/FindPeakElement.java @@ -3,48 +3,47 @@ /** * Created by gouthamvidyapradhan on 10/07/2017. * A peak element is an element that is greater than its neighbors. - - Given an input array where num[i] ≠ num[i+1], find a peak element and return its index. - - The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. - - You may imagine that num[-1] = num[n] = -∞. - - For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. - - Note: - Your solution should be in logarithmic complexity. - - Solution: O(log N) check if the first or the last element is the peak element, if yes then return this index. - Else binary search for the answer - check mid element if this is a peak element return this index, else if the - left element is greater than current element search left else search right. + *

+ * Given an input array where num[i] ≠ num[i+1], find a peak element and return its index. + *

+ * The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. + *

+ * You may imagine that num[-1] = num[n] = -∞. + *

+ * For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. + *

+ * Note: + * Your solution should be in logarithmic complexity. + *

+ * Solution: O(log N) check if the first or the last element is the peak element, if yes then return this index. + * Else binary search for the answer - check mid element if this is a peak element return this index, else if the + * left element is greater than current element search left else search right. */ public class FindPeakElement { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] nums = {3, 4, 3, 2, 1}; System.out.println(new FindPeakElement().findPeakElement(nums)); } public int findPeakElement(int[] nums) { - if(nums.length == 1)return 0; - if(nums[0] > nums[1]) + if (nums.length == 1) return 0; + if (nums[0] > nums[1]) return 0; - else if(nums[nums.length - 1] > nums[nums.length - 2]) + else if (nums[nums.length - 1] > nums[nums.length - 2]) return nums.length - 1; int l = 0, h = nums.length - 1; int ans = 0; - while(l <= h){ + while (l <= h) { int m = l + (h - l) / 2; - if(m - 1 >= 0 && m + 1 < nums.length){ - if(nums[m] > nums[m - 1] && nums[m] > nums[m + 1]){ + if (m - 1 >= 0 && m + 1 < nums.length) { + if (nums[m] > nums[m - 1] && nums[m] > nums[m + 1]) { return m; } } - if(m - 1 >= 0 && nums[m - 1] > nums[m]){ //search left + if (m - 1 >= 0 && nums[m - 1] > nums[m]) { //search left h = m - 1; - } - else { + } else { ans = l; //mark this as the answer and search right l = m + 1; } diff --git a/problems/src/binary_search/MedianOfTwoSortedArrays.java b/problems/src/binary_search/MedianOfTwoSortedArrays.java index fcc60c86..e6bdc86c 100644 --- a/problems/src/binary_search/MedianOfTwoSortedArrays.java +++ b/problems/src/binary_search/MedianOfTwoSortedArrays.java @@ -6,91 +6,87 @@ /** * Created by gouthamvidyapradhan on 23/05/2017. - There are two sorted arrays nums1 and nums2 of size m and n respectively. - - Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). - - Example 1: - nums1 = [1, 3] - nums2 = [2] - - The median is 2.0 - Example 2: - nums1 = [1, 2] - nums2 = [3, 4] - - The median is (2 + 3)/2 = 2.5 - - Solution: Works in worst case time complexity of O(log min(m, n)) - - The basic idea is that if you are given two arrays A and B and know - the length of each, you can check whether an element A[i] is the median in constant - time. Suppose that the median is A[i]. Since the array is sorted, it is greater than - exactly i − 1 values in array A. Then if it is the median, it is also greater than exactly - j = [n / 2] − (i − 1) elements in B. It requires constant time to check if B[j] - A[i] <= B[j + 1]. If A[i] is not the median, then depending on whether A[i] is greater - or less than B[j] and B[j + 1], you know that A[i] is either greater than or less than - the median. Thus you can binary search for A[i] in O(log N) worst-case time - + * There are two sorted arrays nums1 and nums2 of size m and n respectively. + *

+ * Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). + *

+ * Example 1: + * nums1 = [1, 3] + * nums2 = [2] + *

+ * The median is 2.0 + * Example 2: + * nums1 = [1, 2] + * nums2 = [3, 4] + *

+ * The median is (2 + 3)/2 = 2.5 + *

+ * Solution: Works in worst case time complexity of O(log min(m, n)) + *

+ * The basic idea is that if you are given two arrays A and B and know + * the length of each, you can check whether an element A[i] is the median in constant + * time. Suppose that the median is A[i]. Since the array is sorted, it is greater than + * exactly i − 1 values in array A. Then if it is the median, it is also greater than exactly + * j = [n / 2] − (i − 1) elements in B. It requires constant time to check if B[j] + * A[i] <= B[j + 1]. If A[i] is not the median, then depending on whether A[i] is greater + * or less than B[j] and B[j + 1], you know that A[i] is either greater than or less than + * the median. Thus you can binary search for A[i] in O(log N) worst-case time */ -public class MedianOfTwoSortedArrays -{ +public class MedianOfTwoSortedArrays { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] A = {1,2,5,8,44,45,45}; - int[] B = {1, 2, 3,4,5,6,7,23,23,23,33,44,45,45,56,77,5555}; + public static void main(String[] args) throws Exception { + int[] A = {1, 2, 5, 8, 44, 45, 45}; + int[] B = {1, 2, 3, 4, 5, 6, 7, 23, 23, 23, 33, 44, 45, 45, 56, 77, 5555}; System.out.println(new MedianOfTwoSortedArrays().findMedianSortedArrays(A, B)); } /** * Find median + * * @param nums1 array one * @param nums2 array two * @return */ - public double findMedianSortedArrays(int[] nums1, int[] nums2) - { - if(nums1.length > nums2.length) + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + if (nums1.length > nums2.length) return findMedianSortedArrays(nums2, nums1); //ensure always nums1 is the shortest array int T = nums1.length + nums2.length, low = -1, high = -1; int median = (T - 1) / 2; boolean isOdd = false; - if((T % 2) != 0) + if ((T % 2) != 0) isOdd = true; int s = 0, e = nums1.length - 1; - while(s <= e) { + while (s <= e) { int m = s + (e - s) / 2; - if((median - m - 1) < 0 || nums1[m] >= nums2[median - m - 1]) { + if ((median - m - 1) < 0 || nums1[m] >= nums2[median - m - 1]) { e = m - 1; low = m; high = median - m; - } - else s = m + 1; + } else s = m + 1; } - if(low == -1) { - if(isOdd) return nums2[median - nums1.length]; - else return (double)(nums2[median - nums1.length] + nums2[median - nums1.length + 1]) / 2.0D; - } - else { - if(isOdd) return nums1[low] < nums2[high] ? nums1[low] : nums2[high]; + if (low == -1) { + if (isOdd) return nums2[median - nums1.length]; + else return (double) (nums2[median - nums1.length] + nums2[median - nums1.length + 1]) / 2.0D; + } else { + if (isOdd) return nums1[low] < nums2[high] ? nums1[low] : nums2[high]; else { //Always sorts maximum of 4 elements hence works in O(1) List list = new ArrayList<>(); list.add(nums1[low]); - if(low + 1 < nums1.length) + if (low + 1 < nums1.length) list.add(nums1[low + 1]); list.add(nums2[high]); - if(high + 1 < nums2.length) + if (high + 1 < nums2.length) list.add(nums2[high + 1]); Collections.sort(list); - return (double)(list.get(0) + list.get(1)) / 2.0; + return (double) (list.get(0) + list.get(1)) / 2.0; } } } diff --git a/problems/src/binary_search/MinSortedRotatedArray.java b/problems/src/binary_search/MinSortedRotatedArray.java index 9ae7e843..7c107bc3 100644 --- a/problems/src/binary_search/MinSortedRotatedArray.java +++ b/problems/src/binary_search/MinSortedRotatedArray.java @@ -2,40 +2,37 @@ /** * Created by gouthamvidyapradhan on 10/04/2017. - Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. - - (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). - - Find the minimum element. - - You may assume no duplicate exists in the array. + * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. + *

+ * (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + *

+ * Find the minimum element. + *

+ * You may assume no duplicate exists in the array. */ -public class MinSortedRotatedArray -{ +public class MinSortedRotatedArray { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] A = {5, 1, 2, 3, 4}; System.out.println(new MinSortedRotatedArray().findMin(A)); } - public int findMin(int[] nums) - { - if(nums.length == 0) return 0; - else if(nums.length == 1) return nums[0]; + public int findMin(int[] nums) { + if (nums.length == 0) return 0; + else if (nums.length == 1) return nums[0]; int low = 0, high = nums.length - 1; - while(low < high) - { + while (low < high) { int mid = (low + high) / 2; - if(mid > 0 && nums[mid] < nums[mid - 1]) + if (mid > 0 && nums[mid] < nums[mid - 1]) return nums[mid]; - if(nums[low] > nums[mid]) + if (nums[low] > nums[mid]) high = mid - 1; - else if(nums[high] < nums[mid]) + else if (nums[high] < nums[mid]) low = mid + 1; else high = mid - 1; } diff --git a/problems/src/binary_search/PowXN.java b/problems/src/binary_search/PowXN.java index eeb5457c..da3e1a78 100644 --- a/problems/src/binary_search/PowXN.java +++ b/problems/src/binary_search/PowXN.java @@ -2,33 +2,30 @@ /** * Created by gouthamvidyapradhan on 23/05/2017. - - Implement pow(x, n). - - Solution: Works with O(log n) + *

+ * Implement pow(x, n). + *

+ * Solution: Works with O(log n) */ -public class PowXN -{ +public class PowXN { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(1 / new PowXN().myPow(2.00000, -2147483648)); } - public double myPow(double x, int n) - { - if(n == 0) return 1D; + public double myPow(double x, int n) { + if (n == 0) return 1D; long N = n; //use long to avoid overflow. return solve(n < 0 ? (1 / x) : x, N < 0 ? (N * -1) : N); } - public double solve(double x, long n) - { - if(n == 1) return x; + public double solve(double x, long n) { + if (n == 1) return x; double val = solve(x, n / 2); return val * val * ((n % 2) == 0 ? 1 : x); } diff --git a/problems/src/binary_search/SearchForARange.java b/problems/src/binary_search/SearchForARange.java index 2d806a7a..b75192c8 100644 --- a/problems/src/binary_search/SearchForARange.java +++ b/problems/src/binary_search/SearchForARange.java @@ -2,22 +2,20 @@ /** * Created by gouthamvidyapradhan on 20/05/2017. - Given an array of integers sorted in ascending order, find the starting and ending position of a given target value. - - Your algorithm's runtime complexity must be in the order of O(log n). - - If the target is not found in the array, return [-1, -1]. - - For example, - Given [5, 7, 7, 8, 8, 10] and target value 8, - return [3, 4]. - - Solution: Works with worst case time complexity of O(log n). Recursively binary search to find the target index. + * Given an array of integers sorted in ascending order, find the starting and ending position of a given target value. + *

+ * Your algorithm's runtime complexity must be in the order of O(log n). + *

+ * If the target is not found in the array, return [-1, -1]. + *

+ * For example, + * Given [5, 7, 7, 8, 8, 10] and target value 8, + * return [3, 4]. + *

+ * Solution: Works with worst case time complexity of O(log n). Recursively binary search to find the target index. */ -public class SearchForARange -{ - public static void main(String[] args) throws Exception - { +public class SearchForARange { + public static void main(String[] args) throws Exception { int[] test = {5, 7, 7, 8, 8, 10, 10, 10, 10, 18, 19, 20, 21, 21, 21, 21, 22, 23, 28, 28, 90, 101, 101, 101, 200, 200, 200, 200, 200, 200}; int[] result = new SearchForARange().searchRange(test, 200); @@ -36,26 +34,25 @@ public int[] searchRange(int[] nums, int target) { /** * Find index - * @param nums nums array - * @param target target + * + * @param nums nums array + * @param target target * @param isLowerIndex true if target is to find lower index, false otherwise * @return index */ - private int findIndex(int[] nums, int target, boolean isLowerIndex){ + private int findIndex(int[] nums, int target, boolean isLowerIndex) { int result = -1; int s = 0, e = nums.length - 1; - while(s <= e) { + while (s <= e) { int m = s + (e - s) / 2; - if(nums[m] == target) { + if (nums[m] == target) { result = m; - if(isLowerIndex) e = m - 1; //if searching for the lower index then search the lower bound, + if (isLowerIndex) e = m - 1; //if searching for the lower index then search the lower bound, // else search the upper bound else s = m + 1; - } - else if(nums[m] < target){ + } else if (nums[m] < target) { s = m + 1; - } - else e = m - 1; + } else e = m - 1; } return result; } diff --git a/problems/src/binary_search/SearchInsertPosition.java b/problems/src/binary_search/SearchInsertPosition.java index 31a28d49..d054cb24 100644 --- a/problems/src/binary_search/SearchInsertPosition.java +++ b/problems/src/binary_search/SearchInsertPosition.java @@ -2,37 +2,31 @@ /** * Created by gouthamvidyapradhan on 22/05/2017. - Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. - - You may assume no duplicates in the array. - - Here are few examples. - [1,3,5,6], 5 → 2 - [1,3,5,6], 2 → 1 - [1,3,5,6], 7 → 4 - [1,3,5,6], 0 → 0 + * Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. + *

+ * You may assume no duplicates in the array. + *

+ * Here are few examples. + * [1,3,5,6], 5 → 2 + * [1,3,5,6], 2 → 1 + * [1,3,5,6], 7 → 4 + * [1,3,5,6], 0 → 0 */ -public class SearchInsertPosition -{ - public static void main(String[] args) throws Exception - { +public class SearchInsertPosition { + public static void main(String[] args) throws Exception { int[] A = {1, 3, 5, 6}; new SearchInsertPosition().searchInsert(A, 5); } - public int searchInsert(int[] nums, int target) - { + public int searchInsert(int[] nums, int target) { int pos = nums.length; int s = 0, e = nums.length - 1; - while(s <= e) - { + while (s <= e) { int m = s + (e - s) / 2; - if(nums[m] >= target) - { + if (nums[m] >= target) { pos = m; e = m - 1; - } - else s = m + 1; + } else s = m + 1; } return pos; } diff --git a/problems/src/binary_search/SearchRotatedSortedArray.java b/problems/src/binary_search/SearchRotatedSortedArray.java index 28e27423..755a608b 100644 --- a/problems/src/binary_search/SearchRotatedSortedArray.java +++ b/problems/src/binary_search/SearchRotatedSortedArray.java @@ -2,42 +2,37 @@ /** * Created by gouthamvidyapradhan on 10/04/2017. - Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. - - (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). - - You are given a target value to search. If found in the array return its index, otherwise return -1. - - You may assume no duplicate exists in the array. - + * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. + *

+ * (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + *

+ * You are given a target value to search. If found in the array return its index, otherwise return -1. + *

+ * You may assume no duplicate exists in the array. */ -public class SearchRotatedSortedArray -{ +public class SearchRotatedSortedArray { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] A = {5, 4, 3, 2, 1}; System.out.println(new SearchRotatedSortedArray().search(A, 4)); } - public int search(int[] nums, int target) - { - if(nums.length == 0) return -1; - if(nums.length == 1) - { + public int search(int[] nums, int target) { + if (nums.length == 0) return -1; + if (nums.length == 1) { return (nums[0] == target) ? 0 : -1; } int low = 0, high = nums.length - 1; - while(low < high) - { + while (low < high) { int mid = (low + high) >>> 1; - if(nums[mid] == target) + if (nums[mid] == target) return mid; - if((nums[mid] <= nums[low]) && (target > nums[mid] && target <= nums[high]) || + if ((nums[mid] <= nums[low]) && (target > nums[mid] && target <= nums[high]) || (nums[low] <= nums[mid] && (target < nums[low] || target > nums[mid]))) low = mid + 1; else high = mid - 1; diff --git a/problems/src/binary_search/SqrtX.java b/problems/src/binary_search/SqrtX.java index 4f008ff6..ef9e191b 100644 --- a/problems/src/binary_search/SqrtX.java +++ b/problems/src/binary_search/SqrtX.java @@ -2,33 +2,27 @@ /** * Created by gouthamvidyapradhan on 22/05/2017. - Implement int sqrt(int x). - - Compute and return the square root of x. + * Implement int sqrt(int x). + *

+ * Compute and return the square root of x. */ -public class SqrtX -{ - public static void main(String[] args) throws Exception - { +public class SqrtX { + public static void main(String[] args) throws Exception { System.out.println(new SqrtX().mySqrt(Integer.MAX_VALUE)); } - public int mySqrt(int x) - { + public int mySqrt(int x) { int s = 0, e = x; long ans = 0L; - while(s <= e) - { + while (s <= e) { long m = s + (e - s) / 2; long prod = m * m; - if(prod <= x) - { - s = (int)(m + 1); + if (prod <= x) { + s = (int) (m + 1); ans = m; - } - else e = (int)m - 1; + } else e = (int) m - 1; } - return (int)ans; + return (int) ans; } diff --git a/problems/src/bit_manipulation/GrayCode.java b/problems/src/bit_manipulation/GrayCode.java index 6c50336a..9db5ce92 100644 --- a/problems/src/bit_manipulation/GrayCode.java +++ b/problems/src/bit_manipulation/GrayCode.java @@ -1,43 +1,42 @@ package bit_manipulation; -import java.util.*; +import java.util.ArrayList; +import java.util.List; /** * Created by gouthamvidyapradhan on 16/03/2017. - The gray code is a binary numeral system where two successive values differ in only one bit. - - Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0. - - For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: - - 00 - 0 - 01 - 1 - 11 - 3 - 10 - 2 - Note: - For a given n, a gray code sequence is not uniquely defined. - - For example, [0,2,3,1] is also a valid gray code sequence according to the above definition. - - For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that. + * The gray code is a binary numeral system where two successive values differ in only one bit. + *

+ * Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0. + *

+ * For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: + *

+ * 00 - 0 + * 01 - 1 + * 11 - 3 + * 10 - 2 + * Note: + * For a given n, a gray code sequence is not uniquely defined. + *

+ * For example, [0,2,3,1] is also a valid gray code sequence according to the above definition. + *

+ * For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that. */ -public class GrayCode -{ +public class GrayCode { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List result = new GrayCode().grayCode(3); } - public List grayCode(int n) - { + public List grayCode(int n) { List result = new ArrayList<>(); - for(int i = 0; i <= ((1 << n) - 1); i ++) + for (int i = 0; i <= ((1 << n) - 1); i++) result.add(i ^ (i >> 1)); return result; } diff --git a/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java b/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java index 5df4b49d..a266ddc0 100644 --- a/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java +++ b/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java @@ -7,50 +7,50 @@ /** * Created by gouthamvidyapradhan on 13/03/2017. - Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). - - For example: - Given binary tree [3,9,20,null,null,15,7], - 3 - / \ - 9 20 - / \ - 15 7 - return its level order traversal as: - [ - [3], - [9,20], - [15,7] - ] - + * Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). + *

+ * For example: + * Given binary tree [3,9,20,null,null,15,7], + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * return its level order traversal as: + * [ + * [3], + * [9,20], + * [15,7] + * ] */ -public class BinarayTreeLevelOrderTraversal -{ - public static class TreeNode - { +public class BinarayTreeLevelOrderTraversal { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - private class LevelNode - { + private class LevelNode { TreeNode node; int level; - LevelNode(TreeNode node, int level) - { + + LevelNode(TreeNode node, int level) { this.node = node; this.level = level; } } + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(2); root.left = new TreeNode(3); root.right = new TreeNode(4); @@ -64,21 +64,17 @@ public static void main(String[] args) throws Exception List> result = new BinarayTreeLevelOrderTraversal().levelOrder(root); } - public List> levelOrder(TreeNode root) - { + public List> levelOrder(TreeNode root) { List> result = new ArrayList<>(); - if(root == null) return result; + if (root == null) return result; Queue queue = new ArrayDeque<>(); queue.offer(new LevelNode(root, 0)); int currentLevel = 0; List row = new ArrayList<>(); - while(!queue.isEmpty()) - { + while (!queue.isEmpty()) { LevelNode levelNode = queue.poll(); - if(levelNode.node != null) - { - if(levelNode.level != currentLevel) - { + if (levelNode.node != null) { + if (levelNode.level != currentLevel) { result.add(row); row = new ArrayList<>(); currentLevel++; diff --git a/problems/src/breadth_first_search/WordLadder.java b/problems/src/breadth_first_search/WordLadder.java index af7cefa1..c7a4444d 100644 --- a/problems/src/breadth_first_search/WordLadder.java +++ b/problems/src/breadth_first_search/WordLadder.java @@ -4,35 +4,33 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. - Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: - - Only one letter can be changed at a time. - Each transformed word must exist in the word list. Note that beginWord is not a transformed word. - For example, - - Given: - beginWord = "hit" - endWord = "cog" - wordList = ["hot","dot","dog","lot","log","cog"] - As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", - return its length 5. - - Note: - Return 0 if there is no such transformation sequence. - All words have the same length. - All words contain only lowercase alphabetic characters. - You may assume no duplicates in the word list. - You may assume beginWord and endWord are non-empty and are not the same. + * Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: + *

+ * Only one letter can be changed at a time. + * Each transformed word must exist in the word list. Note that beginWord is not a transformed word. + * For example, + *

+ * Given: + * beginWord = "hit" + * endWord = "cog" + * wordList = ["hot","dot","dog","lot","log","cog"] + * As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", + * return its length 5. + *

+ * Note: + * Return 0 if there is no such transformation sequence. + * All words have the same length. + * All words contain only lowercase alphabetic characters. + * You may assume no duplicates in the word list. + * You may assume beginWord and endWord are non-empty and are not the same. */ -public class WordLadder -{ +public class WordLadder { - class State - { + class State { String word; int len; - State(String word, int len) - { + + State(String word, int len) { this.word = word; this.len = len; } @@ -42,13 +40,14 @@ class State private static Set dictionary = new HashSet<>(); private static final String CONST = "abcdefghijklmnopqrstuvwxyz"; private static Set done = new HashSet<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List list = new ArrayList<>(); list.add("hot"); list.add("dot"); @@ -60,27 +59,21 @@ public static void main(String[] args) throws Exception } - public int ladderLength(String beginWord, String endWord, List wordList) - { + public int ladderLength(String beginWord, String endWord, List wordList) { dictionary.addAll(wordList); queue.offer(new State(beginWord, 0)); done.add(beginWord); - while(!queue.isEmpty()) - { + while (!queue.isEmpty()) { State head = queue.poll(); - if(head.word.equals(endWord)) + if (head.word.equals(endWord)) return head.len + 1; - for(int i = 0, l = CONST.length(); i < l; i ++ ) - { + for (int i = 0, l = CONST.length(); i < l; i++) { StringBuilder word = new StringBuilder(head.word); - for(int j = 0, ln = word.length(); j < ln; j ++ ) - { + for (int j = 0, ln = word.length(); j < ln; j++) { char old = word.charAt(j); word.replace(j, j + 1, String.valueOf(CONST.charAt(i))); - if(!done.contains(word.toString())) - { - if(dictionary.contains(word.toString())) - { + if (!done.contains(word.toString())) { + if (dictionary.contains(word.toString())) { done.add(word.toString()); queue.offer(new State(word.toString(), head.len + 1)); } diff --git a/problems/src/breadth_first_search/WordLadderII.java b/problems/src/breadth_first_search/WordLadderII.java index 8df6bb21..f25325d4 100644 --- a/problems/src/breadth_first_search/WordLadderII.java +++ b/problems/src/breadth_first_search/WordLadderII.java @@ -4,30 +4,29 @@ /** * Created by gouthamvidyapradhan on 24/03/2017. - Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: - - Only one letter can be changed at a time - Each transformed word must exist in the word list. Note that beginWord is not a transformed word. - For example, - - Given: - beginWord = "hit" - endWord = "cog" - wordList = ["hot","dot","dog","lot","log","cog"] - Return - [ - ["hit","hot","dot","dog","cog"], - ["hit","hot","lot","log","cog"] - ] - Note: - Return an empty list if there is no such transformation sequence. - All words have the same length. - All words contain only lowercase alphabetic characters. - You may assume no duplicates in the word list. - You may assume beginWord and endWord are non-empty and are not the same. + * Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: + *

+ * Only one letter can be changed at a time + * Each transformed word must exist in the word list. Note that beginWord is not a transformed word. + * For example, + *

+ * Given: + * beginWord = "hit" + * endWord = "cog" + * wordList = ["hot","dot","dog","lot","log","cog"] + * Return + * [ + * ["hit","hot","dot","dog","cog"], + * ["hit","hot","lot","log","cog"] + * ] + * Note: + * Return an empty list if there is no such transformation sequence. + * All words have the same length. + * All words contain only lowercase alphabetic characters. + * You may assume no duplicates in the word list. + * You may assume beginWord and endWord are non-empty and are not the same. */ -public class WordLadderII -{ +public class WordLadderII { private static Queue queue = new ArrayDeque<>(); private static Set dictionary = new HashSet<>(); @@ -37,20 +36,18 @@ public class WordLadderII private static List> result = new ArrayList<>(); - /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - List dic = Arrays.asList("kid","tag","pup","ail","tun","woo","erg","luz","brr","gay","sip","kay","per","val","mes","ohs","now","boa","cet","pal","bar","die","war","hay","eco","pub","lob","rue","fry","lit","rex","jan","cot","bid","ali","pay","col","gum","ger","row","won","dan","rum","fad","tut","sag","yip","sui","ark","has","zip","fez","own","ump","dis","ads","max","jaw","out","btu","ana","gap","cry","led","abe","box","ore","pig","fie","toy","fat","cal","lie","noh","sew","ono","tam","flu","mgm","ply","awe","pry","tit","tie","yet","too","tax","jim","san","pan","map","ski","ova","wed","non","wac","nut","why","bye","lye","oct","old","fin","feb","chi","sap","owl","log","tod","dot","bow","fob","for","joe","ivy","fan","age","fax","hip","jib","mel","hus","sob","ifs","tab","ara","dab","jag","jar","arm","lot","tom","sax","tex","yum","pei","wen","wry","ire","irk","far","mew","wit","doe","gas","rte","ian","pot","ask","wag","hag","amy","nag","ron","soy","gin","don","tug","fay","vic","boo","nam","ave","buy","sop","but","orb","fen","paw","his","sub","bob","yea","oft","inn","rod","yam","pew","web","hod","hun","gyp","wei","wis","rob","gad","pie","mon","dog","bib","rub","ere","dig","era","cat","fox","bee","mod","day","apr","vie","nev","jam","pam","new","aye","ani","and","ibm","yap","can","pyx","tar","kin","fog","hum","pip","cup","dye","lyx","jog","nun","par","wan","fey","bus","oak","bad","ats","set","qom","vat","eat","pus","rev","axe","ion","six","ila","lao","mom","mas","pro","few","opt","poe","art","ash","oar","cap","lop","may","shy","rid","bat","sum","rim","fee","bmw","sky","maj","hue","thy","ava","rap","den","fla","auk","cox","ibo","hey","saw","vim","sec","ltd","you","its","tat","dew","eva","tog","ram","let","see","zit","maw","nix","ate","gig","rep","owe","ind","hog","eve","sam","zoo","any","dow","cod","bed","vet","ham","sis","hex","via","fir","nod","mao","aug","mum","hoe","bah","hal","keg","hew","zed","tow","gog","ass","dem","who","bet","gos","son","ear","spy","kit","boy","due","sen","oaf","mix","hep","fur","ada","bin","nil","mia","ewe","hit","fix","sad","rib","eye","hop","haw","wax","mid","tad","ken","wad","rye","pap","bog","gut","ito","woe","our","ado","sin","mad","ray","hon","roy","dip","hen","iva","lug","asp","hui","yak","bay","poi","yep","bun","try","lad","elm","nat","wyo","gym","dug","toe","dee","wig","sly","rip","geo","cog","pas","zen","odd","nan","lay","pod","fit","hem","joy","bum","rio","yon","dec","leg","put","sue","dim","pet","yaw","nub","bit","bur","sid","sun","oil","red","doc","moe","caw","eel","dix","cub","end","gem","off","yew","hug","pop","tub","sgt","lid","pun","ton","sol","din","yup","jab","pea","bug","gag","mil","jig","hub","low","did","tin","get","gte","sox","lei","mig","fig","lon","use","ban","flo","nov","jut","bag","mir","sty","lap","two","ins","con","ant","net","tux","ode","stu","mug","cad","nap","gun","fop","tot","sow","sal","sic","ted","wot","del","imp","cob","way","ann","tan","mci","job","wet","ism","err","him","all","pad","hah","hie","aim","ike","jed","ego","mac","baa","min","com","ill","was","cab","ago","ina","big","ilk","gal","tap","duh","ola","ran","lab","top","gob","hot","ora","tia","kip","han","met","hut","she","sac","fed","goo","tee","ell","not","act","gil","rut","ala","ape","rig","cid","god","duo","lin","aid","gel","awl","lag","elf","liz","ref","aha","fib","oho","tho","her","nor","ace","adz","fun","ned","coo","win","tao","coy","van","man","pit","guy","foe","hid","mai","sup","jay","hob","mow","jot","are","pol","arc","lax","aft","alb","len","air","pug","pox","vow","got","meg","zoe","amp","ale","bud","gee","pin","dun","pat","ten","mob"); + public static void main(String[] args) throws Exception { + List dic = Arrays.asList("kid", "tag", "pup", "ail", "tun", "woo", "erg", "luz", "brr", "gay", "sip", "kay", "per", "val", "mes", "ohs", "now", "boa", "cet", "pal", "bar", "die", "war", "hay", "eco", "pub", "lob", "rue", "fry", "lit", "rex", "jan", "cot", "bid", "ali", "pay", "col", "gum", "ger", "row", "won", "dan", "rum", "fad", "tut", "sag", "yip", "sui", "ark", "has", "zip", "fez", "own", "ump", "dis", "ads", "max", "jaw", "out", "btu", "ana", "gap", "cry", "led", "abe", "box", "ore", "pig", "fie", "toy", "fat", "cal", "lie", "noh", "sew", "ono", "tam", "flu", "mgm", "ply", "awe", "pry", "tit", "tie", "yet", "too", "tax", "jim", "san", "pan", "map", "ski", "ova", "wed", "non", "wac", "nut", "why", "bye", "lye", "oct", "old", "fin", "feb", "chi", "sap", "owl", "log", "tod", "dot", "bow", "fob", "for", "joe", "ivy", "fan", "age", "fax", "hip", "jib", "mel", "hus", "sob", "ifs", "tab", "ara", "dab", "jag", "jar", "arm", "lot", "tom", "sax", "tex", "yum", "pei", "wen", "wry", "ire", "irk", "far", "mew", "wit", "doe", "gas", "rte", "ian", "pot", "ask", "wag", "hag", "amy", "nag", "ron", "soy", "gin", "don", "tug", "fay", "vic", "boo", "nam", "ave", "buy", "sop", "but", "orb", "fen", "paw", "his", "sub", "bob", "yea", "oft", "inn", "rod", "yam", "pew", "web", "hod", "hun", "gyp", "wei", "wis", "rob", "gad", "pie", "mon", "dog", "bib", "rub", "ere", "dig", "era", "cat", "fox", "bee", "mod", "day", "apr", "vie", "nev", "jam", "pam", "new", "aye", "ani", "and", "ibm", "yap", "can", "pyx", "tar", "kin", "fog", "hum", "pip", "cup", "dye", "lyx", "jog", "nun", "par", "wan", "fey", "bus", "oak", "bad", "ats", "set", "qom", "vat", "eat", "pus", "rev", "axe", "ion", "six", "ila", "lao", "mom", "mas", "pro", "few", "opt", "poe", "art", "ash", "oar", "cap", "lop", "may", "shy", "rid", "bat", "sum", "rim", "fee", "bmw", "sky", "maj", "hue", "thy", "ava", "rap", "den", "fla", "auk", "cox", "ibo", "hey", "saw", "vim", "sec", "ltd", "you", "its", "tat", "dew", "eva", "tog", "ram", "let", "see", "zit", "maw", "nix", "ate", "gig", "rep", "owe", "ind", "hog", "eve", "sam", "zoo", "any", "dow", "cod", "bed", "vet", "ham", "sis", "hex", "via", "fir", "nod", "mao", "aug", "mum", "hoe", "bah", "hal", "keg", "hew", "zed", "tow", "gog", "ass", "dem", "who", "bet", "gos", "son", "ear", "spy", "kit", "boy", "due", "sen", "oaf", "mix", "hep", "fur", "ada", "bin", "nil", "mia", "ewe", "hit", "fix", "sad", "rib", "eye", "hop", "haw", "wax", "mid", "tad", "ken", "wad", "rye", "pap", "bog", "gut", "ito", "woe", "our", "ado", "sin", "mad", "ray", "hon", "roy", "dip", "hen", "iva", "lug", "asp", "hui", "yak", "bay", "poi", "yep", "bun", "try", "lad", "elm", "nat", "wyo", "gym", "dug", "toe", "dee", "wig", "sly", "rip", "geo", "cog", "pas", "zen", "odd", "nan", "lay", "pod", "fit", "hem", "joy", "bum", "rio", "yon", "dec", "leg", "put", "sue", "dim", "pet", "yaw", "nub", "bit", "bur", "sid", "sun", "oil", "red", "doc", "moe", "caw", "eel", "dix", "cub", "end", "gem", "off", "yew", "hug", "pop", "tub", "sgt", "lid", "pun", "ton", "sol", "din", "yup", "jab", "pea", "bug", "gag", "mil", "jig", "hub", "low", "did", "tin", "get", "gte", "sox", "lei", "mig", "fig", "lon", "use", "ban", "flo", "nov", "jut", "bag", "mir", "sty", "lap", "two", "ins", "con", "ant", "net", "tux", "ode", "stu", "mug", "cad", "nap", "gun", "fop", "tot", "sow", "sal", "sic", "ted", "wot", "del", "imp", "cob", "way", "ann", "tan", "mci", "job", "wet", "ism", "err", "him", "all", "pad", "hah", "hie", "aim", "ike", "jed", "ego", "mac", "baa", "min", "com", "ill", "was", "cab", "ago", "ina", "big", "ilk", "gal", "tap", "duh", "ola", "ran", "lab", "top", "gob", "hot", "ora", "tia", "kip", "han", "met", "hut", "she", "sac", "fed", "goo", "tee", "ell", "not", "act", "gil", "rut", "ala", "ape", "rig", "cid", "god", "duo", "lin", "aid", "gel", "awl", "lag", "elf", "liz", "ref", "aha", "fib", "oho", "tho", "her", "nor", "ace", "adz", "fun", "ned", "coo", "win", "tao", "coy", "van", "man", "pit", "guy", "foe", "hid", "mai", "sup", "jay", "hob", "mow", "jot", "are", "pol", "arc", "lax", "aft", "alb", "len", "air", "pug", "pox", "vow", "got", "meg", "zoe", "amp", "ale", "bud", "gee", "pin", "dun", "pat", "ten", "mob"); new WordLadderII().findLadders("cet", "ism", dic); } - public List> findLadders(String beginWord, String endWord, List wordList) - { + public List> findLadders(String beginWord, String endWord, List wordList) { dictionary.addAll(wordList); bfs(beginWord, endWord, wordList); List path = new ArrayList<>(); @@ -62,37 +59,30 @@ public List> findLadders(String beginWord, String endWord, List wordList) - { + private void bfs(String beginWord, String endWord, List wordList) { queue.offer(beginWord); minDistance.put(beginWord, 0); - while(!queue.isEmpty()) - { + while (!queue.isEmpty()) { String currWord = queue.poll(); StringBuilder childSb = new StringBuilder(currWord); - for(int j = 0, ln = childSb.length(); j < ln; j ++ ) - { - for(int i = 0, l = CONST.length(); i < l; i ++ ) - { + for (int j = 0, ln = childSb.length(); j < ln; j++) { + for (int i = 0, l = CONST.length(); i < l; i++) { char old = childSb.charAt(j); childSb.replace(j, j + 1, String.valueOf(CONST.charAt(i))); String child = childSb.toString(); - if(dictionary.contains(child)) - { - if(minDistance.get(child) == null) - { + if (dictionary.contains(child)) { + if (minDistance.get(child) == null) { minDistance.put(child, minDistance.get(currWord) + 1); addChild(currWord, child); - if(!child.equals(endWord)) + if (!child.equals(endWord)) queue.offer(child); - } - else - { - if(minDistance.get(child) == (minDistance.get(currWord) + 1)) + } else { + if (minDistance.get(child) == (minDistance.get(currWord) + 1)) addChild(currWord, child); } } @@ -101,15 +91,16 @@ private void bfs(String beginWord, String endWord, List wordList) } } } + /** * Add child + * * @param parent parent - * @param child child + * @param child child */ - private void addChild(String parent, String child) - { + private void addChild(String parent, String child) { Set children = graph.get(parent); - if(children == null) + if (children == null) children = new HashSet<>(); children.add(child); graph.put(parent, children); @@ -117,23 +108,18 @@ private void addChild(String parent, String child) /** * Dfs to build path + * * @param currWord node - * @param endWord endword - * @param path path + * @param endWord endword + * @param path path */ - private void dfs(String currWord, String endWord, List path) - { - if(currWord.equals(endWord)) - { + private void dfs(String currWord, String endWord, List path) { + if (currWord.equals(endWord)) { result.add(new ArrayList<>(path)); - } - else - { + } else { Set children = graph.get(currWord); - if(children != null) - { - for(String c : children) - { + if (children != null) { + for (String c : children) { path.add(c); dfs(c, endWord, path); path.remove(path.size() - 1); diff --git a/problems/src/depth_first_search/CourseSchedule.java b/problems/src/depth_first_search/CourseSchedule.java index 131b4f25..b7465228 100644 --- a/problems/src/depth_first_search/CourseSchedule.java +++ b/problems/src/depth_first_search/CourseSchedule.java @@ -5,34 +5,35 @@ /** * Created by gouthamvidyapradhan on 22/06/2017. * There are a total of n courses you have to take, labeled from 0 to n - 1. - - Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] - - Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses? - - For example: - - 2, [[1,0]] - There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible. - - 2, [[1,0],[0,1]] - There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible. - - Note: - The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. - You may assume that there are no duplicate edges in the input prerequisites. - - Solution: - 1. Topologically sort the vertices. - 2. Pick each sorted vertex and mark each of its neighbours as visited, - if you encounter a vertex which is already visited then return false otherwise return true + *

+ * Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] + *

+ * Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses? + *

+ * For example: + *

+ * 2, [[1,0]] + * There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible. + *

+ * 2, [[1,0],[0,1]] + * There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible. + *

+ * Note: + * The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. + * You may assume that there are no duplicate edges in the input prerequisites. + *

+ * Solution: + * 1. Topologically sort the vertices. + * 2. Pick each sorted vertex and mark each of its neighbours as visited, + * if you encounter a vertex which is already visited then return false otherwise return true */ public class CourseSchedule { private Map> graph; private BitSet visited; private Queue toposorted; - public static void main(String[] args) throws Exception{ - int[][] pre = {{1,0}}; + + public static void main(String[] args) throws Exception { + int[][] pre = {{1, 0}}; System.out.println(new CourseSchedule().canFinish(2, pre)); } @@ -49,9 +50,9 @@ public boolean canFinish(int numCourses, int[][] prerequisites) { visited.clear(); - while(!toposorted.isEmpty()){ + while (!toposorted.isEmpty()) { int v = toposorted.poll(); - if(visited.get(v)) + if (visited.get(v)) return false; relax(v); } @@ -60,12 +61,13 @@ public boolean canFinish(int numCourses, int[][] prerequisites) { /** * Mark a vetex and its connected vertices as visited. + * * @param v vertex */ private void relax(int v) { visited.set(v); List children = graph.get(v); - if(children != null){ + if (children != null) { for (int c : children) visited.set(c); } @@ -73,14 +75,15 @@ private void relax(int v) { /** * Toposort + * * @param v vertex */ private void dfs(int v) { visited.set(v); List children = graph.get(v); - if(children != null) { - for(int c : children) - if(!visited.get(c)) + if (children != null) { + for (int c : children) + if (!visited.get(c)) dfs(c); } toposorted.offer(v); diff --git a/problems/src/depth_first_search/CourseScheduleII.java b/problems/src/depth_first_search/CourseScheduleII.java index cb8967b4..987e4f36 100644 --- a/problems/src/depth_first_search/CourseScheduleII.java +++ b/problems/src/depth_first_search/CourseScheduleII.java @@ -5,31 +5,31 @@ /** * Created by gouthamvidyapradhan on 23/06/2017. * There are a total of n courses you have to take, labeled from 0 to n - 1. - - Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] - - Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses. - - There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array. - - For example: - - 2, [[1,0]] - There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1] - - 4, [[1,0],[2,0],[3,1],[3,2]] - There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3]. - - Note: - The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. - You may assume that there are no duplicate edges in the input prerequisites. + *

+ * Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] + *

+ * Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses. + *

+ * There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array. + *

+ * For example: + *

+ * 2, [[1,0]] + * There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1] + *

+ * 4, [[1,0],[2,0],[3,1],[3,2]] + * There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3]. + *

+ * Note: + * The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. + * You may assume that there are no duplicate edges in the input prerequisites. */ public class CourseScheduleII { private Map> graph; private BitSet visited; private Queue toposorted; - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[][] pre = {{1, 0}}; int[] result = new CourseScheduleII().findOrder(2, pre); for (int i : result) @@ -41,7 +41,7 @@ public int[] findOrder(int numCourses, int[][] prerequisites) { int j = 0; int[] courses = new int[numCourses]; int[] result = new int[numCourses]; - for(int i = 0; i < numCourses; i ++) + for (int i = 0; i < numCourses; i++) courses[i] = j++; graph = new HashMap<>(); visited = new BitSet(); @@ -55,29 +55,30 @@ public int[] findOrder(int numCourses, int[][] prerequisites) { visited.clear(); int i = 0; - while(!toposorted.isEmpty()){ + while (!toposorted.isEmpty()) { int v = toposorted.poll(); - if(visited.get(v)) + if (visited.get(v)) return new int[0]; relax(v); result[i++] = v; courses[v] = -1; } //add the remaining courses - for(int c : courses) - if(c != -1) + for (int c : courses) + if (c != -1) result[i++] = c; return result; } /** * Mark a vetex and its connected vertices as visited. + * * @param v vertex */ private void relax(int v) { visited.set(v); List children = graph.get(v); - if(children != null){ + if (children != null) { for (int c : children) visited.set(c); } @@ -85,14 +86,15 @@ private void relax(int v) { /** * Toposort + * * @param v vertex */ private void dfs(int v) { visited.set(v); List children = graph.get(v); - if(children != null) { - for(int c : children) - if(!visited.get(c)) + if (children != null) { + for (int c : children) + if (!visited.get(c)) dfs(c); } toposorted.offer(v); diff --git a/problems/src/depth_first_search/Minesweeper.java b/problems/src/depth_first_search/Minesweeper.java index 1008ed08..fbf41584 100644 --- a/problems/src/depth_first_search/Minesweeper.java +++ b/problems/src/depth_first_search/Minesweeper.java @@ -2,108 +2,99 @@ /** * Created by pradhang on 3/28/2017. - You are given a 2D char matrix representing the game board. 'M' represents an unrevealed mine, 'E' represents an unrevealed empty square, 'B' represents a revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines, digit ('1' to '8') represents how many mines are adjacent to this revealed square, and finally 'X' represents a revealed mine. - - Now given the next click position (row and column indices) among all the unrevealed squares ('M' or 'E'), return the board after revealing this position according to the following rules: - - If a mine ('M') is revealed, then the game is over - change it to 'X'. - If an empty square ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') and all of its adjacent unrevealed squares should be revealed recursively. - If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') representing the number of adjacent mines. - Return the board when no more squares will be revealed. - Example 1: - Input: - - [['E', 'E', 'E', 'E', 'E'], - ['E', 'E', 'M', 'E', 'E'], - ['E', 'E', 'E', 'E', 'E'], - ['E', 'E', 'E', 'E', 'E']] - - Click : [3,0] - - Output: - - [['B', '1', 'E', '1', 'B'], - ['B', '1', 'M', '1', 'B'], - ['B', '1', '1', '1', 'B'], - ['B', 'B', 'B', 'B', 'B']] - - Example 2: - Input: - - [['B', '1', 'E', '1', 'B'], - ['B', '1', 'M', '1', 'B'], - ['B', '1', '1', '1', 'B'], - ['B', 'B', 'B', 'B', 'B']] - - Click : [1,2] - - Output: - - [['B', '1', 'E', '1', 'B'], - ['B', '1', 'X', '1', 'B'], - ['B', '1', '1', '1', 'B'], - ['B', 'B', 'B', 'B', 'B']] - - Note: - The range of the input matrix's height and width is [1,50]. - The click position will only be an unrevealed square ('M' or 'E'), which also means the input board contains at least one clickable square. - The input board won't be a stage when game is over (some mines have been revealed). - For simplicity, not mentioned rules should be ignored in this problem. For example, you don't need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares. - + * You are given a 2D char matrix representing the game board. 'M' represents an unrevealed mine, 'E' represents an unrevealed empty square, 'B' represents a revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines, digit ('1' to '8') represents how many mines are adjacent to this revealed square, and finally 'X' represents a revealed mine. + *

+ * Now given the next click position (row and column indices) among all the unrevealed squares ('M' or 'E'), return the board after revealing this position according to the following rules: + *

+ * If a mine ('M') is revealed, then the game is over - change it to 'X'. + * If an empty square ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') and all of its adjacent unrevealed squares should be revealed recursively. + * If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') representing the number of adjacent mines. + * Return the board when no more squares will be revealed. + * Example 1: + * Input: + *

+ * [['E', 'E', 'E', 'E', 'E'], + * ['E', 'E', 'M', 'E', 'E'], + * ['E', 'E', 'E', 'E', 'E'], + * ['E', 'E', 'E', 'E', 'E']] + *

+ * Click : [3,0] + *

+ * Output: + *

+ * [['B', '1', 'E', '1', 'B'], + * ['B', '1', 'M', '1', 'B'], + * ['B', '1', '1', '1', 'B'], + * ['B', 'B', 'B', 'B', 'B']] + *

+ * Example 2: + * Input: + *

+ * [['B', '1', 'E', '1', 'B'], + * ['B', '1', 'M', '1', 'B'], + * ['B', '1', '1', '1', 'B'], + * ['B', 'B', 'B', 'B', 'B']] + *

+ * Click : [1,2] + *

+ * Output: + *

+ * [['B', '1', 'E', '1', 'B'], + * ['B', '1', 'X', '1', 'B'], + * ['B', '1', '1', '1', 'B'], + * ['B', 'B', 'B', 'B', 'B']] + *

+ * Note: + * The range of the input matrix's height and width is [1,50]. + * The click position will only be an unrevealed square ('M' or 'E'), which also means the input board contains at least one clickable square. + * The input board won't be a stage when game is over (some mines have been revealed). + * For simplicity, not mentioned rules should be ignored in this problem. For example, you don't need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares. */ -public class Minesweeper -{ +public class Minesweeper { private static final int[] R = {1, 1, 1, 0, 0, -1, -1, -1}; private static final int[] C = {-1, 0, 1, -1, 1, -1, 0, 1}; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - char[][] board = {{'E','E','E','E','E'},{'E','E','M','E','E'},{'E','E','E','E','E'},{'E','E','E','E','E'}}; + public static void main(String[] args) throws Exception { + char[][] board = {{'E', 'E', 'E', 'E', 'E'}, {'E', 'E', 'M', 'E', 'E'}, {'E', 'E', 'E', 'E', 'E'}, {'E', 'E', 'E', 'E', 'E'}}; int[] click = {3, 0}; new Minesweeper().updateBoard(board, click); - for (int i = 0; i < board.length; i ++) + for (int i = 0; i < board.length; i++) System.out.println(board[i]); } - public char[][] updateBoard(char[][] board, int[] click) - { + public char[][] updateBoard(char[][] board, int[] click) { int r = click[0]; int c = click[1]; dfs(board, r, c); return board; } - private void dfs(char[][] board, int r, int c) - { - if(board[r][c] == 'M') - { + private void dfs(char[][] board, int r, int c) { + if (board[r][c] == 'M') { board[r][c] = 'X'; - } - else - { + } else { int mineCount = 0; - for(int i = 0; i < 8; i ++) - { + for (int i = 0; i < 8; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >=0 && newC >= 0 && newR < board.length && newC < board[0].length && + if (newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length && board[newR][newC] == 'M') //boundary check mineCount++; } - if(mineCount > 0) - board[r][c] = (char)(mineCount + '0'); - else - { + if (mineCount > 0) + board[r][c] = (char) (mineCount + '0'); + else { board[r][c] = 'B'; - for(int i = 0; i < 8; i ++) - { + for (int i = 0; i < 8; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >=0 && newC >= 0 && newR < board.length && newC < board[0].length && + if (newR >= 0 && newC >= 0 && newR < board.length && newC < board[0].length && board[newR][newC] == 'E') //boundary check { dfs(board, newR, newC); diff --git a/problems/src/depth_first_search/MovieRecommend.java b/problems/src/depth_first_search/MovieRecommend.java index dff0c202..a4e061d7 100644 --- a/problems/src/depth_first_search/MovieRecommend.java +++ b/problems/src/depth_first_search/MovieRecommend.java @@ -6,66 +6,58 @@ * Created by gouthamvidyapradhan on 25/02/2017. * Accepted */ -public class MovieRecommend -{ +public class MovieRecommend { Set visited = new HashSet<>(); List list = new ArrayList<>(); - class Movie - { + + class Movie { private int movieId; private float rating; private ArrayList similarMovies; - public List getSimilarMovies() - { + + public List getSimilarMovies() { return similarMovies; } } + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - public Set getMovieRecommendations (Movie movie, int N) - { + public Set getMovieRecommendations(Movie movie, int N) { dfs(movie); Set result = new HashSet<>(); - Comparator cmp = new Comparator() - { + Comparator cmp = new Comparator() { @Override - public int compare(Movie o1, Movie o2) - { + public int compare(Movie o1, Movie o2) { return Float.compare(o2.rating, o1.rating); } }; Collections.sort(list, cmp); - if(list.size() < N) - { + if (list.size() < N) { result.addAll(list); return result; } - for(int i = 0; i < N; i ++) - { + for (int i = 0; i < N; i++) { result.add(list.get(i)); } return result; } - private void dfs(Movie m) - { + private void dfs(Movie m) { visited.add(m.movieId); // mark this visited List movies = m.getSimilarMovies(); - for(Movie mo : movies) - { - if(!visited.contains(mo.movieId)) - { + for (Movie mo : movies) { + if (!visited.contains(mo.movieId)) { list.add(mo); dfs(mo); } diff --git a/problems/src/depth_first_search/NumberOfIslands.java b/problems/src/depth_first_search/NumberOfIslands.java index a5ff9468..e624f42f 100644 --- a/problems/src/depth_first_search/NumberOfIslands.java +++ b/problems/src/depth_first_search/NumberOfIslands.java @@ -2,50 +2,44 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. - - Example 1: - - 11110 - 11010 - 11000 - 00000 - Answer: 1 - - Example 2: - - 11000 - 11000 - 00100 - 00011 - Answer: 3 + * Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. + *

+ * Example 1: + *

+ * 11110 + * 11010 + * 11000 + * 00000 + * Answer: 1 + *

+ * Example 2: + *

+ * 11000 + * 11000 + * 00100 + * 00011 + * Answer: 3 */ -public class NumberOfIslands -{ +public class NumberOfIslands { int[] R = {0, 0, 1, -1}; int[] C = {1, -1, 0, 0}; private static int M, N; private static char temp[][]; - public int numIslands(char[][] grid) - { + public int numIslands(char[][] grid) { M = grid.length; - if(M == 0) return 0; + if (M == 0) return 0; N = grid[0].length; temp = new char[M][N]; int count = 0; - for(int i = 0; i < M; i ++) - { + for (int i = 0; i < M; i++) { System.arraycopy(grid[i], 0, temp[i], 0, N); } - for(int i = 0; i < M; i ++) - { - for(int j = 0; j < N; j++) - { - if(temp[i][j] == '1') - { + for (int i = 0; i < M; i++) { + for (int j = 0; j < N; j++) { + if (temp[i][j] == '1') { ++count; dfs(i, j); } @@ -55,16 +49,13 @@ public int numIslands(char[][] grid) return count; } - private void dfs(int r, int c) - { + private void dfs(int r, int c) { temp[r][c] = '0'; - for(int i = 0; i < 4; i++) - { + for (int i = 0; i < 4; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >=0 && newC >= 0 && newR < M && newC < N) - { - if(temp[newR][newC] != '0') //not visited + if (newR >= 0 && newC >= 0 && newR < M && newC < N) { + if (temp[newR][newC] != '0') //not visited { dfs(newR, newC); } diff --git a/problems/src/design/AutocompleteSystem.java b/problems/src/design/AutocompleteSystem.java index dec4eea1..89b426fe 100644 --- a/problems/src/design/AutocompleteSystem.java +++ b/problems/src/design/AutocompleteSystem.java @@ -4,79 +4,79 @@ /** * Created by gouthamvidyapradhan on 20/08/2017. - * + *

* Design a search autocomplete system for a search engine. Users may input a sentence (at least one word and end with a special character '#'). * For each character they type except '#', you need to return the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. * Here are the specific rules: - - The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before. - The returned top 3 hot sentences should be sorted by hot degree (The first is the hottest one). - If several sentences have the same degree of hot, you need to use ASCII-code order (smaller one appears first). - If less than 3 hot sentences exist, then just return as many as you can. - When the input is a special character, it means the sentence ends, and in this case, you need to return an empty list. - Your job is to implement the following functions: - - The constructor function: - - AutocompleteSystem(String[] sentences, int[] times): This is the constructor. - The input is historical data. Sentences is a string array consists of previously typed sentences. - Times is the corresponding times a sentence has been typed. Your system should record these historical data. - - Now, the user wants to input a new sentence. The following function will provide the next character the user types: - - List input(char c): The input c is the next character typed by the user. - The character will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('#'). - Also, the previously typed sentence should be recorded in your system. - The output will be the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. - - - Example: - Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2]) - The system have already tracked down the following sentences and their corresponding times: - "i love you" : 5 times - "island" : 3 times - "ironman" : 2 times - "i love leetcode" : 2 times - Now, the user begins another search: - - Operation: input('i') - Output: ["i love you", "island","i love leetcode"] - Explanation: - There are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same hot degree. - Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be in front of "ironman". - Also we only need to output top 3 hot sentences, so "ironman" will be ignored. - - Operation: input(' ') - Output: ["i love you","i love leetcode"] - Explanation: - There are only two sentences that have prefix "i ". - - Operation: input('a') - Output: [] - Explanation: - There are no sentences that have prefix "i a". - - Operation: input('#') - Output: [] - Explanation: - The user finished the input, the sentence "i a" should be saved as a historical sentence in system. - And the following input will be counted as a new search. - - Note: - The input sentence will always start with a letter and end with '#', and only one blank space will exist between two words. - The number of complete sentences that to be searched won't exceed 100. - The length of each sentence including those in the historical data won't exceed 100. - Please use double-quote instead of single-quote when you write test cases even for a character input. - Please remember to RESET your class variables declared in class AutocompleteSystem, as static/class variables are persisted across multiple test cases. - - Solution: Maintain a Trie (slightly modified) data-structure to all the input sentences where each node of the Trie - is a node containing a hash-map of child character and node and a TreeSet containing the sorted order of all the - possible child sentences starting from the current node. Maintain a cursor node 'curr' to indicate the current node - of input, if the input character is absent then simply mark curr as null indicating no further auto-complete terms possible. - On the other hand if the input character is present then simply pick the top 3 elements from the TreeSet object of curr - node. - Finally, use a StringBuilder to accumulate all the input characters and when a end of sentence is '#' is encountered - simply update the trie with new sentence and degree. + *

+ * The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before. + * The returned top 3 hot sentences should be sorted by hot degree (The first is the hottest one). + * If several sentences have the same degree of hot, you need to use ASCII-code order (smaller one appears first). + * If less than 3 hot sentences exist, then just return as many as you can. + * When the input is a special character, it means the sentence ends, and in this case, you need to return an empty list. + * Your job is to implement the following functions: + *

+ * The constructor function: + *

+ * AutocompleteSystem(String[] sentences, int[] times): This is the constructor. + * The input is historical data. Sentences is a string array consists of previously typed sentences. + * Times is the corresponding times a sentence has been typed. Your system should record these historical data. + *

+ * Now, the user wants to input a new sentence. The following function will provide the next character the user types: + *

+ * List input(char c): The input c is the next character typed by the user. + * The character will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('#'). + * Also, the previously typed sentence should be recorded in your system. + * The output will be the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. + *

+ *

+ * Example: + * Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2]) + * The system have already tracked down the following sentences and their corresponding times: + * "i love you" : 5 times + * "island" : 3 times + * "ironman" : 2 times + * "i love leetcode" : 2 times + * Now, the user begins another search: + *

+ * Operation: input('i') + * Output: ["i love you", "island","i love leetcode"] + * Explanation: + * There are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same hot degree. + * Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be in front of "ironman". + * Also we only need to output top 3 hot sentences, so "ironman" will be ignored. + *

+ * Operation: input(' ') + * Output: ["i love you","i love leetcode"] + * Explanation: + * There are only two sentences that have prefix "i ". + *

+ * Operation: input('a') + * Output: [] + * Explanation: + * There are no sentences that have prefix "i a". + *

+ * Operation: input('#') + * Output: [] + * Explanation: + * The user finished the input, the sentence "i a" should be saved as a historical sentence in system. + * And the following input will be counted as a new search. + *

+ * Note: + * The input sentence will always start with a letter and end with '#', and only one blank space will exist between two words. + * The number of complete sentences that to be searched won't exceed 100. + * The length of each sentence including those in the historical data won't exceed 100. + * Please use double-quote instead of single-quote when you write test cases even for a character input. + * Please remember to RESET your class variables declared in class AutocompleteSystem, as static/class variables are persisted across multiple test cases. + *

+ * Solution: Maintain a Trie (slightly modified) data-structure to all the input sentences where each node of the Trie + * is a node containing a hash-map of child character and node and a TreeSet containing the sorted order of all the + * possible child sentences starting from the current node. Maintain a cursor node 'curr' to indicate the current node + * of input, if the input character is absent then simply mark curr as null indicating no further auto-complete terms possible. + * On the other hand if the input character is present then simply pick the top 3 elements from the TreeSet object of curr + * node. + * Finally, use a StringBuilder to accumulate all the input characters and when a end of sentence is '#' is encountered + * simply update the trie with new sentence and degree. */ public class AutocompleteSystem { @@ -86,12 +86,13 @@ public class AutocompleteSystem { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ - String[] sentences = {"i love you", "island","ironman", "i love leetcode"}; - int[] degree = {5,3,2,2}; + public static void main(String[] args) throws Exception { + String[] sentences = {"i love you", "island", "ironman", "i love leetcode"}; + int[] degree = {5, 3, 2, 2}; AutocompleteSystem autocomplete = new AutocompleteSystem(sentences, degree); List result = autocomplete.input('i'); result.forEach(System.out::println); @@ -105,35 +106,38 @@ public static void main(String[] args) throws Exception{ /** * Initialize the trie data-structure + * * @param sentences array of sentences - * @param times degree + * @param times degree */ public AutocompleteSystem(String[] sentences, int[] times) { hotTextMap = new HashMap<>(); trie = new Trie(); - for(int i = 0; i < sentences.length; i ++){ + for (int i = 0; i < sentences.length; i++) { hotTextMap.put(sentences[i], times[i]); trie.insert(sentences[i]); trie.update(sentences[i]); } - curr = trie; root = trie; + curr = trie; + root = trie; currSentence = new StringBuilder(); } /** * Accept input and return hot-text for the current char + * * @param c char * @return List of top 3 hot-text */ public List input(char c) { List result = new ArrayList<>(); - if(c == '#'){ + if (c == '#') { String sentence = currSentence.toString(); - if(hotTextMap.containsKey(sentence)){ + if (hotTextMap.containsKey(sentence)) { //already a known sentence hence only update in necessary hotTextMap.put(sentence, hotTextMap.get(sentence) + 1); trie.update(sentence); - } else{ + } else { //insert a new sentence and update the degree hotTextMap.put(sentence, 1); trie.insert(sentence); @@ -141,10 +145,9 @@ public List input(char c) { } currSentence = new StringBuilder(); //reset StringBuilder curr = root; //point to root of the trie - } - else { - if(curr != null) { - if(curr.containsChild(c)) { + } else { + if (curr != null) { + if (curr.containsChild(c)) { List hotText = curr.getSubtrie(c).getTop3HotText(); hotText.stream().forEach((x) -> result.add(currSentence.toString() + x)); //each node only returns //the hot-text for the current and child nodes hence we have to attach the prefix string @@ -162,10 +165,11 @@ public List input(char c) { /** * Class HotText to store the text and degree */ - private class HotText{ + private class HotText { private String text; private int degree; - HotText(String text, int degree){ + + HotText(String text, int degree) { this.text = text; this.degree = degree; } @@ -187,11 +191,12 @@ private class Trie { private TreeSet hotText = new TreeSet<>((HotText o1, HotText o2) -> { int cmp = Integer.compare(o2.getDegree(), o1.getDegree()); - return cmp == 0 ? o1.getText().compareTo(o2.getText()) : cmp; + return cmp == 0 ? o1.getText().compareTo(o2.getText()) : cmp; }); /** * Get hot-text + * * @return HotText */ public TreeSet getHotText() { @@ -200,55 +205,59 @@ public TreeSet getHotText() { /** * Return top 3 hottext + * * @return hot text */ - private List getTop3HotText(){ + private List getTop3HotText() { List hotText = new ArrayList<>(); - if(this.getHotText() != null){ + if (this.getHotText() != null) { this.getHotText().stream().limit(3).forEach((x) -> hotText.add(x.getText())); } return hotText; } - /** Inserts a word into the trie. */ + /** + * Inserts a word into the trie. + */ private void insert(String word) { - if(word != null){ + if (word != null) { add(0, word, word.length()); } } - private void add(int i, String word, int length){ - if(i < length){ + private void add(int i, String word, int length) { + if (i < length) { char c = word.charAt(i); Trie subTrie = map.get(c); - if(subTrie == null){ + if (subTrie == null) { subTrie = new Trie(); map.put(c, subTrie); } subTrie.add(i + 1, word, length); - } - else map.put(null, new Trie()); //use null to indicate end of string + } else map.put(null, new Trie()); //use null to indicate end of string } /** * Update hottex and degree + * * @param word word or sentence */ private void update(String word) { - if(word != null){ + if (word != null) { update(0, word, word.length()); } } /** * Update trie - * @param i curr position - * @param word sentence + * + * @param i curr position + * @param word sentence * @param length length * @return HotText */ - private HotText update(int i, String word, int length){ - if(i < length){ + private HotText update(int i, String word, int length) { + if (i < length) { char c = word.charAt(i); Trie subTrie = map.get(c); HotText subTrieHotText = subTrie.update(i + 1, word, length); @@ -262,9 +271,10 @@ private HotText update(int i, String word, int length){ /** * Hot text update + * * @param hotText hotText object */ - private void updateHotText(Trie trie, HotText hotText){ + private void updateHotText(Trie trie, HotText hotText) { trie.getHotText().remove(new HotText(hotText.getText(), hotText.getDegree() - 1)); //remove already // contained hot-text and add new trie.getHotText().add(hotText); @@ -272,19 +282,21 @@ private void updateHotText(Trie trie, HotText hotText){ /** * Contains child + * * @param c char * @return true if it contains child, false otherwise */ - private boolean containsChild(char c){ + private boolean containsChild(char c) { return this.map.containsKey(c); } /** * Return child tree + * * @param c char * @return child subTrie */ - private Trie getSubtrie(char c){ + private Trie getSubtrie(char c) { return this.map.get(c); } } diff --git a/problems/src/design/BSTIterator.java b/problems/src/design/BSTIterator.java index 801781af..0955e621 100644 --- a/problems/src/design/BSTIterator.java +++ b/problems/src/design/BSTIterator.java @@ -5,13 +5,13 @@ /** * Created by gouthamvidyapradhan on 13/08/2017. * Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. - - Calling next() will return the next smallest number in the BST. - - Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree. - - Solution: The below solution works in average O(1) time and worst case O(h) time using O(h) memory. - Use a stack to keep track of min value node. + *

+ * Calling next() will return the next smallest number in the BST. + *

+ * Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree. + *

+ * Solution: The below solution works in average O(1) time and worst case O(h) time using O(h) memory. + * Use a stack to keep track of min value node. */ public class BSTIterator { @@ -21,10 +21,13 @@ public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(10); root.left = new TreeNode(5); root.left.left = new TreeNode(4); @@ -53,14 +56,18 @@ public BSTIterator(TreeNode root) { fillStack(root); } - /** @return whether we have a next smallest number */ + /** + * @return whether we have a next smallest number + */ public boolean hasNext() { return !stack.isEmpty(); } - /** @return the next smallest number */ + /** + * @return the next smallest number + */ public int next() { - if(!stack.isEmpty()) { + if (!stack.isEmpty()) { TreeNode top = stack.pop(); fillStack(top.right); return top.val; @@ -70,11 +77,12 @@ public int next() { /** * Fill stack with min values + * * @param node curr node to begin with */ - private void fillStack(TreeNode node){ + private void fillStack(TreeNode node) { TreeNode ite = node; - while(ite != null){ + while (ite != null) { stack.push(ite); ite = ite.left; } diff --git a/problems/src/design/CopyListWithRandomPointer.java b/problems/src/design/CopyListWithRandomPointer.java index 90157e19..ec83f894 100644 --- a/problems/src/design/CopyListWithRandomPointer.java +++ b/problems/src/design/CopyListWithRandomPointer.java @@ -2,28 +2,28 @@ /** * Created by gouthamvidyapradhan on 11/03/2017. - A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. - - Return a deep copy of the list. + * A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. + *

+ * Return a deep copy of the list. */ -public class CopyListWithRandomPointer -{ +public class CopyListWithRandomPointer { - static class RandomListNode - { + static class RandomListNode { int label; RandomListNode next, random; - RandomListNode(int x) - { this.label = x; } + + RandomListNode(int x) { + this.label = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { RandomListNode one = new RandomListNode(1); one.next = null; one.random = one; @@ -44,12 +44,10 @@ public static void main(String[] args) throws Exception System.out.println(); } - private RandomListNode copyRandomList(RandomListNode head) - { - if(head == null) return null; + private RandomListNode copyRandomList(RandomListNode head) { + if (head == null) return null; RandomListNode ite = head, next; - while(ite != null) - { + while (ite != null) { next = ite.next; RandomListNode node = new RandomListNode(ite.label); ite.next = node; @@ -58,16 +56,15 @@ private RandomListNode copyRandomList(RandomListNode head) } ite = head; - while(ite != null) - { - if(ite.random != null) + while (ite != null) { + if (ite.random != null) ite.next.random = ite.random.next; ite = ite.next.next; } - ite = head; RandomListNode copyIte = ite.next, copyHead = ite.next; - while(copyIte.next != null) - { + ite = head; + RandomListNode copyIte = ite.next, copyHead = ite.next; + while (copyIte.next != null) { ite.next = copyIte.next; copyIte.next = ite.next.next; copyIte = copyIte.next; diff --git a/problems/src/design/EncodeAndDecodeTinyURL.java b/problems/src/design/EncodeAndDecodeTinyURL.java index fb9b8001..09eae92a 100644 --- a/problems/src/design/EncodeAndDecodeTinyURL.java +++ b/problems/src/design/EncodeAndDecodeTinyURL.java @@ -5,37 +5,34 @@ /** * Created by gouthamvidyapradhan on 11/04/2017. - TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as http://tinyurl.com/4e9iAk. - - Design the encode and decode methods for the TinyURL service. There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL. - + * TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as http://tinyurl.com/4e9iAk. + *

+ * Design the encode and decode methods for the TinyURL service. There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL. */ -public class EncodeAndDecodeTinyURL -{ +public class EncodeAndDecodeTinyURL { private List list = new ArrayList<>(); private static final String URL = "http://tinyurl.com/"; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { EncodeAndDecodeTinyURL encoder = new EncodeAndDecodeTinyURL(); String shorterUrl = encoder.encode("https://leetcode.com/problems/design-tinyurl"); System.out.println(encoder.decode(shorterUrl)); } // Encodes a URL to a shortened URL. - public String encode(String longUrl) - { + public String encode(String longUrl) { list.add(longUrl); return URL.concat(String.valueOf(list.size())); } // Decodes a shortened URL to its original URL. - public String decode(String shortUrl) - { + public String decode(String shortUrl) { String[] parts = shortUrl.split("http://tinyurl.com/"); String code = parts[1]; return list.get(Integer.parseInt(code) - 1); diff --git a/problems/src/design/LFUCache.java b/problems/src/design/LFUCache.java index d8e6b0f6..7a9fd05b 100644 --- a/problems/src/design/LFUCache.java +++ b/problems/src/design/LFUCache.java @@ -1,20 +1,23 @@ package design; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; /** * Created by gouthamvidyapradhan on 20/03/2017. - Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get and put. - - get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. - put(key, value) - Set or insert the value if the key is not already present. When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted. - - Follow up: - Could you do both operations in O(1) time complexity? - - Example: - - LFUCache cache = new LFUCache( 2 /* capacity */ /*) + * Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get and put. + *

+ * get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. + * put(key, value) - Set or insert the value if the key is not already present. When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted. + *

+ * Follow up: + * Could you do both operations in O(1) time complexity? + *

+ * Example: + *

+ * LFUCache cache = new LFUCache( 2 /* capacity + */ /*) cache.put(1, 1); cache.put(2, 2); @@ -27,17 +30,15 @@ Could you do both operations in O(1) time complexity? cache.get(3); // returns 3 cache.get(4); // returns 4 */ -public class LFUCache -{ - private class Node - { +public class LFUCache { + private class Node { int frequency; Node prev; Node next; LinkedHashSet hashSet; + Node(int frequency, - LinkedHashSet hashSet) - { + LinkedHashSet hashSet) { this.frequency = frequency; this.hashSet = hashSet; prev = null; @@ -51,12 +52,13 @@ private class Node private Map cache; private Map fMap; //frequency private Node head; + /** * Main method + * * @param args */ - public static void main(String[] args) - { + public static void main(String[] args) { LFUCache cache1 = new LFUCache(2); cache1.put(1, 1); cache1.put(2, 2); @@ -83,8 +85,7 @@ public static void main(String[] args) //System.out.println(cache1.get(4)); } - public LFUCache(int capacity) - { + public LFUCache(int capacity) { currentSize = 0; this.capacity = capacity; cache = new HashMap<>(); @@ -93,22 +94,17 @@ public LFUCache(int capacity) /** * Remove node and delink + * * @param node Node */ - private void popNode(Node node) - { - if(node.prev != null && node.next != null) - { + private void popNode(Node node) { + if (node.prev != null && node.next != null) { node.prev.next = node.next; node.next.prev = node.prev; - } - else if(node.prev == null) - { + } else if (node.prev == null) { node.next.prev = null; node.next = null; - } - else - { + } else { node.prev.next = null; node.prev = null; } @@ -116,58 +112,54 @@ else if(node.prev == null) /** * Get value + * * @param key key * @return value */ - public int get(int key) - { - if(!cache.containsKey(key)) return -1; + public int get(int key) { + if (!cache.containsKey(key)) return -1; fMap.put(key, update(key)); return cache.get(key); } /** * Update fMap + * * @param key key */ - private Node update(int key) - { + private Node update(int key) { Node node = fMap.get(key); node.hashSet.remove(key); Node newNode; - if(node.next == null) - { + if (node.next == null) { newNode = makeNewNode(key, node.frequency + 1); node.next = newNode; newNode.prev = node; - } - else if(node.next.frequency == node.frequency + 1) - { + } else if (node.next.frequency == node.frequency + 1) { node.next.hashSet.add(key); newNode = node.next; - } - else - { + } else { newNode = makeNewNode(key, node.frequency + 1); node.next.prev = newNode; newNode.next = node.next; newNode.prev = node; node.next = newNode; } - if(node.equals(head)) + if (node.equals(head)) incrementHead(); - else if(node.hashSet.isEmpty()) + else if (node.hashSet.isEmpty()) popNode(node); return newNode; } + /** * Make new node - * @param key key + * + * @param key key * @param frequency frequency * @return Node */ - private Node makeNewNode(int key, int frequency) - { + private Node makeNewNode(int key, int frequency) { LinkedHashSet linkedHashSet = new LinkedHashSet<>(); linkedHashSet.add(key); return new Node(frequency, linkedHashSet); @@ -175,33 +167,29 @@ private Node makeNewNode(int key, int frequency) /** * Add new head - * @param key key + * + * @param key key * @param frequency frequency */ - private Node addHead(int key, int frequency) - { - if(head == null) + private Node addHead(int key, int frequency) { + if (head == null) head = makeNewNode(key, frequency); - else if(head.frequency > frequency) - { + else if (head.frequency > frequency) { Node node = makeNewNode(key, frequency); node.next = head; head.prev = node; head = node; - } - else head.hashSet.add(key); + } else head.hashSet.add(key); return head; } + /** * Increment head */ - private void incrementHead() - { - if(head.hashSet.isEmpty()) - { + private void incrementHead() { + if (head.hashSet.isEmpty()) { head = head.next; - if(head != null) - { + if (head != null) { head.prev.next = null; head.prev = null; } @@ -210,28 +198,21 @@ private void incrementHead() /** * Put key value pair - * @param key key + * + * @param key key * @param value value */ - public void put(int key, int value) - { - if(capacity != 0) - { - if(cache.containsKey(key)) - { + public void put(int key, int value) { + if (capacity != 0) { + if (cache.containsKey(key)) { fMap.put(key, update(key)); //update existing cache.put(key, value); - } - else - { - if(currentSize == capacity) - { + } else { + if (currentSize == capacity) { evict(); cache.put(key, value); fMap.put(key, addHead(key, 1)); - } - else - { + } else { fMap.put(key, addHead(key, 1)); //add new head cache.put(key, value); currentSize++; @@ -243,8 +224,7 @@ public void put(int key, int value) /** * Evict the node with least frequency */ - private void evict() - { + private void evict() { int key = head.hashSet.iterator().next(); head.hashSet.remove(key); cache.remove(key); diff --git a/problems/src/design/LRUCache.java b/problems/src/design/LRUCache.java index 7838106a..2608859f 100644 --- a/problems/src/design/LRUCache.java +++ b/problems/src/design/LRUCache.java @@ -1,20 +1,22 @@ package design; -import java.util.*; +import java.util.HashMap; +import java.util.Map; /** * Created by gouthamvidyapradhan on 18/03/2017. - Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put. - - get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. - put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. - - Follow up: - Could you do both operations in O(1) time complexity? - - Example: - - LRUCache cache = new LRUCache( 2 /* capacity */ /*); + * Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put. + *

+ * get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. + * put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. + *

+ * Follow up: + * Could you do both operations in O(1) time complexity? + *

+ * Example: + *

+ * LRUCache cache = new LRUCache( 2 /* capacity + */ /*); cache.put(1, 1); cache.put(2, 2); @@ -30,15 +32,13 @@ Could you do both operations in O(1) time complexity? Show Similar Problems */ -public class LRUCache -{ - public static class DLinkList - { +public class LRUCache { + public static class DLinkList { int key, value; DLinkList left; DLinkList right; - DLinkList(int key, int value) - { + + DLinkList(int key, int value) { this.key = key; this.value = value; left = null; @@ -52,12 +52,11 @@ public static class DLinkList /** * Pop head node + * * @return */ - private DLinkList popHead() - { - if(!head.right.equals(tail)) - { + private DLinkList popHead() { + if (!head.right.equals(tail)) { DLinkList node = head.right; head.right = node.right; node.right.left = head; @@ -70,10 +69,10 @@ private DLinkList popHead() /** * Push to tail + * * @param node */ - private void offer(DLinkList node) - { + private void offer(DLinkList node) { tail.left.right = node; node.left = tail.left; node.right = tail; @@ -82,26 +81,27 @@ private void offer(DLinkList node) /** * Move node to tail + * * @param node */ - private void moveToTail(DLinkList node) - { + private void moveToTail(DLinkList node) { node.left.right = node.right; node.right.left = node.left; offer(node); } + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { LRUCache cache = new LRUCache(2); cache.put(1, 1); cache.put(2, 2); System.out.println(cache.get(1)); - cache.put(3,3); + cache.put(3, 3); System.out.println(cache.get(2)); cache.put(4, 4); System.out.println(cache.get(1)); @@ -109,8 +109,7 @@ public static void main(String[] args) throws Exception System.out.println(cache.get(4)); } - public LRUCache(int capacity) - { + public LRUCache(int capacity) { this.capacity = capacity; this.currentSize = 0; cache = new HashMap<>(); @@ -120,37 +119,28 @@ public LRUCache(int capacity) tail.left = head; } - public int get(int key) - { - if(cache.get(key) == null) return -1; + public int get(int key) { + if (cache.get(key) == null) return -1; DLinkList node = cache.get(key); moveToTail(node); return node.value; } - public void put(int key, int value) - { - if(cache.containsKey(key)) - { + public void put(int key, int value) { + if (cache.containsKey(key)) { DLinkList node = cache.get(key); node.value = value; moveToTail(node); - } - else - { - if(capacity == currentSize) - { + } else { + if (capacity == currentSize) { DLinkList head = popHead(); - if(head != null) - { + if (head != null) { cache.remove(head.key); DLinkList node = new DLinkList(key, value); offer(node); cache.put(key, node); } - } - else - { + } else { DLinkList node = new DLinkList(key, value); offer(node); cache.put(key, node); diff --git a/problems/src/design/RandomizedSet.java b/problems/src/design/RandomizedSet.java index f675c9b9..5e21d892 100644 --- a/problems/src/design/RandomizedSet.java +++ b/problems/src/design/RandomizedSet.java @@ -4,45 +4,46 @@ /** * Created by gouthamvidyapradhan on 23/03/2017. - Design a data structure that supports all following operations in average O(1) time. - - insert(val): Inserts an item val to the set if not already present. - remove(val): Removes an item val from the set if present. - getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned. - Example: - - // Init an empty set. - RandomizedSet randomSet = new RandomizedSet(); - - // Inserts 1 to the set. Returns true as 1 was inserted successfully. - randomSet.insert(1); - - // Returns false as 2 does not exist in the set. - randomSet.remove(2); - - // Inserts 2 to the set, returns true. Set now contains [1,2]. - randomSet.insert(2); - - // getRandom should return either 1 or 2 randomly. - randomSet.getRandom(); - - // Removes 1 from the set, returns true. Set now contains [2]. - randomSet.remove(1); - - // 2 was already in the set, so return false. - randomSet.insert(2); - - // Since 2 is the only number in the set, getRandom always return 2. - randomSet.getRandom(); + * Design a data structure that supports all following operations in average O(1) time. + *

+ * insert(val): Inserts an item val to the set if not already present. + * remove(val): Removes an item val from the set if present. + * getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned. + * Example: + *

+ * // Init an empty set. + * RandomizedSet randomSet = new RandomizedSet(); + *

+ * // Inserts 1 to the set. Returns true as 1 was inserted successfully. + * randomSet.insert(1); + *

+ * // Returns false as 2 does not exist in the set. + * randomSet.remove(2); + *

+ * // Inserts 2 to the set, returns true. Set now contains [1,2]. + * randomSet.insert(2); + *

+ * // getRandom should return either 1 or 2 randomly. + * randomSet.getRandom(); + *

+ * // Removes 1 from the set, returns true. Set now contains [2]. + * randomSet.remove(1); + *

+ * // 2 was already in the set, so return false. + * randomSet.insert(2); + *

+ * // Since 2 is the only number in the set, getRandom always return 2. + * randomSet.getRandom(); */ -public class RandomizedSet -{ +public class RandomizedSet { private Map map; private List list; private Random random; - /** Initialize your data structure here. */ - public RandomizedSet() - { + + /** + * Initialize your data structure here. + */ + public RandomizedSet() { map = new HashMap<>(); list = new ArrayList<>(); random = new Random(); @@ -50,11 +51,11 @@ public RandomizedSet() /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { RandomizedSet rSet = new RandomizedSet(); System.out.println(rSet.getRandom()); System.out.println(rSet.insert(1)); @@ -73,11 +74,11 @@ public static void main(String[] args) throws Exception System.out.println(rSet.getRandom()); } - /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ - public boolean insert(int val) - { - if(!map.keySet().contains(val)) - { + /** + * Inserts a value to the set. Returns true if the set did not already contain the specified element. + */ + public boolean insert(int val) { + if (!map.keySet().contains(val)) { int pos = list.size(); map.put(val, pos); list.add(val); @@ -86,15 +87,14 @@ public boolean insert(int val) return false; } - /** Removes a value from the set. Returns true if the set contained the specified element. */ - public boolean remove(int val) - { - if(map.containsKey(val)) - { + /** + * Removes a value from the set. Returns true if the set contained the specified element. + */ + public boolean remove(int val) { + if (map.containsKey(val)) { int size = list.size(); int posVal = map.get(val); - if(posVal < (size - 1)) - { + if (posVal < (size - 1)) { int last = list.get(size - 1); map.put(last, posVal); list.set(posVal, last); @@ -106,9 +106,10 @@ public boolean remove(int val) return false; } - /** Get a random element from the set. */ - public int getRandom() - { + /** + * Get a random element from the set. + */ + public int getRandom() { /*if(list.size() == 0) return 0; else if (list.size() == 1) return list.get(0);*/ return list.get(random.nextInt(list.size() - 1)); diff --git a/problems/src/design/SerializeDeserializeBinaryTree.java b/problems/src/design/SerializeDeserializeBinaryTree.java index c3251026..1517e6b0 100644 --- a/problems/src/design/SerializeDeserializeBinaryTree.java +++ b/problems/src/design/SerializeDeserializeBinaryTree.java @@ -4,39 +4,40 @@ /** * Created by gouthamvidyapradhan on 11/03/2017. - Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment. - - Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure. - - For example, you may serialize the following tree - - 1 - / \ - 2 3 - / \ - 4 5 - as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself. - Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless. - + * Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment. + *

+ * Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure. + *

+ * For example, you may serialize the following tree + *

+ * 1 + * / \ + * 2 3 + * / \ + * 4 5 + * as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself. + * Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless. */ -public class SerializeDeserializeBinaryTree -{ - public static class TreeNode - { +public class SerializeDeserializeBinaryTree { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private static final String NULL = "X"; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(1); TreeNode two = new TreeNode(2); TreeNode three = new TreeNode(3); @@ -63,25 +64,21 @@ public static void main(String[] args) throws Exception } // Encodes a tree to a single string. - public String serialize(TreeNode root) - { - if(root == null) return null; + public String serialize(TreeNode root) { + if (root == null) return null; List list = new ArrayList<>(); encode(root, list); StringBuilder sb = new StringBuilder(); sb.append(list.get(0)); - for(int i = 1, l = list.size(); i < l; i++) - { + for (int i = 1, l = list.size(); i < l; i++) { sb.append(",").append(list.get(i)); } return sb.toString(); } - private void encode(TreeNode root, List list) - { - if(root == null) list.add(NULL); - else - { + private void encode(TreeNode root, List list) { + if (root == null) list.add(NULL); + else { list.add(String.valueOf(root.val)); encode(root.left, list); encode(root.right, list); @@ -89,20 +86,18 @@ private void encode(TreeNode root, List list) } // Decodes your encoded data to tree. - public TreeNode deserialize(String data) - { - if(data == null || data.isEmpty()) return null; + public TreeNode deserialize(String data) { + if (data == null || data.isEmpty()) return null; StringTokenizer st = new StringTokenizer(data, ","); Queue queue = new ArrayDeque<>(); - while(st.hasMoreTokens()) + while (st.hasMoreTokens()) queue.offer(st.nextToken()); return decode(queue); } - private TreeNode decode(Queue queue) - { + private TreeNode decode(Queue queue) { String node = queue.poll(); - if(node.equals(NULL)) + if (node.equals(NULL)) return null; TreeNode root = new TreeNode(Integer.parseInt(node)); root.left = decode(queue); diff --git a/problems/src/design/TicTacToe.java b/problems/src/design/TicTacToe.java index 0eb7c2f8..aef7b8fe 100644 --- a/problems/src/design/TicTacToe.java +++ b/problems/src/design/TicTacToe.java @@ -2,70 +2,68 @@ /** * Created by gouthamvidyapradhan on 13/05/2017. - - Design a Tic-tac-toe game that is played between two players on a n x n grid. - - You may assume the following rules: - - A move is guaranteed to be valid and is placed on an empty block. - Once a winning condition is reached, no more moves is allowed. - A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game. - Example: - Given n = 3, assume that player 1 is "X" and player 2 is "O" in the board. - - TicTacToe toe = new TicTacToe(3); - - toe.move(0, 0, 1); -> Returns 0 (no one wins) - |X| | | - | | | | // Player 1 makes a move at (0, 0). - | | | | - - toe.move(0, 2, 2); -> Returns 0 (no one wins) - |X| |O| - | | | | // Player 2 makes a move at (0, 2). - | | | | - - toe.move(2, 2, 1); -> Returns 0 (no one wins) - |X| |O| - | | | | // Player 1 makes a move at (2, 2). - | | |X| - - toe.move(1, 1, 2); -> Returns 0 (no one wins) - |X| |O| - | |O| | // Player 2 makes a move at (1, 1). - | | |X| - - toe.move(2, 0, 1); -> Returns 0 (no one wins) - |X| |O| - | |O| | // Player 1 makes a move at (2, 0). - |X| |X| - - toe.move(1, 0, 2); -> Returns 0 (no one wins) - |X| |O| - |O|O| | // Player 2 makes a move at (1, 0). - |X| |X| - - toe.move(2, 1, 1); -> Returns 1 (player 1 wins) - |X| |O| - |O|O| | // Player 1 makes a move at (2, 1). - |X|X|X| - - Follow up: - Could you do better than O(n2) per move() operation? - - Solution: The below solution works in O(1) time complexity. - 1. For each player move, keep track of count of selection for each row and each column. - 2. To keep track of counts in each diagonals we need to first know if the move is made on either one of the diagonals. - The move is made in either of the diagonals if and only if (row = col) AND/OR (col + row = N - 1) - 3. As soon as the count in any of column, row or diagonal reach N then return the current player as the winner, else return 0. + *

+ * Design a Tic-tac-toe game that is played between two players on a n x n grid. + *

+ * You may assume the following rules: + *

+ * A move is guaranteed to be valid and is placed on an empty block. + * Once a winning condition is reached, no more moves is allowed. + * A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game. + * Example: + * Given n = 3, assume that player 1 is "X" and player 2 is "O" in the board. + *

+ * TicTacToe toe = new TicTacToe(3); + *

+ * toe.move(0, 0, 1); -> Returns 0 (no one wins) + * |X| | | + * | | | | // Player 1 makes a move at (0, 0). + * | | | | + *

+ * toe.move(0, 2, 2); -> Returns 0 (no one wins) + * |X| |O| + * | | | | // Player 2 makes a move at (0, 2). + * | | | | + *

+ * toe.move(2, 2, 1); -> Returns 0 (no one wins) + * |X| |O| + * | | | | // Player 1 makes a move at (2, 2). + * | | |X| + *

+ * toe.move(1, 1, 2); -> Returns 0 (no one wins) + * |X| |O| + * | |O| | // Player 2 makes a move at (1, 1). + * | | |X| + *

+ * toe.move(2, 0, 1); -> Returns 0 (no one wins) + * |X| |O| + * | |O| | // Player 1 makes a move at (2, 0). + * |X| |X| + *

+ * toe.move(1, 0, 2); -> Returns 0 (no one wins) + * |X| |O| + * |O|O| | // Player 2 makes a move at (1, 0). + * |X| |X| + *

+ * toe.move(2, 1, 1); -> Returns 1 (player 1 wins) + * |X| |O| + * |O|O| | // Player 1 makes a move at (2, 1). + * |X|X|X| + *

+ * Follow up: + * Could you do better than O(n2) per move() operation? + *

+ * Solution: The below solution works in O(1) time complexity. + * 1. For each player move, keep track of count of selection for each row and each column. + * 2. To keep track of counts in each diagonals we need to first know if the move is made on either one of the diagonals. + * The move is made in either of the diagonals if and only if (row = col) AND/OR (col + row = N - 1) + * 3. As soon as the count in any of column, row or diagonal reach N then return the current player as the winner, else return 0. */ -public class TicTacToe -{ +public class TicTacToe { /** * Cell class to keep track of first player and second player row/column count */ - private class Cell - { + private class Cell { int player1 = 0, player2 = 0; } @@ -74,11 +72,11 @@ private class Cell /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TicTacToe toe = new TicTacToe(3); System.out.println(toe.move(0, 0, 1)); System.out.println(toe.move(0, 2, 2)); @@ -87,9 +85,10 @@ public static void main(String[] args) throws Exception System.out.println(toe.move(2, 0, 1)); } - /** Initialize your data structure here. */ - public TicTacToe(int n) - { + /** + * Initialize your data structure here. + */ + public TicTacToe(int n) { N = n; rows = new Cell[N]; columns = new Cell[N]; @@ -97,23 +96,22 @@ public TicTacToe(int n) /** * Move and check who wins. - * @param row row - * @param col col + * + * @param row row + * @param col col * @param player player * @return integer indicating the winner */ - public int move(int row, int col, int player) - { - switch (player) - { + public int move(int row, int col, int player) { + switch (player) { case 1: increment(rows, row, 1); increment(columns, col, 1); - if((col + row) == (N - 1)) - fPD2 ++; - if(row == col) - fPD1 ++; - if(rows[row].player1 == N + if ((col + row) == (N - 1)) + fPD2++; + if (row == col) + fPD1++; + if (rows[row].player1 == N || columns[col].player1 == N || fPD1 == N || fPD2 == N) return 1; break; @@ -121,11 +119,11 @@ public int move(int row, int col, int player) case 2: increment(rows, row, 2); increment(columns, col, 2); - if((col + row) == (N - 1)) - sPD2 ++; - if(row == col) - sPD1 ++; - if(rows[row].player2 == N + if ((col + row) == (N - 1)) + sPD2++; + if (row == col) + sPD1++; + if (rows[row].player2 == N || columns[col].player2 == N || sPD1 == N || sPD2 == N) return 2; break; @@ -135,17 +133,18 @@ public int move(int row, int col, int player) /** * Increment row / col count - * @param cells array of cells - * @param key row / col key + * + * @param cells array of cells + * @param key row / col key * @param player Player object */ private void increment(Cell[] cells, int key, int player) { Cell p = cells[key]; - if(p == null) { + if (p == null) { p = new Cell(); cells[key] = p; } - if(player == 1) + if (player == 1) p.player1++; else p.player2++; } diff --git a/problems/src/design/Trie.java b/problems/src/design/Trie.java index 3b6f8711..ff77639c 100644 --- a/problems/src/design/Trie.java +++ b/problems/src/design/Trie.java @@ -6,19 +6,21 @@ /** * Created by Goutham Vidya Pradhan on 7/3/2017. * Implement a trie with insert, search, and startsWith methods. - - Note: - You may assume that all inputs are consist of lowercase letters a-z. + *

+ * Note: + * You may assume that all inputs are consist of lowercase letters a-z. */ public class Trie { private Map map; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { Trie trie = new Trie(); trie.insert("boxing"); trie.insert("box"); @@ -27,67 +29,73 @@ public static void main(String[] args) throws Exception{ System.out.println(trie.search("box")); } - /** Initialize your data structure here. */ + /** + * Initialize your data structure here. + */ public Trie() { map = new HashMap<>(); } - /** Inserts a word into the trie. */ + /** + * Inserts a word into the trie. + */ public void insert(String word) { - if(word != null){ + if (word != null) { add(0, word, word.length()); } } - private void add(int i, String word, int length){ - if(i < length){ + private void add(int i, String word, int length) { + if (i < length) { char c = word.charAt(i); Trie subTrie = map.get(c); - if(subTrie == null){ + if (subTrie == null) { subTrie = new Trie(); map.put(c, subTrie); } subTrie.add(i + 1, word, length); - } - else map.put(null, new Trie()); //use null to indicate end of string + } else map.put(null, new Trie()); //use null to indicate end of string } - /** Returns if the word is in the trie. */ + /** + * Returns if the word is in the trie. + */ public boolean search(String word) { - if(word != null){ + if (word != null) { return search(0, word, word.length()); } return false; } - private boolean search(int i, String word, int length){ - if(i < length){ + private boolean search(int i, String word, int length) { + if (i < length) { char c = word.charAt(i); Trie subTrie = map.get(c); - if(subTrie == null) + if (subTrie == null) return false; return subTrie.search(i + 1, word, length); } return map.containsKey(null); } - /** Returns if there is any word in the trie that starts with the given prefix. */ + /** + * Returns if there is any word in the trie that starts with the given prefix. + */ public boolean startsWith(String prefix) { - if(prefix != null){ + if (prefix != null) { return startsWith(0, prefix, prefix.length()); } return false; } - private boolean startsWith(int i, String prefix, int length){ - if(i < length){ + private boolean startsWith(int i, String prefix, int length) { + if (i < length) { char c = prefix.charAt(i); Trie subTrie = map.get(c); - if(subTrie == null) + if (subTrie == null) return false; return subTrie.startsWith(i + 1, prefix, length); - } - else return true; + } else return true; } } diff --git a/problems/src/design/Twitter.java b/problems/src/design/Twitter.java index d56c3bc2..88095f88 100644 --- a/problems/src/design/Twitter.java +++ b/problems/src/design/Twitter.java @@ -4,64 +4,61 @@ /** * Created by gouthamvidyapradhan on 18/03/2017. - Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and is able to see the 10 most recent tweets in the user's news feed. Your design should support the following methods: - - postTweet(userId, tweetId): Compose a new tweet. - getNewsFeed(userId): Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. - follow(followerId, followeeId): Follower follows a followee. - unfollow(followerId, followeeId): Follower unfollows a followee. - Example: - - Twitter twitter = new Twitter(); - - // User 1 posts a new tweet (id = 5). - twitter.postTweet(1, 5); - - // User 1's news feed should return a list with 1 tweet id -> [5]. - twitter.getNewsFeed(1); - - // User 1 follows user 2. - twitter.follow(1, 2); - - // User 2 posts a new tweet (id = 6). - twitter.postTweet(2, 6); - - // User 1's news feed should return a list with 2 tweet ids -> [6, 5]. - // Tweet id 6 should precede tweet id 5 because it is posted after tweet id 5. - twitter.getNewsFeed(1); - - // User 1 unfollows user 2. - twitter.unfollow(1, 2); - - // User 1's news feed should return a list with 1 tweet id -> [5], - // since user 1 is no longer following user 2. - twitter.getNewsFeed(1); + * Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and is able to see the 10 most recent tweets in the user's news feed. Your design should support the following methods: + *

+ * postTweet(userId, tweetId): Compose a new tweet. + * getNewsFeed(userId): Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. + * follow(followerId, followeeId): Follower follows a followee. + * unfollow(followerId, followeeId): Follower unfollows a followee. + * Example: + *

+ * Twitter twitter = new Twitter(); + *

+ * // User 1 posts a new tweet (id = 5). + * twitter.postTweet(1, 5); + *

+ * // User 1's news feed should return a list with 1 tweet id -> [5]. + * twitter.getNewsFeed(1); + *

+ * // User 1 follows user 2. + * twitter.follow(1, 2); + *

+ * // User 2 posts a new tweet (id = 6). + * twitter.postTweet(2, 6); + *

+ * // User 1's news feed should return a list with 2 tweet ids -> [6, 5]. + * // Tweet id 6 should precede tweet id 5 because it is posted after tweet id 5. + * twitter.getNewsFeed(1); + *

+ * // User 1 unfollows user 2. + * twitter.unfollow(1, 2); + *

+ * // User 1's news feed should return a list with 1 tweet id -> [5], + * // since user 1 is no longer following user 2. + * twitter.getNewsFeed(1); */ -public class Twitter -{ - class User - { +public class Twitter { + class User { int id; Set follow = new HashSet<>(); Queue tweets = new ArrayDeque<>(); - User(int id) - { + + User(int id) { this.id = id; } - public void follow(int id) - { + + public void follow(int id) { follow.add(id); } - public void addTweet(Tweet t) - { - if(tweets.size() == 10) - { + + public void addTweet(Tweet t) { + if (tweets.size() == 10) { tweets.poll(); } tweets.offer(t); } - public void unFollow(int id) - { + + public void unFollow(int id) { follow.remove(id); } @@ -74,12 +71,11 @@ public Queue getTweets() { } } - class Tweet - { + class Tweet { int id; long time; - Tweet(int id, long time) - { + + Tweet(int id, long time) { this.id = id; this.time = time; } @@ -88,13 +84,14 @@ class Tweet private Map userMap; private Map tweetMap; private static long tweetCount = 0L; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { Twitter twitter = new Twitter(); twitter.postTweet(1, 5); twitter.follow(1, 1); @@ -114,41 +111,40 @@ public static void main(String[] args) throws Exception */ } - /** Initialize your data structure here. */ - public Twitter() - { + /** + * Initialize your data structure here. + */ + public Twitter() { userMap = new HashMap<>(); tweetMap = new HashMap<>(); } - /** Compose a new tweet. */ - public void postTweet(int userId, int tweetId) - { + /** + * Compose a new tweet. + */ + public void postTweet(int userId, int tweetId) { User user = userMap.get(userId); - if(user == null) - { + if (user == null) { user = new User(userId); userMap.put(userId, user); } user.addTweet(new Tweet(tweetId, tweetCount++)); } - /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ - public List getNewsFeed(int userId) - { + /** + * Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. + */ + public List getNewsFeed(int userId) { User user = userMap.get(userId); List result = new ArrayList<>(); - if(user == null) return result; + if (user == null) return result; Set follwers = user.getFollow(); - if(follwers != null) - { + if (follwers != null) { List tweets = new ArrayList<>(); tweets.addAll(user.getTweets()); - for(Integer i : follwers) - { + for (Integer i : follwers) { User f = userMap.get(i); - if(f != null) - { + if (f != null) { tweets.addAll(f.getTweets()); } } @@ -161,9 +157,8 @@ public int compare(Tweet o1, Tweet o2) { Collections.sort(tweets, comparator); - for(int i = 0; i < 10; i ++) - { - if(i >= tweets.size()) + for (int i = 0; i < 10; i++) { + if (i >= tweets.size()) break; result.add(tweets.get(i).id); } @@ -171,32 +166,30 @@ public int compare(Tweet o1, Tweet o2) { return result; } - /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ - public void follow(int followerId, int followeeId) - { - if(followerId == followeeId) return; + /** + * Follower follows a followee. If the operation is invalid, it should be a no-op. + */ + public void follow(int followerId, int followeeId) { + if (followerId == followeeId) return; User user = userMap.get(followerId); - if(user == null) + if (user == null) user = new User(followerId); userMap.put(followerId, user); - if(userMap.get(followeeId) != null) - { + if (userMap.get(followeeId) != null) { user.follow(userMap.get(followeeId).id); - } - else - { + } else { User newUser = new User(followeeId); userMap.put(followeeId, newUser); user.follow(userMap.get(followeeId).id); } } - /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ - public void unfollow(int followerId, int followeeId) - { + /** + * Follower unfollows a followee. If the operation is invalid, it should be a no-op. + */ + public void unfollow(int followerId, int followeeId) { User user = userMap.get(followerId); - if(user != null) - { + if (user != null) { user.unFollow(followeeId); } } diff --git a/problems/src/divide_and_conquer/KthLargestElementInAnArray.java b/problems/src/divide_and_conquer/KthLargestElementInAnArray.java index 7d2b44db..4d4d4249 100644 --- a/problems/src/divide_and_conquer/KthLargestElementInAnArray.java +++ b/problems/src/divide_and_conquer/KthLargestElementInAnArray.java @@ -2,42 +2,37 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. - - For example, - Given [3,2,1,5,6,4] and k = 2, return 5. - - Note: - You may assume k is always valid, 1 ≤ k ≤ array's length. + * Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. + *

+ * For example, + * Given [3,2,1,5,6,4] and k = 2, return 5. + *

+ * Note: + * You may assume k is always valid, 1 ≤ k ≤ array's length. */ -public class KthLargestElementInAnArray -{ +public class KthLargestElementInAnArray { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] nums = {3,2,1,5,6,4}; + public static void main(String[] args) throws Exception { + int[] nums = {3, 2, 1, 5, 6, 4}; System.out.println(new KthLargestElementInAnArray().findKthLargest(nums, 6)); } - private int findKthLargest(int[] nums, int k) - { + private int findKthLargest(int[] nums, int k) { return solve(nums, 0, nums.length - 1, k); } - private int solve(int[] nums, int pIndex, int end, int k) - { + private int solve(int[] nums, int pIndex, int end, int k) { int pivot = nums[end]; int temp; int start = pIndex; - for(int i = pIndex; i < end; i ++) - { - if(nums[i] <= pivot) - { + for (int i = pIndex; i < end; i++) { + if (nums[i] <= pivot) { temp = nums[i]; nums[i] = nums[pIndex]; nums[pIndex] = temp; @@ -49,13 +44,10 @@ private int solve(int[] nums, int pIndex, int end, int k) nums[end] = temp; int pos = (end - pIndex) + 1; - if(pos == k) return nums[pIndex]; - else if(pos > k) - { + if (pos == k) return nums[pIndex]; + else if (pos > k) { return solve(nums, pIndex + 1, end, k); - } - else - { + } else { return solve(nums, start, pIndex - 1, k - pos); } } diff --git a/problems/src/divide_and_conquer/SearchA2DMatrix.java b/problems/src/divide_and_conquer/SearchA2DMatrix.java index fb533803..c876b612 100644 --- a/problems/src/divide_and_conquer/SearchA2DMatrix.java +++ b/problems/src/divide_and_conquer/SearchA2DMatrix.java @@ -2,57 +2,54 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: - - Integers in each row are sorted in ascending from left to right. - Integers in each column are sorted in ascending from top to bottom. - For example, - - Consider the following matrix: - - [ - [1, 4, 7, 11, 15], - [2, 5, 8, 12, 19], - [3, 6, 9, 16, 22], - [10, 13, 14, 17, 24], - [18, 21, 23, 26, 30] - ] - Given target = 5, return true. - - Given target = 20, return false. + * Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: + *

+ * Integers in each row are sorted in ascending from left to right. + * Integers in each column are sorted in ascending from top to bottom. + * For example, + *

+ * Consider the following matrix: + *

+ * [ + * [1, 4, 7, 11, 15], + * [2, 5, 8, 12, 19], + * [3, 6, 9, 16, 22], + * [10, 13, 14, 17, 24], + * [18, 21, 23, 26, 30] + * ] + * Given target = 5, return true. + *

+ * Given target = 20, return false. */ -public class SearchA2DMatrix -{ +public class SearchA2DMatrix { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[][] matrix = { - {1,3,5,7,9} , //1, 3, 5, 7, 9 - {2,4,6,8,10}, //2, 4, 6, 8, 10 - {11,13,15,17,19}, //11, 15, 17, 18, 19 - {12,14,16,18,20}, //13, 20, 21, 22, 23 - {21,22,23,24,25} //14, 25, 26, 27, 28 + {1, 3, 5, 7, 9}, //1, 3, 5, 7, 9 + {2, 4, 6, 8, 10}, //2, 4, 6, 8, 10 + {11, 13, 15, 17, 19}, //11, 15, 17, 18, 19 + {12, 14, 16, 18, 20}, //13, 20, 21, 22, 23 + {21, 22, 23, 24, 25} //14, 25, 26, 27, 28 }; System.out.println(new SearchA2DMatrix().searchMatrix(matrix, 11)); } - private boolean searchMatrix(int[][] matrix, int target) - { - if(matrix.length == 0) return false; + private boolean searchMatrix(int[][] matrix, int target) { + if (matrix.length == 0) return false; int M = matrix.length; int N = matrix[0].length; int r = 0, c = N - 1; - while(r < M && c >= 0) - { - if(matrix[r][c] == target) return true; - else if(target < matrix[r][c]) --c; - else if(target > matrix[r][c]) r++; + while (r < M && c >= 0) { + if (matrix[r][c] == target) return true; + else if (target < matrix[r][c]) --c; + else if (target > matrix[r][c]) r++; } return false; } diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java b/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java index 1d312863..54417f9f 100644 --- a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java +++ b/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java @@ -2,46 +2,42 @@ /** * Created by gouthamvidyapradhan on 17/03/2017. - Say you have an array for which the ith element is the price of a given stock on day i. - - If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit. - - Example 1: - Input: [7, 1, 5, 3, 6, 4] - Output: 5 - - max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price) - Example 2: - Input: [7, 6, 4, 3, 1] - Output: 0 - - In this case, no transaction is done, i.e. max profit = 0. + * Say you have an array for which the ith element is the price of a given stock on day i. + *

+ * If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit. + *

+ * Example 1: + * Input: [7, 1, 5, 3, 6, 4] + * Output: 5 + *

+ * max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price) + * Example 2: + * Input: [7, 6, 4, 3, 1] + * Output: 0 + *

+ * In this case, no transaction is done, i.e. max profit = 0. */ -public class BestTimeToBuyAndSellStocks -{ +public class BestTimeToBuyAndSellStocks { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] prices = {1, 1, 1, 1, 1}; System.out.println(new BestTimeToBuyAndSellStocks().maxProfit(prices)); } - public int maxProfit(int[] prices) - { - if(prices.length == 0) return 0; + public int maxProfit(int[] prices) { + if (prices.length == 0) return 0; int[] max = new int[prices.length]; max[prices.length - 1] = prices[prices.length - 1]; - for(int i = prices.length - 2; i >= 0; i --) - { + for (int i = prices.length - 2; i >= 0; i--) { max[i] = Math.max(prices[i], max[i + 1]); } int result = Integer.MIN_VALUE; - for(int i = 0, l = max.length; i < l; i ++) - { + for (int i = 0, l = max.length; i < l; i++) { result = Math.max(result, max[i] - prices[i]); } return result; diff --git a/problems/src/dynamic_programming/CanIWin.java b/problems/src/dynamic_programming/CanIWin.java index 3042da02..acd26de4 100644 --- a/problems/src/dynamic_programming/CanIWin.java +++ b/problems/src/dynamic_programming/CanIWin.java @@ -6,65 +6,67 @@ /** * Created by gouthamvidyapradhan on 04/07/2017. * In the "100 game," two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running total to reach or exceed 100 wins. - - What if we change the game so that players cannot re-use integers? - - For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100. - - Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally. - - You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300. - - Example - - Input: - maxChoosableInteger = 10 - desiredTotal = 11 - - Output: - false - - Explanation: - No matter which integer the first player choose, the first player will lose. - The first player can choose an integer from 1 up to 10. - If the first player choose 1, the second player can only choose integers from 2 up to 10. - The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal. - Same with other integers chosen by the first player, the second player will always win. + *

+ * What if we change the game so that players cannot re-use integers? + *

+ * For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100. + *

+ * Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally. + *

+ * You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300. + *

+ * Example + *

+ * Input: + * maxChoosableInteger = 10 + * desiredTotal = 11 + *

+ * Output: + * false + *

+ * Explanation: + * No matter which integer the first player choose, the first player will lose. + * The first player can choose an integer from 1 up to 10. + * If the first player choose 1, the second player can only choose integers from 2 up to 10. + * The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal. + * Same with other integers chosen by the first player, the second player will always win. */ public class CanIWin { private Map> DP; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new CanIWin().canIWin(5, 15)); } public boolean canIWin(int maxChoosableInteger, int desiredTotal) { int sum = 0; - for(int i = 1; i <= maxChoosableInteger; i ++) + for (int i = 1; i <= maxChoosableInteger; i++) sum += i; - if(desiredTotal == 0) return true; - else if(desiredTotal > sum) return false; //if the desiredTotal exceeds the max possible sum return false; + if (desiredTotal == 0) return true; + else if (desiredTotal > sum) return false; //if the desiredTotal exceeds the max possible sum return false; DP = new HashMap<>(); DP.put(true, new HashMap<>()); DP.put(false, new HashMap<>()); return dp(0, maxChoosableInteger, desiredTotal, true, 0); } - private boolean dp(int state, int M, int D, boolean P, int sum){ - if(sum >= D) return false; + private boolean dp(int state, int M, int D, boolean P, int sum) { + if (sum >= D) return false; Map map = DP.get(P); - if(map.containsKey(state)) + if (map.containsKey(state)) return map.get(state); else { map.put(state, false); - for(int i = 0; i < M; i ++){ - if((state & (1 << i)) == 0){ - if(!dp(state | (1 << i), M, D, !P, sum + i + 1)){ + for (int i = 0; i < M; i++) { + if ((state & (1 << i)) == 0) { + if (!dp(state | (1 << i), M, D, !P, sum + i + 1)) { map.put(state, true); break; } diff --git a/problems/src/dynamic_programming/ClimbingStairs.java b/problems/src/dynamic_programming/ClimbingStairs.java index d886fd3c..a5f1cd34 100644 --- a/problems/src/dynamic_programming/ClimbingStairs.java +++ b/problems/src/dynamic_programming/ClimbingStairs.java @@ -2,32 +2,30 @@ /** * Created by gouthamvidyapradhan on 01/04/2017. - You are climbing a stair case. It takes n steps to reach to the top. - - Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? - - Note: Given n will be a positive integer. + * You are climbing a stair case. It takes n steps to reach to the top. + *

+ * Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? + *

+ * Note: Given n will be a positive integer. */ -public class ClimbingStairs -{ +public class ClimbingStairs { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - public int climbStairs(int n) - { - if(n == 0 || n == 1) return 1; + public int climbStairs(int n) { + if (n == 0 || n == 1) return 1; int[] A = new int[n + 1]; A[n] = 1; A[n - 1] = 1; - for(int i = n - 2; i >= 0; i --) - A[i] = A[i + 1] + A[i + 2]; + for (int i = n - 2; i >= 0; i--) + A[i] = A[i + 1] + A[i + 2]; return A[0]; } diff --git a/problems/src/dynamic_programming/CoinChange.java b/problems/src/dynamic_programming/CoinChange.java index b9a1bf3f..b6e1445b 100644 --- a/problems/src/dynamic_programming/CoinChange.java +++ b/problems/src/dynamic_programming/CoinChange.java @@ -5,43 +5,43 @@ * You are given coins of different denominations and a total amount of money amount. * Write a function to compute the fewest number of coins that you need to make up that amount. * If that amount of money cannot be made up by any combination of the coins, return -1. - - Example 1: - coins = [1, 2, 5], amount = 11 - return 3 (11 = 5 + 5 + 1) - - Example 2: - coins = [2], amount = 3 - return -1. - - Note: - You may assume that you have an infinite number of each kind of coin. - - Solution: - For example if you have N coins and amount equal to Q - For every coin you have two options - i) If you chose to include this coin then, total amount reduces by the sum equivalent to the value of this coin and you are - left with N coins and Q = (Q - value of this coin) - ii) If you chose not to include this coin then, you are left with N - 1 coins (since you chose to not to include this coin) - and total amount is still equal to Q - - Calculate recursively for each coin and possible amount - Since there can be overlapping sub-problems you can save the state in a 2D matrix - a typical DP approach. - - For each state minimum is calculated using -> Min(1 + fn(i, amount - v[i]), fn(i + 1, amount)) - - Worst-case time complexity is O(N x Q) where N is the total number of coins and Q is the total amount - + *

+ * Example 1: + * coins = [1, 2, 5], amount = 11 + * return 3 (11 = 5 + 5 + 1) + *

+ * Example 2: + * coins = [2], amount = 3 + * return -1. + *

+ * Note: + * You may assume that you have an infinite number of each kind of coin. + *

+ * Solution: + * For example if you have N coins and amount equal to Q + * For every coin you have two options + * i) If you chose to include this coin then, total amount reduces by the sum equivalent to the value of this coin and you are + * left with N coins and Q = (Q - value of this coin) + * ii) If you chose not to include this coin then, you are left with N - 1 coins (since you chose to not to include this coin) + * and total amount is still equal to Q + *

+ * Calculate recursively for each coin and possible amount + * Since there can be overlapping sub-problems you can save the state in a 2D matrix - a typical DP approach. + *

+ * For each state minimum is calculated using -> Min(1 + fn(i, amount - v[i]), fn(i + 1, amount)) + *

+ * Worst-case time complexity is O(N x Q) where N is the total number of coins and Q is the total amount */ -public class CoinChange -{ +public class CoinChange { private int[][] DP; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] coins = {1, 2, 5}; System.out.println(new CoinChange().coinChange(coins, 11)); } @@ -49,14 +49,14 @@ public static void main(String[] args) throws Exception{ public int coinChange(int[] coins, int amount) { DP = new int[coins.length][amount + 1]; int result = dp(amount, 0, coins); - if(result == Integer.MAX_VALUE - 1) return -1; + if (result == Integer.MAX_VALUE - 1) return -1; return result; } - private int dp(int amount, int i, int[] coins){ - if(amount == 0) return 0; - else if(i >= coins.length || amount < 0) return Integer.MAX_VALUE - 1; - if(DP[i][amount] != 0) return DP[i][amount]; + private int dp(int amount, int i, int[] coins) { + if (amount == 0) return 0; + else if (i >= coins.length || amount < 0) return Integer.MAX_VALUE - 1; + if (DP[i][amount] != 0) return DP[i][amount]; DP[i][amount] = Math.min(1 + dp(amount - coins[i], i, coins), dp(amount, i + 1, coins)); return DP[i][amount]; } diff --git a/problems/src/dynamic_programming/CoinChange2.java b/problems/src/dynamic_programming/CoinChange2.java index 275e02a5..2f072002 100644 --- a/problems/src/dynamic_programming/CoinChange2.java +++ b/problems/src/dynamic_programming/CoinChange2.java @@ -4,60 +4,57 @@ /** * Created by gouthamvidyapradhan on 22/03/2017. - You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin. - - Note: You can assume that - - 0 <= amount <= 5000 - 1 <= coin <= 5000 - the number of coins is less than 500 - the answer is guaranteed to fit into signed 32-bit integer - Example 1: - - Input: amount = 5, coins = [1, 2, 5] - Output: 4 - Explanation: there are four ways to make up the amount: - 5=5 - 5=2+2+1 - 5=2+1+1+1 - 5=1+1+1+1+1 - Example 2: - - Input: amount = 3, coins = [2] - Output: 0 - Explanation: the amount of 3 cannot be made up just with coins of 2. - Example 3: - - Input: amount = 10, coins = [10] - Output: 1 + * You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin. + *

+ * Note: You can assume that + *

+ * 0 <= amount <= 5000 + * 1 <= coin <= 5000 + * the number of coins is less than 500 + * the answer is guaranteed to fit into signed 32-bit integer + * Example 1: + *

+ * Input: amount = 5, coins = [1, 2, 5] + * Output: 4 + * Explanation: there are four ways to make up the amount: + * 5=5 + * 5=2+2+1 + * 5=2+1+1+1 + * 5=1+1+1+1+1 + * Example 2: + *

+ * Input: amount = 3, coins = [2] + * Output: 0 + * Explanation: the amount of 3 cannot be made up just with coins of 2. + * Example 3: + *

+ * Input: amount = 10, coins = [10] + * Output: 1 */ -public class CoinChange2 -{ +public class CoinChange2 { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] coins = {1,2,5}; + public static void main(String[] args) throws Exception { + int[] coins = {1, 2, 5}; System.out.println(new CoinChange2().change(5, coins)); } - public int change(int amount, int[] coins) - { + public int change(int amount, int[] coins) { int[][] dp = new int[coins.length][amount + 1]; - for(int i = 0, l = coins.length; i < l; i ++) + for (int i = 0, l = coins.length; i < l; i++) Arrays.fill(dp[i], -1); return dp(dp, 0, coins, coins.length, amount); } - private int dp(int[][] dp, int i, int[] coins, int l, int n) - { - if(n == 0) return 1; - else if(i >= l) return 0; - if(n < 0) return 0; - if(dp[i][n] != -1) return dp[i][n]; + private int dp(int[][] dp, int i, int[] coins, int l, int n) { + if (n == 0) return 1; + else if (i >= l) return 0; + if (n < 0) return 0; + if (dp[i][n] != -1) return dp[i][n]; dp[i][n] = dp(dp, i + 1, coins, l, n) + dp(dp, i, coins, l, n - coins[i]); return dp[i][n]; } diff --git a/problems/src/dynamic_programming/ConcatenatedWords.java b/problems/src/dynamic_programming/ConcatenatedWords.java index 12a25a8a..dc4254ac 100644 --- a/problems/src/dynamic_programming/ConcatenatedWords.java +++ b/problems/src/dynamic_programming/ConcatenatedWords.java @@ -8,56 +8,51 @@ /** * Created by gouthamvidyapradhan on 12/06/2017. * Accepted - Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words. - - A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array. - - Example: - Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] - - Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] - - Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; - "dogcatsdog" can be concatenated by "dog", "cats" and "dog"; - "ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat". - - Note: - The number of elements of the given array will not exceed 10,000 - The length sum of elements in the given array will not exceed 600,000. - All the input string will only include lower case letters. - The returned elements order does not matter. - - + * Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words. + *

+ * A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array. + *

+ * Example: + * Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] + *

+ * Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] + *

+ * Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; + * "dogcatsdog" can be concatenated by "dog", "cats" and "dog"; + * "ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat". + *

+ * Note: + * The number of elements of the given array will not exceed 10,000 + * The length sum of elements in the given array will not exceed 600,000. + * All the input string will only include lower case letters. + * The returned elements order does not matter. */ -public class ConcatenatedWords -{ - public static void main(String[] args) throws Exception - { +public class ConcatenatedWords { + public static void main(String[] args) throws Exception { String[] words = {""}; System.out.println(new ConcatenatedWords().findAllConcatenatedWordsInADict(words)); } public List findAllConcatenatedWordsInADict(String[] words) { Set dictionary = new HashSet<>(); - for(String w : words) - dictionary.add(w); + for (String w : words) + dictionary.add(w); List result = new ArrayList<>(); - for(String w : words) { - if(!w.isEmpty() && concatenatedWordsPossible(w, dictionary)) + for (String w : words) { + if (!w.isEmpty() && concatenatedWordsPossible(w, dictionary)) result.add(w); } return result; } - private boolean concatenatedWordsPossible(String word, Set dictionary) - { + private boolean concatenatedWordsPossible(String word, Set dictionary) { boolean[] D = new boolean[word.length() + 1]; D[word.length()] = true; dictionary.remove(word); //remove current word from dictionary temporarily - for(int i = word.length() - 1; i >= 0; i --) { - for(int j = i, l = word.length(); j < l; j ++) { + for (int i = word.length() - 1; i >= 0; i--) { + for (int j = i, l = word.length(); j < l; j++) { String subStr = word.substring(i, j + 1); - if(dictionary.contains(subStr) && D[j + 1]) { + if (dictionary.contains(subStr) && D[j + 1]) { D[i] = true; break; } diff --git a/problems/src/dynamic_programming/DecodeWays.java b/problems/src/dynamic_programming/DecodeWays.java index 95dffb39..f554179f 100644 --- a/problems/src/dynamic_programming/DecodeWays.java +++ b/problems/src/dynamic_programming/DecodeWays.java @@ -2,49 +2,42 @@ /** * Created by gouthamvidyapradhan on 01/04/2017. - A message containing letters from A-Z is being encoded to numbers using the following mapping: - - 'A' -> 1 - 'B' -> 2 - ... - 'Z' -> 26 - Given an encoded message containing digits, determine the total number of ways to decode it. - - For example, - Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). - - The number of ways decoding "12" is 2. + * A message containing letters from A-Z is being encoded to numbers using the following mapping: + *

+ * 'A' -> 1 + * 'B' -> 2 + * ... + * 'Z' -> 26 + * Given an encoded message containing digits, determine the total number of ways to decode it. + *

+ * For example, + * Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). + *

+ * The number of ways decoding "12" is 2. */ -public class DecodeWays -{ +public class DecodeWays { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new DecodeWays().numDecodings("3120")); } - public int numDecodings(String s) - { - if(s == null || s.isEmpty()) return 0; + public int numDecodings(String s) { + if (s == null || s.isEmpty()) return 0; int[] dp = new int[s.length() + 2]; dp[s.length()] = 1; dp[s.length() + 1] = 1; - for(int i = s.length() - 1; i >= 0; i --) - { - for(int j = i + 1; j < i + 3; j ++) - { - if(j <= s.length()) - { + for (int i = s.length() - 1; i >= 0; i--) { + for (int j = i + 1; j < i + 3; j++) { + if (j <= s.length()) { String subStr = s.substring(i, j); - if(!subStr.startsWith("0")) - { + if (!subStr.startsWith("0")) { int intVal = Integer.parseInt(subStr); - if(intVal <= 26) - { + if (intVal <= 26) { dp[i] += dp[j]; } } diff --git a/problems/src/dynamic_programming/DungeonGame.java b/problems/src/dynamic_programming/DungeonGame.java index f58ba285..03111f51 100644 --- a/problems/src/dynamic_programming/DungeonGame.java +++ b/problems/src/dynamic_programming/DungeonGame.java @@ -6,36 +6,37 @@ * Created by gouthamvidyapradhan on 12/07/2017. * The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. * The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess. - - The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately. - - Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers). - - In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step. - - - Write a function to determine the knight's minimum initial health so that he is able to rescue the princess. - - For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN. - - -2 (K) -3 3 - -5 -10 1 - 10 30 -5 (P) - - Notes: - - The knight's health has no upper bound. - Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned. - - Solution: O(MxN log Integer.MAX_VALUE) - Binary search the suitable initial health value in the range (1, Integer.MAX_VALUE) and do a top down DP to check the - balance health when he reaches princess. + *

+ * The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately. + *

+ * Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers). + *

+ * In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step. + *

+ *

+ * Write a function to determine the knight's minimum initial health so that he is able to rescue the princess. + *

+ * For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN. + *

+ * -2 (K) -3 3 + * -5 -10 1 + * 10 30 -5 (P) + *

+ * Notes: + *

+ * The knight's health has no upper bound. + * Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned. + *

+ * Solution: O(MxN log Integer.MAX_VALUE) + * Binary search the suitable initial health value in the range (1, Integer.MAX_VALUE) and do a top down DP to check the + * balance health when he reaches princess. */ public class DungeonGame { private final int[] R = {0, -1}; private final int[] C = {-1, 0}; private int DP[][]; - public static void main(String[] args) throws Exception{ + + public static void main(String[] args) throws Exception { int[][] dungeon = {{200}}; System.out.println(new DungeonGame().calculateMinimumHP(dungeon)); } @@ -43,30 +44,30 @@ public static void main(String[] args) throws Exception{ public int calculateMinimumHP(int[][] dungeon) { DP = new int[dungeon.length][dungeon[0].length]; int l = 0, h = Integer.MAX_VALUE, ans = 0; - while(l <= h){ + while (l <= h) { int m = l + (h - l) / 2; - for(int i = 0; i < dungeon.length; i ++) + for (int i = 0; i < dungeon.length; i++) Arrays.fill(DP[i], Integer.MIN_VALUE); DP[0][0] = m + dungeon[0][0]; - if(dp(dungeon, dungeon.length - 1, dungeon[0].length - 1) > 0){ + if (dp(dungeon, dungeon.length - 1, dungeon[0].length - 1) > 0) { ans = m; h = m - 1; - }else{ + } else { l = m + 1; } } return ans == 0 ? 1 : ans; } - private int dp(int[][] dungeon, int r, int c){ - if(DP[r][c] != Integer.MIN_VALUE) + private int dp(int[][] dungeon, int r, int c) { + if (DP[r][c] != Integer.MIN_VALUE) return DP[r][c]; - for(int i = 0; i < 2; i ++){ + for (int i = 0; i < 2; i++) { int newR = r + R[i]; int newC = c + C[i]; - if(newR >= 0 && newR < dungeon.length && newC >=0 && newC < dungeon[0].length){ + if (newR >= 0 && newR < dungeon.length && newC >= 0 && newC < dungeon[0].length) { int life = dp(dungeon, newR, newC); - if(life <= 0) + if (life <= 0) DP[r][c] = Math.max(DP[r][c], 0); else DP[r][c] = Math.max(DP[r][c], dungeon[r][c] + life); } diff --git a/problems/src/dynamic_programming/HouseRobber.java b/problems/src/dynamic_programming/HouseRobber.java index aa4ccfdd..14678335 100644 --- a/problems/src/dynamic_programming/HouseRobber.java +++ b/problems/src/dynamic_programming/HouseRobber.java @@ -2,32 +2,30 @@ /** * Created by pradhang on 4/3/2017. - You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. - - Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. + * You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. + *

+ * Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. */ -public class HouseRobber -{ +public class HouseRobber { private int[] max; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - public int rob(int[] nums) - { - if(nums.length == 0) return 0; + public int rob(int[] nums) { + if (nums.length == 0) return 0; max = new int[nums.length]; - if(nums.length == 1) return nums[0]; + if (nums.length == 1) return nums[0]; max[nums.length - 1] = nums[nums.length - 1]; max[nums.length - 2] = Math.max(nums[nums.length - 1], nums[nums.length - 2]); - for(int i = nums.length - 3; i >= 0; i --) - { + for (int i = nums.length - 3; i >= 0; i--) { max[i] = Math.max(max[i + 1], nums[i] + max[i + 2]); } return max[0]; diff --git a/problems/src/dynamic_programming/HouseRobberII.java b/problems/src/dynamic_programming/HouseRobberII.java index f3554c76..ed118091 100644 --- a/problems/src/dynamic_programming/HouseRobberII.java +++ b/problems/src/dynamic_programming/HouseRobberII.java @@ -6,39 +6,38 @@ * Created by pradhang on 7/11/2017. * After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. * This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street. - - Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. + *

+ * Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. */ public class HouseRobberII { - public static void main(String[] args) throws Exception{ - int[] nums = {6,3,10,8,2,10,3,5,10,5,3}; + public static void main(String[] args) throws Exception { + int[] nums = {6, 3, 10, 8, 2, 10, 3, 5, 10, 5, 3}; System.out.println(new HouseRobberII().rob(nums)); } public int rob(int[] nums) { - if(nums.length == 0) return 0; - if(nums.length == 1) + if (nums.length == 0) return 0; + if (nums.length == 1) return nums[0]; - else if(nums.length == 2){ - if(nums[0] > nums[1]) + else if (nums.length == 2) { + if (nums[0] > nums[1]) return nums[0]; return nums[1]; - } - else if(nums.length == 3) return Math.max(Math.max(nums[0], nums[1]), nums[2]); + } else if (nums.length == 3) return Math.max(Math.max(nums[0], nums[1]), nums[2]); int[] DP = new int[nums.length]; - for(int i = nums.length - 1; i > 0; i --){ - if(i + 3 < nums.length) + for (int i = nums.length - 1; i > 0; i--) { + if (i + 3 < nums.length) DP[i] = Math.max(nums[i] + DP[i + 2], nums[i] + DP[i + 3]); - else if(i + 2 < nums.length) + else if (i + 2 < nums.length) DP[i] = nums[i] + DP[i + 2]; else DP[i] = nums[i]; } int max = Math.max(DP[1], DP[2]); Arrays.fill(DP, 0); //reset - for(int i = nums.length - 2; i >= 0; i --){ - if(i + 3 < nums.length) + for (int i = nums.length - 2; i >= 0; i--) { + if (i + 3 < nums.length) DP[i] = Math.max(nums[i] + DP[i + 2], nums[i] + DP[i + 3]); - else if(i + 2 < nums.length) + else if (i + 2 < nums.length) DP[i] = nums[i] + DP[i + 2]; else DP[i] = nums[i]; } diff --git a/problems/src/dynamic_programming/LongestIncreasingSubsequence.java b/problems/src/dynamic_programming/LongestIncreasingSubsequence.java index 4a1bf4aa..db119e0d 100644 --- a/problems/src/dynamic_programming/LongestIncreasingSubsequence.java +++ b/problems/src/dynamic_programming/LongestIncreasingSubsequence.java @@ -2,40 +2,36 @@ /** * Created by gouthamvidyapradhan on 02/04/2017. - Given an unsorted array of integers, find the length of longest increasing subsequence. - - For example, - Given [10, 9, 2, 5, 3, 7, 101, 18], - The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. - - Your algorithm should run in O(n2) complexity. - - Follow up: Could you improve it to O(n log n) time complexity? + * Given an unsorted array of integers, find the length of longest increasing subsequence. + *

+ * For example, + * Given [10, 9, 2, 5, 3, 7, 101, 18], + * The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. + *

+ * Your algorithm should run in O(n2) complexity. + *

+ * Follow up: Could you improve it to O(n log n) time complexity? */ -public class LongestIncreasingSubsequence -{ +public class LongestIncreasingSubsequence { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] nums = {9, 8, 7, 6}; System.out.println(new LongestIncreasingSubsequence().lengthOfLIS(nums)); } - public int lengthOfLIS(int[] nums) - { - if(nums.length == 0) return 0; + public int lengthOfLIS(int[] nums) { + if (nums.length == 0) return 0; int[] A = new int[nums.length]; int max = Integer.MIN_VALUE; - for(int i = 0, l = nums.length; i < l; i ++) - { + for (int i = 0, l = nums.length; i < l; i++) { int lis = 1; - for(int j = 0; j < i; j ++) - { - if(nums[i] > nums[j]) + for (int j = 0; j < i; j++) { + if (nums[i] > nums[j]) lis = Math.max(lis, A[j] + 1); } A[i] = lis; diff --git a/problems/src/dynamic_programming/LongestPaliandromicSubstring.java b/problems/src/dynamic_programming/LongestPaliandromicSubstring.java index 33b92216..5587dea1 100644 --- a/problems/src/dynamic_programming/LongestPaliandromicSubstring.java +++ b/problems/src/dynamic_programming/LongestPaliandromicSubstring.java @@ -2,62 +2,54 @@ /** * Created by gouthamvidyapradhan on 24/02/2017. - Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. - - Example: - - Input: "babad" - - Output: "bab" - - Note: "aba" is also a valid answer. - Example: - - Input: "cbbd" - - Output: "bb" + * Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. + *

+ * Example: + *

+ * Input: "babad" + *

+ * Output: "bab" + *

+ * Note: "aba" is also a valid answer. + * Example: + *

+ * Input: "cbbd" + *

+ * Output: "bb" */ -public class LongestPaliandromicSubstring -{ +public class LongestPaliandromicSubstring { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new LongestPaliandromicSubstring().longestPalindrome("forgeeksskeegfor")); } - public String longestPalindrome(String s) - { + public String longestPalindrome(String s) { int l = s.length(); - int startIndex = 0; int maxLen = 1; + int startIndex = 0; + int maxLen = 1; boolean[][] A = new boolean[l][l]; - for(int i = 0, j = 0; i < l; i++, j++) + for (int i = 0, j = 0; i < l; i++, j++) A[i][j] = true; - for(int i = 0, j = i + 1; j < l; i++, j++) - { - if(s.charAt(i) == s.charAt(j)) - { + for (int i = 0, j = i + 1; j < l; i++, j++) { + if (s.charAt(i) == s.charAt(j)) { A[i][j] = true; startIndex = i; maxLen = 2; } } - for(int k = 3; k <= l; k++) - { - for(int i = 0, j = k - 1; j < l; i++, j++) - { - if(s.charAt(i) == s.charAt(j)) - { + for (int k = 3; k <= l; k++) { + for (int i = 0, j = k - 1; j < l; i++, j++) { + if (s.charAt(i) == s.charAt(j)) { A[i][j] = A[i + 1][j - 1]; - if(A[i][j]) - { - if(k > maxLen) - { + if (A[i][j]) { + if (k > maxLen) { startIndex = i; maxLen = k; } diff --git a/problems/src/dynamic_programming/LongestPalindromicSubsequence.java b/problems/src/dynamic_programming/LongestPalindromicSubsequence.java index d00f7890..b450687a 100644 --- a/problems/src/dynamic_programming/LongestPalindromicSubsequence.java +++ b/problems/src/dynamic_programming/LongestPalindromicSubsequence.java @@ -2,35 +2,32 @@ /** * Created by gouthamvidyapradhan on 27/03/2017. - Given an unsorted array of integers, find the length of longest increasing subsequence. - - For example, - Given [10, 9, 2, 5, 3, 7, 101, 18], - The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. - - Your algorithm should run in O(n2) complexity. - - Follow up: Could you improve it to O(n log n) time complexity? + * Given an unsorted array of integers, find the length of longest increasing subsequence. + *

+ * For example, + * Given [10, 9, 2, 5, 3, 7, 101, 18], + * The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. + *

+ * Your algorithm should run in O(n2) complexity. + *

+ * Follow up: Could you improve it to O(n log n) time complexity? */ -public class LongestPalindromicSubsequence -{ +public class LongestPalindromicSubsequence { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new LongestPalindromicSubsequence().longestPalindromeSubseq("bbbab")); } - public int longestPalindromeSubseq(String s) - { + public int longestPalindromeSubseq(String s) { int[][] dp = new int[s.length() + 1][s.length() + 1]; String sI = new StringBuilder(s).reverse().toString(); - for(int i = 1, l = s.length(); i <= l; i++) - for(int j = 1; j <= l; j++) - { + for (int i = 1, l = s.length(); i <= l; i++) + for (int j = 1; j <= l; j++) { dp[i][j] = (s.charAt(i - 1) == sI.charAt(j - 1)) ? dp[i - 1][j - 1] + 1 : Math.max(dp[i - 1][j], dp[i][j - 1]); } diff --git a/problems/src/dynamic_programming/MaximumProductSubarray.java b/problems/src/dynamic_programming/MaximumProductSubarray.java index 0ed05cdc..ee14e793 100644 --- a/problems/src/dynamic_programming/MaximumProductSubarray.java +++ b/problems/src/dynamic_programming/MaximumProductSubarray.java @@ -2,32 +2,29 @@ /** * Created by gouthamvidyapradhan on 02/04/2017. - Find the contiguous subarray within an array (containing at least one number) which has the largest product. - - For example, given the array [2,3,-2,4], - the contiguous subarray [2,3] has the largest product = 6. + * Find the contiguous subarray within an array (containing at least one number) which has the largest product. + *

+ * For example, given the array [2,3,-2,4], + * the contiguous subarray [2,3] has the largest product = 6. */ -public class MaximumProductSubarray -{ +public class MaximumProductSubarray { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] A = {2,3,-2,4}; + public static void main(String[] args) throws Exception { + int[] A = {2, 3, -2, 4}; System.out.println(new MaximumProductSubarray().maxProduct(A)); } - public int maxProduct(int[] nums) - { - if(nums.length == 1) return nums[0]; + public int maxProduct(int[] nums) { + if (nums.length == 1) return nums[0]; int min = nums[0]; int max = nums[0]; int result = max; - for(int i = 1; i < nums.length; i ++) - { + for (int i = 1; i < nums.length; i++) { int prevMin = min, prevMax = max; min = Math.min(nums[i], Math.min(nums[i] * prevMin, nums[i] * prevMax)); max = Math.max(nums[i], Math.max(nums[i] * prevMin, nums[i] * prevMax)); diff --git a/problems/src/dynamic_programming/MaximumSubarray.java b/problems/src/dynamic_programming/MaximumSubarray.java index ec3fdc97..2a122c31 100644 --- a/problems/src/dynamic_programming/MaximumSubarray.java +++ b/problems/src/dynamic_programming/MaximumSubarray.java @@ -3,21 +3,21 @@ /** * Created by gouthamvidyapradhan on 07/07/2017. * Find the contiguous subarray within an array (containing at least one number) which has the largest sum. - - For example, given the array [-2,1,-3,4,-1,2,1,-5,4], - the contiguous subarray [4,-1,2,1] has the largest sum = 6. + *

+ * For example, given the array [-2,1,-3,4,-1,2,1,-5,4], + * the contiguous subarray [4,-1,2,1] has the largest sum = 6. */ public class MaximumSubarray { - public static void main(String[] args) throws Exception{ - int[] nums = {-2,1,-3,4,-1,2,1,-5,4}; + public static void main(String[] args) throws Exception { + int[] nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; System.out.println(new MaximumSubarray().maxSubArray(nums)); } public int maxSubArray(int[] nums) { - if(nums.length == 1) return nums[0]; + if (nums.length == 1) return nums[0]; int max = nums[nums.length - 1]; - for(int i = nums.length - 2; i >= 0; i --){ - nums[i] = Math.max(nums[i], nums[i] + nums[i + 1]); + for (int i = nums.length - 2; i >= 0; i--) { + nums[i] = Math.max(nums[i], nums[i] + nums[i + 1]); max = Math.max(max, nums[i]); } return max; diff --git a/problems/src/dynamic_programming/PalindromePartitioningII.java b/problems/src/dynamic_programming/PalindromePartitioningII.java index 83705149..a72f8e26 100644 --- a/problems/src/dynamic_programming/PalindromePartitioningII.java +++ b/problems/src/dynamic_programming/PalindromePartitioningII.java @@ -4,29 +4,28 @@ /** * Created by pradhang on 4/3/2017. - Given a string s, partition s such that every substring of the partition is a palindrome. - - Return the minimum cuts needed for a palindrome partitioning of s. - - For example, given s = "aab", - Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. + * Given a string s, partition s such that every substring of the partition is a palindrome. + *

+ * Return the minimum cuts needed for a palindrome partitioning of s. + *

+ * For example, given s = "aab", + * Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. */ -public class PalindromePartitioningII -{ +public class PalindromePartitioningII { private int A[]; private boolean[][] paliandrome; + /** * Main method + * * @param args */ - public static void main(String[] args) - { + public static void main(String[] args) { System.out.println(new PalindromePartitioningII().minCut("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); } - public int minCut(String s) - { - if(s == null || s.isEmpty()) return 0; + public int minCut(String s) { + if (s == null || s.isEmpty()) return 0; A = new int[s.length()]; Arrays.fill(A, Integer.MAX_VALUE); char[] charArr = s.toCharArray(); @@ -34,22 +33,16 @@ public int minCut(String s) return doNext(charArr, 0) - 1; } - private int doNext(char[] s, int p) - { - if(p >= s.length) return 0; - if(A[p] < Integer.MAX_VALUE) return A[p]; - for(int i = p, l = s.length; i < l; i ++ ) - { - if(p + 1 <= i - 1) - { - paliandrome[p][i] = (paliandrome[p+1][i-1] && (s[p] == s[i])); - } - else - { + private int doNext(char[] s, int p) { + if (p >= s.length) return 0; + if (A[p] < Integer.MAX_VALUE) return A[p]; + for (int i = p, l = s.length; i < l; i++) { + if (p + 1 <= i - 1) { + paliandrome[p][i] = (paliandrome[p + 1][i - 1] && (s[p] == s[i])); + } else { paliandrome[p][i] = (i == p) || (s[i] == s[p]); } - if(paliandrome[p][i]) - { + if (paliandrome[p][i]) { A[p] = Math.min(doNext(s, i + 1) + 1, A[p]); } } diff --git a/problems/src/dynamic_programming/TwoKeysKeyboard.java b/problems/src/dynamic_programming/TwoKeysKeyboard.java index 8c1f1b25..0bd11db5 100644 --- a/problems/src/dynamic_programming/TwoKeysKeyboard.java +++ b/problems/src/dynamic_programming/TwoKeysKeyboard.java @@ -3,39 +3,40 @@ /** * Created by gouthamvidyapradhan on 19/08/2017. * Initially on a notepad only one character 'A' is present. You can perform two operations on this notepad for each step: - - Copy All: You can copy all the characters present on the notepad (partial copy is not allowed). - Paste: You can paste the characters which are copied last time. - Given a number n. You have to get exactly n 'A' on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n 'A'. - - Example 1: - Input: 3 - Output: 3 - Explanation: - Intitally, we have one character 'A'. - In step 1, we use Copy All operation. - In step 2, we use Paste operation to get 'AA'. - In step 3, we use Paste operation to get 'AAA'. - - Note: - The n will be in the range [1, 1000]. + *

+ * Copy All: You can copy all the characters present on the notepad (partial copy is not allowed). + * Paste: You can paste the characters which are copied last time. + * Given a number n. You have to get exactly n 'A' on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n 'A'. + *

+ * Example 1: + * Input: 3 + * Output: 3 + * Explanation: + * Intitally, we have one character 'A'. + * In step 1, we use Copy All operation. + * In step 2, we use Paste operation to get 'AA'. + * In step 3, we use Paste operation to get 'AAA'. + *

+ * Note: + * The n will be in the range [1, 1000]. */ public class TwoKeysKeyboard { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new TwoKeysKeyboard().minSteps(8)); } public int minSteps(int n) { int[] DP = new int[n + 1]; - for(int i = 2; i <= n; i++){ + for (int i = 2; i <= n; i++) { DP[i] = i; - for(int j = 2; j < i; j++){ - if((i % j) == 0){ + for (int j = 2; j < i; j++) { + if ((i % j) == 0) { DP[i] = Math.min(DP[i], DP[j] + (i / j)); } } diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTrees.java b/problems/src/dynamic_programming/UniqueBinarySearchTrees.java index 922e7296..708c9a1f 100644 --- a/problems/src/dynamic_programming/UniqueBinarySearchTrees.java +++ b/problems/src/dynamic_programming/UniqueBinarySearchTrees.java @@ -2,42 +2,38 @@ /** * Created by gouthamvidyapradhan on 31/03/2017. - Given n, how many structurally unique BST's (binary search trees) that store values 1...n? - - For example, - Given n = 3, there are a total of 5 unique BST's. - - 1 3 3 2 1 - \ / / / \ \ - 3 2 1 1 3 2 - / / \ \ - 2 1 2 3 - + * Given n, how many structurally unique BST's (binary search trees) that store values 1...n? + *

+ * For example, + * Given n = 3, there are a total of 5 unique BST's. + *

+ * 1 3 3 2 1 + * \ / / / \ \ + * 3 2 1 1 3 2 + * / / \ \ + * 2 1 2 3 */ -public class UniqueBinarySearchTrees -{ +public class UniqueBinarySearchTrees { int[] dp; + /** * Main method + * * @param args */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new UniqueBinarySearchTrees().numTrees(5)); } - public int numTrees(int n) - { + public int numTrees(int n) { dp = new int[n + 1]; dp[0] = 1; return dp(n); } - private int dp(int n) - { - if(dp[n] != 0) return dp[n]; - for(int i = 1; i <= n; i ++) - { + private int dp(int n) { + if (dp[n] != 0) return dp[n]; + for (int i = 1; i <= n; i++) { dp[n] += dp(n - i) * dp(n - (n - i) - 1); } return dp[n]; diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java b/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java index e55c19fa..5fd0bc56 100644 --- a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java +++ b/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java @@ -5,98 +5,83 @@ /** * Created by gouthamvidyapradhan on 31/03/2017. - Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n. - - For example, - Given n = 3, your program should return all 5 unique BST's shown below. - - 1 3 3 2 1 - \ / / / \ \ - 3 2 1 1 3 2 - / / \ \ - 2 1 2 3 - + * Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n. + *

+ * For example, + * Given n = 3, your program should return all 5 unique BST's shown below. + *

+ * 1 3 3 2 1 + * \ / / / \ \ + * 3 2 1 1 3 2 + * / / \ \ + * 2 1 2 3 */ -public class UniqueBinarySearchTreesII -{ - public static class TreeNode - { +public class UniqueBinarySearchTreesII { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private List[][] dp; /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List list = new UniqueBinarySearchTreesII().generateTrees(3); } - public List generateTrees(int n) - { - if(n == 0) return new ArrayList<>(); + public List generateTrees(int n) { + if (n == 0) return new ArrayList<>(); dp = new List[n + 1][n + 1]; dp[0][0] = new ArrayList<>(); - for(int i = 1, j = 1; i <= n; i ++, j ++) - { + for (int i = 1, j = 1; i <= n; i++, j++) { dp[i][j] = new ArrayList<>(); dp[i][j].add(new TreeNode(i)); } return dp(1, n, n); } - private List dp(int s, int e, int n) - { - if(e < s) return null; - if(dp[s][e] != null) return dp[s][e]; + private List dp(int s, int e, int n) { + if (e < s) return null; + if (dp[s][e] != null) return dp[s][e]; List result = new ArrayList<>(); - for(int i = s; i <= e; i ++) - { + for (int i = s; i <= e; i++) { List left = dp(s, i - 1, n); List right = dp(i + 1, e, n); List temp = new ArrayList<>(); - if(left != null) - { - for(TreeNode node : left) - { + if (left != null) { + for (TreeNode node : left) { TreeNode root = new TreeNode(i); root.left = node; temp.add(root); } } - if(right != null) - { - if(!temp.isEmpty()) - { - for(TreeNode root : temp) - { - for(TreeNode node : right) - { + if (right != null) { + if (!temp.isEmpty()) { + for (TreeNode root : temp) { + for (TreeNode node : right) { TreeNode newRoot = clone(root); newRoot.right = node; result.add(newRoot); } } - } - else - { - for(TreeNode node : right) - { + } else { + for (TreeNode node : right) { TreeNode root = new TreeNode(i); root.right = node; result.add(root); } } - } - else if(!temp.isEmpty()) - { + } else if (!temp.isEmpty()) { result.addAll(temp); } } @@ -106,12 +91,12 @@ else if(!temp.isEmpty()) /** * Clone treeNode + * * @param root rootnode * @return cloned root */ - private TreeNode clone(TreeNode root) - { - if(root == null) return null; + private TreeNode clone(TreeNode root) { + if (root == null) return null; TreeNode newNode = new TreeNode(root.val); newNode.left = clone(root.left); newNode.right = clone(root.right); diff --git a/problems/src/dynamic_programming/WordBreak.java b/problems/src/dynamic_programming/WordBreak.java index 70968715..bc7ca55b 100644 --- a/problems/src/dynamic_programming/WordBreak.java +++ b/problems/src/dynamic_programming/WordBreak.java @@ -4,60 +4,53 @@ /** * Created by gouthamvidyapradhan on 16/03/2017. - Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words. - - For example, given - s = "leetcode", - dict = ["leet", "code"]. - - Return true because "leetcode" can be segmented as "leet code". + * Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words. + *

+ * For example, given + * s = "leetcode", + * dict = ["leet", "code"]. + *

+ * Return true because "leetcode" can be segmented as "leet code". */ -public class WordBreak -{ +public class WordBreak { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List dic = new ArrayList<>(); - String[] arr = {"a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"}; + String[] arr = {"a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa", "aaaaaaa", "aaaaaaaa", "aaaaaaaaa", "aaaaaaaaaa"}; for (String s : arr) dic.add(s); System.out.println(new WordBreak().wordBreak("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", dic)); } - public boolean wordBreak(String s, List wordDict) - { + public boolean wordBreak(String s, List wordDict) { Set dictionary = new HashSet<>(); dictionary.addAll(wordDict); Map dic = new HashMap<>(); - for(int i = s.length() - 1; i >= 0; i --) + for (int i = s.length() - 1; i >= 0; i--) dp(i, s, dic, dictionary); return dic.get(0); } - private boolean dp(int i, String s, Map dic, Set dictionary) - { - if(i == s.length()) return true; - else if(dic.containsKey(i)) return dic.get(i); - else - { - for(int j = i, l = s.length(); j < l; j++) - { + private boolean dp(int i, String s, Map dic, Set dictionary) { + if (i == s.length()) return true; + else if (dic.containsKey(i)) return dic.get(i); + else { + for (int j = i, l = s.length(); j < l; j++) { String subStr = s.substring(i, j + 1); - if(dictionary.contains(subStr)) - { - if(dp(j + 1, s, dic, dictionary)) - { + if (dictionary.contains(subStr)) { + if (dp(j + 1, s, dic, dictionary)) { dic.put(i, true); break; } } } } - if(!dic.containsKey(i)) + if (!dic.containsKey(i)) dic.put(i, false); return dic.get(i); } diff --git a/problems/src/dynamic_programming/WordBreakII.java b/problems/src/dynamic_programming/WordBreakII.java index 6c99493d..7265dcb1 100644 --- a/problems/src/dynamic_programming/WordBreakII.java +++ b/problems/src/dynamic_programming/WordBreakII.java @@ -4,26 +4,26 @@ /** * Created by gouthamvidyapradhan on 07/04/2017. - Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. You may assume the dictionary does not contain duplicate words. - - Return all such possible sentences. - - For example, given - s = "catsanddog", - dict = ["cat", "cats", "and", "sand", "dog"]. - - A solution is ["cats and dog", "cat sand dog"]. + * Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. You may assume the dictionary does not contain duplicate words. + *

+ * Return all such possible sentences. + *

+ * For example, given + * s = "catsanddog", + * dict = ["cat", "cats", "and", "sand", "dog"]. + *

+ * A solution is ["cats and dog", "cat sand dog"]. */ -public class WordBreakII -{ +public class WordBreakII { private Map> map; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List wordList = new ArrayList<>(); wordList.add("cat"); wordList.add("cats"); @@ -33,34 +33,27 @@ public static void main(String[] args) throws Exception System.out.println(new WordBreakII().wordBreak("catsanddog", wordList)); } - public List wordBreak(String s, List wordDict) - { - if(s == null) return new ArrayList<>(); + public List wordBreak(String s, List wordDict) { + if (s == null) return new ArrayList<>(); map = new HashMap<>(); Set dictionary = new HashSet<>(); dictionary.addAll(wordDict); return dp(0, s, s.length(), dictionary); } - private List dp(int p, String s, int l, Set dictionary) - { + private List dp(int p, String s, int l, Set dictionary) { List result = new ArrayList<>(); - if(p >= s.length()) - { + if (p >= s.length()) { result.add(""); return result; - } - else if(map.containsKey(p)) - { + } else if (map.containsKey(p)) { return map.get(p); } - for(int i = p; i < l; i ++) - { + for (int i = p; i < l; i++) { String subStr = s.substring(p, i + 1); - if(dictionary.contains(subStr)) - { + if (dictionary.contains(subStr)) { List subList = dp(i + 1, s, l, dictionary); - for(String se : subList) + for (String se : subList) result.add((subStr + " " + se).trim()); } } diff --git a/problems/src/greedy/BurstBalloons.java b/problems/src/greedy/BurstBalloons.java index 1fe8e8ea..c9501aab 100644 --- a/problems/src/greedy/BurstBalloons.java +++ b/problems/src/greedy/BurstBalloons.java @@ -1,45 +1,45 @@ package greedy; -import java.util.ArrayDeque; import java.util.Arrays; /** * Created by gouthamvidyapradhan on 28/06/2017. - * + *

* There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided input is the start and end coordinates of the horizontal diameter. Since it's horizontal, y-coordinates don't matter and hence the x-coordinates of start and end of the diameter suffice. Start is always smaller than end. There will be at most 104 balloons. - - An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons. - - Example: - - Input: - [[10,16], [2,8], [1,6], [7,12]] - - Output: - 2 - - Explanation: - One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x + *

+ * An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons. + *

+ * Example: + *

+ * Input: + * [[10,16], [2,8], [1,6], [7,12]] + *

+ * Output: + * 2 + *

+ * Explanation: + * One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x */ public class BurstBalloons { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ - int[][] baloons = {{10,16}, {2,8}, {1,6}, {7,12}}; + public static void main(String[] args) throws Exception { + int[][] baloons = {{10, 16}, {2, 8}, {1, 6}, {7, 12}}; System.out.println(new BurstBalloons().findMinArrowShots(baloons)); } public int findMinArrowShots(int[][] points) { - if(points.length == 0) return 0; + if (points.length == 0) return 0; Arrays.sort(points, ((o1, o2) -> o1[1] - o2[1])); int count = 0; int leftMost = points[0][1]; - for(int i = 1; i < points.length; i ++){ - if(leftMost < points[i][0]){ - count ++; + for (int i = 1; i < points.length; i++) { + if (leftMost < points[i][0]) { + count++; leftMost = points[i][1]; } } diff --git a/problems/src/greedy/CourseScheduleIII.java b/problems/src/greedy/CourseScheduleIII.java index 16469658..b370de3f 100644 --- a/problems/src/greedy/CourseScheduleIII.java +++ b/problems/src/greedy/CourseScheduleIII.java @@ -6,25 +6,25 @@ /** * Created by gouthamvidyapradhan on 27/06/2017. - * + *

* There are n different online courses numbered from 1 to n. Each course has some duration(course length) t and closed on dth day. A course should be taken continuously for t days and must be finished before or on the dth day. You will start at the 1st day. - - Given n online courses represented by pairs (t,d), your task is to find the maximal number of courses that can be taken. - - Example: - Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]] - Output: 3 - Explanation: - There're totally 4 courses, but you can take 3 courses at most: - First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day. - Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day. - Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. - The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date. - - Note: - The integer 1 <= d, t, n <= 10,000. - You can't take two courses simultaneously. - + *

+ * Given n online courses represented by pairs (t,d), your task is to find the maximal number of courses that can be taken. + *

+ * Example: + * Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]] + * Output: 3 + * Explanation: + * There're totally 4 courses, but you can take 3 courses at most: + * First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day. + * Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day. + * Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. + * The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date. + *

+ * Note: + * The integer 1 <= d, t, n <= 10,000. + * You can't take two courses simultaneously. + *

* Solution: O(N log N) * 1. Sort the courses with earliest deadline time (Greedy sort) * 2. Maintain a max-heap of course duration. @@ -34,7 +34,7 @@ Given n online courses represented by pairs (t,d), your task is to find the maxi * inorder to accommodate the new course. */ public class CourseScheduleIII { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[][] course = {{5, 5}, {2, 6}, {4, 6}}; System.out.println(new CourseScheduleIII().scheduleCourse(course)); } @@ -43,10 +43,10 @@ public int scheduleCourse(int[][] courses) { Arrays.sort(courses, (a, b) -> a[1] - b[1]); Queue pq = new PriorityQueue<>((a, b) -> b - a); int time = 0; - for(int[] course : courses){ + for (int[] course : courses) { time += course[0]; pq.add(course[0]); - if(time > course[1]) + if (time > course[1]) time -= pq.poll(); } return pq.size(); diff --git a/problems/src/greedy/GasStation.java b/problems/src/greedy/GasStation.java index b6f38879..7afa0f51 100644 --- a/problems/src/greedy/GasStation.java +++ b/problems/src/greedy/GasStation.java @@ -3,36 +3,36 @@ /** * Created by gouthamvidyapradhan on 28/06/2017. * There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. - - You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. - - Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. - - Note: - The solution is guaranteed to be unique. - - Solution: O(N) - If point B cant be reached from point A then all the intermediate points between A and B cant be the starting - point. Therefore reset the starting point to the new starting point. - + *

+ * You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. + *

+ * Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. + *

+ * Note: + * The solution is guaranteed to be unique. + *

+ * Solution: O(N) + * If point B cant be reached from point A then all the intermediate points between A and B cant be the starting + * point. Therefore reset the starting point to the new starting point. */ public class GasStation { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ - int[] gas = {10, 20, 30, 10}; + public static void main(String[] args) throws Exception { + int[] gas = {10, 20, 30, 10}; int[] cost = {5, 30, 10, 10}; System.out.println(new GasStation().canCompleteCircuit(gas, cost)); } public int canCompleteCircuit(int[] gas, int[] cost) { int debt = 0, sum = 0, start = 0; - for(int i = 0; i < gas.length; i ++){ + for (int i = 0; i < gas.length; i++) { sum += gas[i] - cost[i]; - if(sum < 0){ + if (sum < 0) { debt += sum; sum = 0; start = i + 1; diff --git a/problems/src/greedy/JumpGame.java b/problems/src/greedy/JumpGame.java index 91b43b0f..3c7ea2fa 100644 --- a/problems/src/greedy/JumpGame.java +++ b/problems/src/greedy/JumpGame.java @@ -2,37 +2,34 @@ /** * Created by gouthamvidyapradhan on 17/03/2017. - Given an array of non-negative integers, you are initially positioned at the first index of the array. - - Each element in the array represents your maximum jump length at that position. - - Determine if you are able to reach the last index. - - For example: - A = [2,3,1,1,4], return true. - - A = [3,2,1,0,4], return false. + * Given an array of non-negative integers, you are initially positioned at the first index of the array. + *

+ * Each element in the array represents your maximum jump length at that position. + *

+ * Determine if you are able to reach the last index. + *

+ * For example: + * A = [2,3,1,1,4], return true. + *

+ * A = [3,2,1,0,4], return false. */ -public class JumpGame -{ +public class JumpGame { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] nums = {1,2,1,0,4}; + public static void main(String[] args) throws Exception { + int[] nums = {1, 2, 1, 0, 4}; System.out.println(new JumpGame().canJump(nums)); } - public boolean canJump(int[] nums) - { - if(nums.length == 0) return false; + public boolean canJump(int[] nums) { + if (nums.length == 0) return false; int min = nums.length - 1, max = nums.length - 1; - for(int i = nums.length - 2; i >= 0; i --) - { - if((nums[i] + i) >= min) + for (int i = nums.length - 2; i >= 0; i--) { + if ((nums[i] + i) >= min) min = i; } return (min == 0); diff --git a/problems/src/greedy/JumpGameII.java b/problems/src/greedy/JumpGameII.java index 7e45e13d..051ab50e 100644 --- a/problems/src/greedy/JumpGameII.java +++ b/problems/src/greedy/JumpGameII.java @@ -2,41 +2,37 @@ /** * Created by gouthamvidyapradhan on 02/04/2017. - Given an array of non-negative integers, you are initially positioned at the first index of the array. - - Each element in the array represents your maximum jump length at that position. - - Your goal is to reach the last index in the minimum number of jumps. - - For example: - Given array A = [2,3,1,1,4] - - 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.) - - Note: - You can assume that you can always reach the last index. + * Given an array of non-negative integers, you are initially positioned at the first index of the array. + *

+ * Each element in the array represents your maximum jump length at that position. + *

+ * Your goal is to reach the last index in the minimum number of jumps. + *

+ * For example: + * Given array A = [2,3,1,1,4] + *

+ * 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.) + *

+ * Note: + * You can assume that you can always reach the last index. */ -public class JumpGameII -{ +public class JumpGameII { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - public int jump(int[] nums) - { + public int jump(int[] nums) { int step = 0; int e = 0, max = 0; - for(int i = 0; i < nums.length - 1; i++) - { + for (int i = 0; i < nums.length - 1; i++) { max = Math.max(max, i + nums[i]); - if(i == e) - { + if (i == e) { step++; e = max; } diff --git a/problems/src/greedy/NonOverlappingIntervals.java b/problems/src/greedy/NonOverlappingIntervals.java index 0f0bbaf4..2ec7bcce 100644 --- a/problems/src/greedy/NonOverlappingIntervals.java +++ b/problems/src/greedy/NonOverlappingIntervals.java @@ -1,50 +1,57 @@ package greedy; -import array.MergeIntervals; - import java.util.Arrays; /** * Created by gouthamvidyapradhan on 28/06/2017. * Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping. - - Note: - You may assume the interval's end point is always bigger than its start point. - Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. - Example 1: - Input: [ [1,2], [2,3], [3,4], [1,3] ] - - Output: 1 - - Explanation: [1,3] can be removed and the rest of intervals are non-overlapping. - Example 2: - Input: [ [1,2], [1,2], [1,2] ] - - Output: 2 - - Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. - Example 3: - Input: [ [1,2], [2,3] ] - - Output: 0 - - Explanation: You don't need to remove any of the intervals since they're already non-overlapping. + *

+ * Note: + * You may assume the interval's end point is always bigger than its start point. + * Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. + * Example 1: + * Input: [ [1,2], [2,3], [3,4], [1,3] ] + *

+ * Output: 1 + *

+ * Explanation: [1,3] can be removed and the rest of intervals are non-overlapping. + * Example 2: + * Input: [ [1,2], [1,2], [1,2] ] + *

+ * Output: 2 + *

+ * Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. + * Example 3: + * Input: [ [1,2], [2,3] ] + *

+ * Output: 0 + *

+ * Explanation: You don't need to remove any of the intervals since they're already non-overlapping. */ public class NonOverlappingIntervals { public static class Interval { int start; int end; - Interval() { start = 0; end = 0; } - Interval(int s, int e) { start = s; end = e; } + + Interval() { + start = 0; + end = 0; + } + + Interval(int s, int e) { + start = s; + end = e; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { Interval i1 = new Interval(1, 4); Interval i2 = new Interval(5, 9); Interval i3 = new Interval(3, 12); @@ -54,15 +61,14 @@ public static void main(String[] args) throws Exception{ } public int eraseOverlapIntervals(Interval[] intervals) { - if(intervals.length == 0) return 0; + if (intervals.length == 0) return 0; Arrays.sort(intervals, ((o1, o2) -> o1.end - o2.end)); int count = 0; Interval prev = intervals[0]; - for(int i = 1; i < intervals.length; i ++){ - if(intervals[i].start < prev.end){ + for (int i = 1; i < intervals.length; i++) { + if (intervals[i].start < prev.end) { count++; - } - else{ + } else { prev = intervals[i]; } } diff --git a/problems/src/greedy/QueueReconstructionByHeight.java b/problems/src/greedy/QueueReconstructionByHeight.java index 4de71294..96269910 100644 --- a/problems/src/greedy/QueueReconstructionByHeight.java +++ b/problems/src/greedy/QueueReconstructionByHeight.java @@ -6,23 +6,23 @@ /** * Created by gouthamvidyapradhan on 29/06/2017. * Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue. - - Note: - The number of people is less than 1,100. - - Example - - Input: - [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] - - Output: - [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] + *

+ * Note: + * The number of people is less than 1,100. + *

+ * Example + *

+ * Input: + * [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] + *

+ * Output: + * [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] */ public class QueueReconstructionByHeight { - public static void main(String[] args) throws Exception{ - int[][] A = {{7,0}, {4,4}, {7,1}, {5,0}, {6,1}, {5,2}}; + public static void main(String[] args) throws Exception { + int[][] A = {{7, 0}, {4, 4}, {7, 1}, {5, 0}, {6, 1}, {5, 2}}; int[][] r = new QueueReconstructionByHeight().reconstructQueue(A); - for(int[] i : r){ + for (int[] i : r) { System.out.println(i[0] + " " + i[1]); } } @@ -30,10 +30,10 @@ public static void main(String[] args) throws Exception{ public int[][] reconstructQueue(int[][] people) { Arrays.sort(people, ((o1, o2) -> (o2[0] - o1[0] == 0) ? o1[1] - o2[1] : o2[0] - o1[0])); LinkedList list = new LinkedList<>(); - for(int[] p : people) + for (int[] p : people) list.add(p[1], p); int[][] result = new int[people.length][2]; - for(int i = 0, l = list.size(); i < l; i ++) + for (int i = 0, l = list.size(); i < l; i++) result[i] = list.get(i); return result; } diff --git a/problems/src/hashing/Anagrams.java b/problems/src/hashing/Anagrams.java index 10fc0bf1..a9a91aa1 100644 --- a/problems/src/hashing/Anagrams.java +++ b/problems/src/hashing/Anagrams.java @@ -6,84 +6,79 @@ /** * Created by gouthamvidyapradhan on 25/02/2017. - Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. - - Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100. - - The order of output does not matter. - - Example 1: - - Input: - s: "cbaebabacd" p: "abc" - - Output: - [0, 6] - - Explanation: - The substring with start index = 0 is "cba", which is an anagram of "abc". - The substring with start index = 6 is "bac", which is an anagram of "abc". - Example 2: - - Input: - s: "abab" p: "ab" - - Output: - [0, 1, 2] - - Explanation: - The substring with start index = 0 is "ab", which is an anagram of "ab". - The substring with start index = 1 is "ba", which is an anagram of "ab". - The substring with start index = 2 is "ab", which is an anagram of "ab". + * Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. + *

+ * Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100. + *

+ * The order of output does not matter. + *

+ * Example 1: + *

+ * Input: + * s: "cbaebabacd" p: "abc" + *

+ * Output: + * [0, 6] + *

+ * Explanation: + * The substring with start index = 0 is "cba", which is an anagram of "abc". + * The substring with start index = 6 is "bac", which is an anagram of "abc". + * Example 2: + *

+ * Input: + * s: "abab" p: "ab" + *

+ * Output: + * [0, 1, 2] + *

+ * Explanation: + * The substring with start index = 0 is "ab", which is an anagram of "ab". + * The substring with start index = 1 is "ba", which is an anagram of "ab". + * The substring with start index = 2 is "ab", which is an anagram of "ab". */ -public class Anagrams -{ +public class Anagrams { int[] TC = new int[256]; int[] PC = new int[256]; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { List result = new Anagrams().findAnagrams("abab", "ab"); result.forEach(System.out::print); } - public List findAnagrams(String s, String p) - { + public List findAnagrams(String s, String p) { List result = new ArrayList<>(); int pLen = p.length(); - if(pLen > s.length()) return result; + if (pLen > s.length()) return result; Arrays.fill(TC, 0); Arrays.fill(PC, 0); - for(int i = 0; i < pLen; i ++) - { + for (int i = 0; i < pLen; i++) { TC[s.charAt(i)]++; PC[p.charAt(i)]++; } int i = pLen; - for(int l = s.length(); i < l; i ++) - { - if(compare()) + for (int l = s.length(); i < l; i++) { + if (compare()) result.add(i - pLen); TC[s.charAt(i)]++; TC[s.charAt(i - pLen)]--; } - if(compare()) + if (compare()) result.add(i - pLen); return result; } - private boolean compare() - { - for(int i = 0; i < 256; i ++) - { - if(TC[i] != PC[i]) + private boolean compare() { + for (int i = 0; i < 256; i++) { + if (TC[i] != PC[i]) return false; } return true; diff --git a/problems/src/hashing/GroupAnagrams.java b/problems/src/hashing/GroupAnagrams.java index 4b62b9c3..06ba7b78 100644 --- a/problems/src/hashing/GroupAnagrams.java +++ b/problems/src/hashing/GroupAnagrams.java @@ -7,64 +7,60 @@ /** * Created by gouthamvidyapradhan on 10/03/2017. - Given an array of strings, group anagrams together. - - For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], - Return: - - [ - ["ate", "eat","tea"], - ["nat","tan"], - ["bat"] - ] - Note: All inputs will be in lower-case. + * Given an array of strings, group anagrams together. + *

+ * For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], + * Return: + *

+ * [ + * ["ate", "eat","tea"], + * ["nat","tan"], + * ["bat"] + * ] + * Note: All inputs will be in lower-case. */ -public class GroupAnagrams -{ +public class GroupAnagrams { private int[] A = new int[256]; private HashMap> hashMap = new HashMap<>(); private List> result = new ArrayList<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { String[] strs = {"huh", "tit"}; List> result = new GroupAnagrams().groupAnagrams(strs); - for (List l : result) - { - for(String s : l) + for (List l : result) { + for (String s : l) System.out.println(s); System.out.println("-----"); } } - public List> groupAnagrams(String[] strs) - { - for(int i = 0, l = strs.length; i < l; i ++) - { + public List> groupAnagrams(String[] strs) { + for (int i = 0, l = strs.length; i < l; i++) { Arrays.fill(A, 0); String s = strs[i]; - for(int j = 0, sl = s.length(); j < sl; j ++) + for (int j = 0, sl = s.length(); j < sl; j++) A[s.charAt(j)]++; StringBuilder sb = new StringBuilder(); - for(int k = 0; k < 256; k ++) - { - if(A[k] != 0) + for (int k = 0; k < 256; k++) { + if (A[k] != 0) sb.append(k).append("").append(A[k]); } List value = hashMap.get(sb.toString()); - if(value == null) + if (value == null) value = new ArrayList<>(); value.add(s); hashMap.put(sb.toString(), value); } - for(String s : hashMap.keySet()) + for (String s : hashMap.keySet()) result.add(hashMap.get(s)); return result; diff --git a/problems/src/hashing/KdiffPairsInanArray.java b/problems/src/hashing/KdiffPairsInanArray.java index 5d1b330d..4f9b2ca2 100644 --- a/problems/src/hashing/KdiffPairsInanArray.java +++ b/problems/src/hashing/KdiffPairsInanArray.java @@ -1,62 +1,57 @@ package hashing; -import java.util.*; +import java.util.HashMap; +import java.util.Map; /** * Created by gouthamvidyapradhan on 28/03/2017. - Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k. - - Example 1: - Input: [3, 1, 4, 1, 5], k = 2 - Output: 2 - Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5). - Although we have two 1s in the input, we should only return the number of unique pairs. - Example 2: - Input:[1, 2, 3, 4, 5], k = 1 - Output: 4 - Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5). - Example 3: - Input: [1, 3, 1, 5, 4], k = 0 - Output: 1 - Explanation: There is one 0-diff pair in the array, (1, 1). - Note: - The pairs (i, j) and (j, i) count as the same pair. - The length of the array won't exceed 10,000. - All the integers in the given input belong to the range: [-1e7, 1e7]. + * Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k. + *

+ * Example 1: + * Input: [3, 1, 4, 1, 5], k = 2 + * Output: 2 + * Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5). + * Although we have two 1s in the input, we should only return the number of unique pairs. + * Example 2: + * Input:[1, 2, 3, 4, 5], k = 1 + * Output: 4 + * Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5). + * Example 3: + * Input: [1, 3, 1, 5, 4], k = 0 + * Output: 1 + * Explanation: There is one 0-diff pair in the array, (1, 1). + * Note: + * The pairs (i, j) and (j, i) count as the same pair. + * The length of the array won't exceed 10,000. + * All the integers in the given input belong to the range: [-1e7, 1e7]. */ -public class KdiffPairsInanArray -{ +public class KdiffPairsInanArray { private Map map = new HashMap<>(); private int count = 0; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] nums = {1,2,3,4,5}; + public static void main(String[] args) throws Exception { + int[] nums = {1, 2, 3, 4, 5}; System.out.println(new KdiffPairsInanArray().findPairs(nums, -1)); } - public int findPairs(int[] nums, int k) - { - if(nums.length == 0 || k < 0) return 0; - for(int i : nums) - { + public int findPairs(int[] nums, int k) { + if (nums.length == 0 || k < 0) return 0; + for (int i : nums) { map.put(i, map.getOrDefault(i, 0) + 1); } - for(Map.Entry entry : map.entrySet()) - { - if(k == 0) - { - if(entry.getValue() > 1) - count ++; - } - else - { - if(map.containsKey(entry.getKey() + k)) - count ++; + for (Map.Entry entry : map.entrySet()) { + if (k == 0) { + if (entry.getValue() > 1) + count++; + } else { + if (map.containsKey(entry.getKey() + k)) + count++; } } return count; diff --git a/problems/src/hashing/SortCharByFrequency.java b/problems/src/hashing/SortCharByFrequency.java index cf4da160..eb9ce36a 100644 --- a/problems/src/hashing/SortCharByFrequency.java +++ b/problems/src/hashing/SortCharByFrequency.java @@ -1,79 +1,77 @@ package hashing; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Created by gouthamvidyapradhan on 25/03/2017. - Given a string, sort it in decreasing order based on the frequency of characters. - - Example 1: - - Input: - "tree" - - Output: - "eert" - - Explanation: - 'e' appears twice while 'r' and 't' both appear once. - So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer. - Example 2: - - Input: - "cccaaa" - - Output: - "cccaaa" - - Explanation: - Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer. - Note that "cacaca" is incorrect, as the same characters must be together. - - Example 3: - - Input: - "Aabb" - - Output: - "bbAa" - - Explanation: - "bbaA" is also a valid answer, but "Aabb" is incorrect. - Note that 'A' and 'a' are treated as two different characters. - + * Given a string, sort it in decreasing order based on the frequency of characters. + *

+ * Example 1: + *

+ * Input: + * "tree" + *

+ * Output: + * "eert" + *

+ * Explanation: + * 'e' appears twice while 'r' and 't' both appear once. + * So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer. + * Example 2: + *

+ * Input: + * "cccaaa" + *

+ * Output: + * "cccaaa" + *

+ * Explanation: + * Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer. + * Note that "cacaca" is incorrect, as the same characters must be together. + *

+ * Example 3: + *

+ * Input: + * "Aabb" + *

+ * Output: + * "bbAa" + *

+ * Explanation: + * "bbaA" is also a valid answer, but "Aabb" is incorrect. + * Note that 'A' and 'a' are treated as two different characters. */ -public class SortCharByFrequency -{ - class Freq - { +public class SortCharByFrequency { + class Freq { int i; int c; } private int[] buff = new int[256]; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new SortCharByFrequency().frequencySort("askdfkasdkfasdkljfklasdjfkl")); } - public String frequencySort(String s) - { - if(s == null || s.isEmpty()) return s; + public String frequencySort(String s) { + if (s == null || s.isEmpty()) return s; Arrays.fill(buff, 0); StringBuilder sb = new StringBuilder(); - for(int i = 0, l = s.length(); i < l; i ++) + for (int i = 0, l = s.length(); i < l; i++) buff[s.charAt(i)]++; List fList = new ArrayList<>(); - for(int i = 0; i < 256; i ++) - { - if(buff[i] > 0) - { + for (int i = 0; i < 256; i++) { + if (buff[i] > 0) { Freq f = new Freq(); f.i = i; f.c = buff[i]; @@ -83,11 +81,10 @@ public String frequencySort(String s) Collections.sort(fList, (o1, o2) -> Integer.compare(o2.c, o1.c)); - for(Freq f : fList) - { - char c = (char)f.i; + for (Freq f : fList) { + char c = (char) f.i; int freq = f.c; - while(freq-- > 0) + while (freq-- > 0) sb.append(c); } return sb.toString(); diff --git a/problems/src/hashing/TwoSum.java b/problems/src/hashing/TwoSum.java index 84ee1f30..9ddd8909 100644 --- a/problems/src/hashing/TwoSum.java +++ b/problems/src/hashing/TwoSum.java @@ -4,65 +4,49 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given an array of integers, return indices of the two numbers such that they add up to a specific target. - - You may assume that each input would have exactly one solution, and you may not use the same element twice. - - Example: - Given nums = [2, 7, 11, 15], target = 9, - - Because nums[0] + nums[1] = 2 + 7 = 9, - return [0, 1]. + * Given an array of integers, return indices of the two numbers such that they add up to a specific target. + *

+ * You may assume that each input would have exactly one solution, and you may not use the same element twice. + *

+ * Example: + * Given nums = [2, 7, 11, 15], target = 9, + *

+ * Because nums[0] + nums[1] = 2 + 7 = 9, + * return [0, 1]. */ -public class TwoSum -{ +public class TwoSum { HashMap map = new HashMap<>(); - public int[] twoSum(int[] nums, int target) - { + public int[] twoSum(int[] nums, int target) { int[] result = new int[2]; - for(int i : nums) - { - if(map.keySet().contains(i)) - { + for (int i : nums) { + if (map.keySet().contains(i)) { int count = map.get(i); map.put(i, ++count); - } - else - { + } else { map.put(i, 1); } } - for(int i = 0, l = nums.length; i < l; i ++) - { + for (int i = 0, l = nums.length; i < l; i++) { int ele = nums[i]; int req = target - ele; - if(map.keySet().contains(req)) - { + if (map.keySet().contains(req)) { result[0] = i; - if(ele == req) - { + if (ele == req) { int count = map.get(req); - if(count > 1) - { - for(int j = i + 1; j < l; j++) - { - if(nums[j] == req) - { + if (count > 1) { + for (int j = i + 1; j < l; j++) { + if (nums[j] == req) { result[1] = j; return result; } } } - } - else - { - for(int j = i + 1; j < l; j++) - { - if(nums[j] == req) - { + } else { + for (int j = i + 1; j < l; j++) { + if (nums[j] == req) { result[1] = j; return result; } diff --git a/problems/src/hashing/ValidAnagram.java b/problems/src/hashing/ValidAnagram.java index 3b01751f..da98099d 100644 --- a/problems/src/hashing/ValidAnagram.java +++ b/problems/src/hashing/ValidAnagram.java @@ -2,49 +2,45 @@ /** * Created by gouthamvidyapradhan on 10/03/2017. - Given two strings s and t, write a function to determine if t is an anagram of s. - - For example, - s = "anagram", t = "nagaram", return true. - s = "rat", t = "car", return false. - - Note: - You may assume the string contains only lowercase alphabets. - - Follow up: - What if the inputs contain unicode characters? How would you adapt your solution to such case? + * Given two strings s and t, write a function to determine if t is an anagram of s. + *

+ * For example, + * s = "anagram", t = "nagaram", return true. + * s = "rat", t = "car", return false. + *

+ * Note: + * You may assume the string contains only lowercase alphabets. + *

+ * Follow up: + * What if the inputs contain unicode characters? How would you adapt your solution to such case? */ -public class ValidAnagram -{ +public class ValidAnagram { private int[] S = new int[256]; private int[] T = new int[256]; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new ValidAnagram().isAnagram("anagram", "nagaram")); } - public boolean isAnagram(String s, String t) - { - if(s.length() != t.length()) return false; + public boolean isAnagram(String s, String t) { + if (s.length() != t.length()) return false; - for(int i = 0, l = s.length(); i < l; i ++) - { + for (int i = 0, l = s.length(); i < l; i++) { S[s.charAt(i)]++; } - for(int i = 0, l = t.length(); i < l; i ++) - { + for (int i = 0, l = t.length(); i < l; i++) { T[t.charAt(i)]++; } - for(int i = 0; i < 256; i ++) - { - if(S[i] != T[i]) return false; + for (int i = 0; i < 256; i++) { + if (S[i] != T[i]) return false; } return true; diff --git a/problems/src/heap/SlidingWindowMaximum.java b/problems/src/heap/SlidingWindowMaximum.java index f457524e..76682aa3 100644 --- a/problems/src/heap/SlidingWindowMaximum.java +++ b/problems/src/heap/SlidingWindowMaximum.java @@ -5,67 +5,61 @@ /** * Created by gouthamvidyapradhan on 10/03/2017. - Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. - - For example, - Given nums = [1,3,-1,-3,5,3,6,7], and k = 3. - - Window position Max - --------------- ----- - [1 3 -1] -3 5 3 6 7 3 - 1 [3 -1 -3] 5 3 6 7 3 - 1 3 [-1 -3 5] 3 6 7 5 - 1 3 -1 [-3 5 3] 6 7 5 - 1 3 -1 -3 [5 3 6] 7 6 - 1 3 -1 -3 5 [3 6 7] 7 - Therefore, return the max sliding window as [3,3,5,5,6,7]. - - Note: - You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array. + * Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. + *

+ * For example, + * Given nums = [1,3,-1,-3,5,3,6,7], and k = 3. + *

+ * Window position Max + * --------------- ----- + * [1 3 -1] -3 5 3 6 7 3 + * 1 [3 -1 -3] 5 3 6 7 3 + * 1 3 [-1 -3 5] 3 6 7 5 + * 1 3 -1 [-3 5 3] 6 7 5 + * 1 3 -1 -3 [5 3 6] 7 6 + * 1 3 -1 -3 5 [3 6 7] 7 + * Therefore, return the max sliding window as [3,3,5,5,6,7]. + *

+ * Note: + * You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array. */ -public class SlidingWindowMaximum -{ +public class SlidingWindowMaximum { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] a = {1, 3, 1, 2, 0, 5}; int[] result = new SlidingWindowMaximum().maxSlidingWindow(a, 3); - for(int i : result) + for (int i : result) System.out.print(i + " "); } /** - * * @param nums * @param k * @return */ - public int[] maxSlidingWindow(int[] nums, int k) - { + public int[] maxSlidingWindow(int[] nums, int k) { int[] result = new int[nums.length - (k - 1)]; - if(nums.length == 0) return new int[0]; + if (nums.length == 0) return new int[0]; Deque queue = new ArrayDeque<>(); - for(int i = 0, j = 0, l = nums.length; i < l; i ++) - { + for (int i = 0, j = 0, l = nums.length; i < l; i++) { int head = i - (k - 1); - if(head >= 0) - { + if (head >= 0) { //remove out of range - if(queue.peek() != null && queue.peek() < head) + if (queue.peek() != null && queue.peek() < head) queue.poll(); } - while(queue.peekLast() != null && nums[queue.peekLast()] <= nums[i]) - { + while (queue.peekLast() != null && nums[queue.peekLast()] <= nums[i]) { queue.pollLast(); } queue.offer(i); - if(i >= k - 1) + if (i >= k - 1) result[j++] = nums[queue.peek()]; } diff --git a/problems/src/heap/TheSkylineProblem.java b/problems/src/heap/TheSkylineProblem.java index 2b323ced..90bc186b 100644 --- a/problems/src/heap/TheSkylineProblem.java +++ b/problems/src/heap/TheSkylineProblem.java @@ -8,12 +8,12 @@ * A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. * Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), * write a program to output the skyline formed by these buildings collectively (Figure B). - * + *

*

* See below link for image. * https://leetcode.com/problems/the-skyline-problem/description/ *

- * + *

* Buildings Skyline Contour * The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0. *

@@ -29,10 +29,32 @@ * The input list is already sorted in ascending order by the left x position Li. * The output list must be sorted by the x position. * There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], [12 7], ...] - * + *

+ * Solution: + * 1. Sort array of points. Each point here is either a start of a rectangle or end of a rectangle. + * 2. Maintain a priority queue of rectangles ordered by increasing order of height, if height of two rectangle is same then, + * order by left most start index. + * 3. For each point starting from left-most point: + * 3.a. Add all the rectangles which starts at this point. + * 3.b. Remove all the rectangles which ends at this point. Keep a max of height for each rectangle removed. + * 3.c. If the current priority queue is empty then, include current point (x, 0) to the result set. This indicates this was the last rectangle and after this + * there is a gap of at least 1 unit. + *

+ * If the max calculated in step b is greater than current max then, include current x and max height from priority queue to the result set. + * This indicates one of the larger rectangle's right edge intersects with a smaller one. + *

+ * If the max calculated in stop b is smaller then check if the peek element in priority queue has the left edge value equal to current point. If so, + * then this indicates that a new larger rectangle starts from this point therefore add this point to the result set. + * 4. Return the result set */ public class TheSkylineProblem { + /** + * Main method + * + * @param args + * @throws Exception + */ public static void main(String[] args) throws Exception { int[][] A = {{0, 30, 30}, {2, 9, 10}, {3, 7, 15}, {4, 8, 10}, {5, 12, 12}, {15, 20, 10}, {19, 24, 8}}; //int[][] A = {{2,9,10}, {3,9,11}, {4,9,12}, {5,9,13}}; @@ -41,7 +63,9 @@ public static void main(String[] args) throws Exception { } public List getSkyline(int[][] buildings) { - PriorityQueue pq = new PriorityQueue<>(Comparator.comparing(Rectangle::getH).reversed().thenComparing(Rectangle::getX1)); + PriorityQueue pq = new PriorityQueue<>(Comparator.comparing(Rectangle::getH) + .reversed() + .thenComparing(Rectangle::getX1)); //order by height, if height is same then, order by left most starting edge. List result = new ArrayList<>(); Set set = new HashSet<>(); for (int[] p : buildings) { @@ -54,7 +78,8 @@ public List getSkyline(int[][] buildings) { for (int i = 0, j = 0, l = points.size(); i < l; i++) { int curr = points.get(i); - for (int k = j; k < buildings.length; k++) { + + for (int k = j; k < buildings.length; k++) { //add all the rectangles that begin at this point int[] rectangle = buildings[k]; if (rectangle[0] == curr) { pq.offer(new Rectangle(rectangle[0], rectangle[1], rectangle[2])); @@ -64,7 +89,7 @@ public List getSkyline(int[][] buildings) { } } int max = Integer.MIN_VALUE; - while (!pq.isEmpty()) { + while (!pq.isEmpty()) { // remove all the rectangles that end at this point if (pq.peek().getX2() == curr) { Rectangle top = pq.poll(); max = Math.max(max, top.getH()); @@ -75,14 +100,12 @@ public List getSkyline(int[][] buildings) { } } if (pq.isEmpty()) { - result.add(makeNewPoint(curr, 0)); + result.add(makeNewPoint(curr, 0)); //This is the last rectangle after this there is a gap of at least one unit } else { if (max > pq.peek().getH()) { - result.add(makeNewPoint(curr, pq.peek().getH())); - } else if (max < pq.peek().getH()) { - if (pq.peek().getX1() == curr) { - result.add(makeNewPoint(curr, pq.peek().getH())); - } + result.add(makeNewPoint(curr, pq.peek().getH())); //one of the larger rectangle's right edge intersects with a smaller one + } else if (max < pq.peek().getH() && pq.peek().getX1() == curr) { + result.add(makeNewPoint(curr, pq.peek().getH())); //new larger rectangle begins at this point } } } diff --git a/problems/src/linked_list/DeleteNode.java b/problems/src/linked_list/DeleteNode.java index 50a5172a..b22be8cc 100644 --- a/problems/src/linked_list/DeleteNode.java +++ b/problems/src/linked_list/DeleteNode.java @@ -3,15 +3,17 @@ /** * Created by gouthamvidyapradhan on 04/07/2017. * Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. - - Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. - + *

+ * Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. */ public class DeleteNode { public static class ListNode { int val; ListNode next; - ListNode(int x) { val = x; } + + ListNode(int x) { + val = x; + } } public static void main(String[] args) { @@ -20,7 +22,7 @@ public static void main(String[] args) { node.next.next = new ListNode(3); node.next.next.next = new ListNode(4); new DeleteNode().deleteNode(node.next.next); - while (node != null){ + while (node != null) { System.out.println(node.val); node = node.next; } @@ -30,7 +32,7 @@ public void deleteNode(ListNode node) { ListNode prev = node; ListNode last = node; ListNode next = node.next; - while(next != null){ + while (next != null) { last = prev; int temp = prev.val; prev.val = next.val; diff --git a/problems/src/linked_list/IntersectionOfTwoLists.java b/problems/src/linked_list/IntersectionOfTwoLists.java index 19cfbab6..5e9ae0c2 100644 --- a/problems/src/linked_list/IntersectionOfTwoLists.java +++ b/problems/src/linked_list/IntersectionOfTwoLists.java @@ -2,36 +2,33 @@ /** * Created by gouthamvidyapradhan on 24/02/2017. - Write a program to find the node at which the intersection of two singly linked lists begins. - - - For example, the following two linked lists: - - A: a1 → a2 - ↘ - c1 → c2 → c3 - ↗ - B: b1 → b2 → b3 - begin to intersect at node c1. - - - Notes: - - If the two linked lists have no intersection at all, return null. - The linked lists must retain their original structure after the function returns. - You may assume there are no cycles anywhere in the entire linked structure. - Your code should preferably run in O(n) time and use only O(1) memory. - + * Write a program to find the node at which the intersection of two singly linked lists begins. + *

+ *

+ * For example, the following two linked lists: + *

+ * A: a1 → a2 + * ↘ + * c1 → c2 → c3 + * ↗ + * B: b1 → b2 → b3 + * begin to intersect at node c1. + *

+ *

+ * Notes: + *

+ * If the two linked lists have no intersection at all, return null. + * The linked lists must retain their original structure after the function returns. + * You may assume there are no cycles anywhere in the entire linked structure. + * Your code should preferably run in O(n) time and use only O(1) memory. */ -public class IntersectionOfTwoLists -{ +public class IntersectionOfTwoLists { - public static class ListNode - { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } @@ -39,35 +36,32 @@ public static class ListNode /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode node1 = new ListNode(2); ListNode node2 = new ListNode(3); node1.next = node2; System.out.println(new IntersectionOfTwoLists().getIntersectionNode(node1, node2)); } - public ListNode getIntersectionNode(ListNode headA, ListNode headB) - { - if(headA == null || headB == null) + public ListNode getIntersectionNode(ListNode headA, ListNode headB) { + if (headA == null || headB == null) return null; int l1len = 0, l2len = 0; ListNode temp1 = headA; - while(temp1 != null) - { + while (temp1 != null) { temp1 = temp1.next; - l1len ++; + l1len++; } temp1 = headB; - while(temp1 != null) - { + while (temp1 != null) { temp1 = temp1.next; - l2len ++; + l2len++; } @@ -75,30 +69,25 @@ public ListNode getIntersectionNode(ListNode headA, ListNode headB) ListNode temp2; - if(l1len > l2len) - { + if (l1len > l2len) { temp1 = headA; temp2 = headB; - } - else - { + } else { temp1 = headB; temp2 = headA; } - while(diff != 0) - { + while (diff != 0) { temp1 = temp1.next; diff--; } - while(!temp1.equals(temp2) ) - { + while (!temp1.equals(temp2)) { temp1 = temp1.next; temp2 = temp2.next; - if(temp1 == null || temp2 == null) return null; + if (temp1 == null || temp2 == null) return null; } - if(temp1.equals(temp2)) + if (temp1.equals(temp2)) return temp1; return null; } diff --git a/problems/src/linked_list/LinkedListCycle.java b/problems/src/linked_list/LinkedListCycle.java index ec218f89..72f5fa07 100644 --- a/problems/src/linked_list/LinkedListCycle.java +++ b/problems/src/linked_list/LinkedListCycle.java @@ -5,20 +5,19 @@ /** * Created by gouthamvidyapradhan on 23/02/2017. - Given a linked list, determine if it has a cycle in it. - - Follow up: - Can you solve it without using extra space? + * Given a linked list, determine if it has a cycle in it. + *

+ * Follow up: + * Can you solve it without using extra space? */ -public class LinkedListCycle -{ +public class LinkedListCycle { private static Set hashCode = new HashSet<>(); - static class ListNode - { + + static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } @@ -26,10 +25,10 @@ static class ListNode /** * Main method + * * @param args */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode node1 = new ListNode(1); ListNode node2 = new ListNode(2); ListNode node3 = new ListNode(3); @@ -39,19 +38,17 @@ public static void main(String[] args) throws Exception System.out.println(new LinkedListCycle().hasCycle(node1)); } - public boolean hasCycle(ListNode head) - { + public boolean hasCycle(ListNode head) { ListNode slow = head; ListNode fast = head; - while(slow != null && fast != null) - { + while (slow != null && fast != null) { slow = slow.next; fast = fast.next; - if(fast != null) + if (fast != null) fast = fast.next; else break; - if(fast != null && slow != null) - if(fast.equals(slow)) return true; + if (fast != null && slow != null) + if (fast.equals(slow)) return true; } return false; } diff --git a/problems/src/linked_list/MergeKSortedLists.java b/problems/src/linked_list/MergeKSortedLists.java index c15b5a80..8e3cd62f 100644 --- a/problems/src/linked_list/MergeKSortedLists.java +++ b/problems/src/linked_list/MergeKSortedLists.java @@ -2,16 +2,14 @@ /** * Created by gouthamvidyapradhan on 11/03/2017. - Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. + * Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. */ -public class MergeKSortedLists -{ - public static class ListNode - { +public class MergeKSortedLists { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } @@ -19,11 +17,11 @@ public static class ListNode /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode node2 = new ListNode(-1); ListNode node3 = new ListNode(5); ListNode node4 = new ListNode(11); @@ -68,16 +66,14 @@ public static void main(String[] args) throws Exception ListNode result = new MergeKSortedLists().mergeKLists(list); } - public ListNode mergeKLists(ListNode[] lists) - { - if(lists.length == 0) return null; - if(lists.length == 1) return lists[0]; + public ListNode mergeKLists(ListNode[] lists) { + if (lists.length == 0) return null; + if (lists.length == 1) return lists[0]; return merge(lists, 0, lists.length - 1); } - private ListNode merge(ListNode[] lists, int s, int e) - { - if(s == e) return lists[s]; + private ListNode merge(ListNode[] lists, int s, int e) { + if (s == e) return lists[s]; int m = s + (e - s) / 2; ListNode left = merge(lists, s, m); ListNode right = merge(lists, m + 1, e); @@ -85,26 +81,22 @@ private ListNode merge(ListNode[] lists, int s, int e) ListNode headNode = new ListNode(0); headNode.next = left; prev = headNode; - if(left == null && right == null) return null; - else if(left == null) return right; - else if(right == null) return left; - while(left != null && right != null) - { - if(left.val > right.val) - { + if (left == null && right == null) return null; + else if (left == null) return right; + else if (right == null) return left; + while (left != null && right != null) { + if (left.val > right.val) { temp = right; right = right.next; prev.next = temp; temp.next = left; prev = prev.next; - } - else - { + } else { left = left.next; prev = prev.next; } } - if(left == null && right != null) + if (left == null && right != null) prev.next = right; return headNode.next; } diff --git a/problems/src/linked_list/MergeTwoSortedList.java b/problems/src/linked_list/MergeTwoSortedList.java index c0eba315..377ebf10 100644 --- a/problems/src/linked_list/MergeTwoSortedList.java +++ b/problems/src/linked_list/MergeTwoSortedList.java @@ -2,23 +2,20 @@ /** * Created by gouthamvidyapradhan on 18/03/2017. - 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. + * 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. */ -public class MergeTwoSortedList -{ - public static class ListNode - { +public class MergeTwoSortedList { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } } - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode head = new ListNode(0); ListNode head1 = new ListNode(3); ListNode head2 = new ListNode(8); @@ -37,23 +34,19 @@ public static void main(String[] args) throws Exception ListNode newHead = new MergeTwoSortedList().mergeTwoLists(head, head3); ListNode link = newHead; - while(link != null) - { + while (link != null) { System.out.println(link.val); link = link.next; } } - public ListNode mergeTwoLists(ListNode l1, ListNode l2) - { - if(l1 == null) return l2; - else if(l2 == null) return l1; - if(l1.val <= l2.val) - { + + public ListNode mergeTwoLists(ListNode l1, ListNode l2) { + if (l1 == null) return l2; + else if (l2 == null) return l1; + if (l1.val <= l2.val) { l1.next = mergeTwoLists(l1.next, l2); return l1; - } - else - { + } else { l2.next = mergeTwoLists(l1, l2.next); return l2; } diff --git a/problems/src/linked_list/PaliandromeList.java b/problems/src/linked_list/PaliandromeList.java index 63c90e67..c1c930fe 100644 --- a/problems/src/linked_list/PaliandromeList.java +++ b/problems/src/linked_list/PaliandromeList.java @@ -2,32 +2,31 @@ /** * Created by gouthamvidyapradhan on 25/02/2017. - Given a singly linked list, determine if it is a palindrome. - - Follow up: - Could you do it in O(n) time and O(1) space? + * Given a singly linked list, determine if it is a palindrome. + *

+ * Follow up: + * Could you do it in O(n) time and O(1) space? */ -public class PaliandromeList -{ - public static class ListNode - { +public class PaliandromeList { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } } ListNode headNode; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode node1 = new ListNode(1); //ListNode node2 = new ListNode(2); //ListNode node3 = new ListNode(3); @@ -42,23 +41,20 @@ public static void main(String[] args) throws Exception System.out.println(new PaliandromeList().isPalindrome(node1)); } - public boolean isPalindrome(ListNode head) - { + public boolean isPalindrome(ListNode head) { int length = 0, count = 0; - if(head == null) return true; + if (head == null) return true; ListNode temp = head; - while(temp != null) - { + while (temp != null) { temp = temp.next; length++; } - if(length == 1) return true; + if (length == 1) return true; int halfLen = length / 2; temp = head; - while(count < halfLen - 1) - { + while (count < halfLen - 1) { temp = temp.next; count++; } @@ -67,9 +63,8 @@ public boolean isPalindrome(ListNode head) temp.next = null; reverse(newHead); ListNode first = head, second = headNode; - for(int i = 0; i < halfLen; i ++) - { - if(first.val != second.val) + for (int i = 0; i < halfLen; i++) { + if (first.val != second.val) return false; first = first.next; second = second.next; @@ -77,10 +72,8 @@ public boolean isPalindrome(ListNode head) return true; } - private ListNode reverse(ListNode node) - { - if(node.next == null) - { + private ListNode reverse(ListNode node) { + if (node.next == null) { headNode = node; return node; } diff --git a/problems/src/linked_list/ReverseLinkedList.java b/problems/src/linked_list/ReverseLinkedList.java index 451b219b..36df8437 100644 --- a/problems/src/linked_list/ReverseLinkedList.java +++ b/problems/src/linked_list/ReverseLinkedList.java @@ -2,18 +2,16 @@ /** * Created by gouthamvidyapradhan on 24/02/2017. - Reverse a singly linked list. + * Reverse a singly linked list. */ -public class ReverseLinkedList -{ +public class ReverseLinkedList { private ListNode newHead; - public static class ListNode - { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } @@ -21,11 +19,11 @@ public static class ListNode /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { ListNode node1 = new ListNode(1); ListNode node2 = new ListNode(2); ListNode node3 = new ListNode(3); @@ -41,18 +39,15 @@ public static void main(String[] args) throws Exception System.out.println(newNode.val); } - public ListNode reverseList(ListNode head) - { - if(head == null) return null; - else if(head.next == null) return head; + public ListNode reverseList(ListNode head) { + if (head == null) return null; + else if (head.next == null) return head; reverse(head).next = null; return newHead; } - private ListNode reverse(ListNode head) - { - if(head.next == null) - { + private ListNode reverse(ListNode head) { + if (head.next == null) { newHead = head; return head; } diff --git a/problems/src/linked_list/ReverseNodesKGroup.java b/problems/src/linked_list/ReverseNodesKGroup.java index fb058595..11dc19ca 100644 --- a/problems/src/linked_list/ReverseNodesKGroup.java +++ b/problems/src/linked_list/ReverseNodesKGroup.java @@ -3,88 +3,91 @@ /** * Created by gouthamvidyapradhan on 06/07/2017. * Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. - - k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. - - You may not alter the values in the nodes, only nodes itself may be changed. - - Only constant memory is allowed. - - For example, - Given this linked list: 1->2->3->4->5 - - For k = 2, you should return: 2->1->4->3->5 - - For k = 3, you should return: 3->2->1->4->5 - - - Solution: O(N) solution with constant space. - Recursively reverse a group of K nodes and for each group join the tail of the prev group to the head - of the next group. + *

+ * k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. + *

+ * You may not alter the values in the nodes, only nodes itself may be changed. + *

+ * Only constant memory is allowed. + *

+ * For example, + * Given this linked list: 1->2->3->4->5 + *

+ * For k = 2, you should return: 2->1->4->3->5 + *

+ * For k = 3, you should return: 3->2->1->4->5 + *

+ *

+ * Solution: O(N) solution with constant space. + * Recursively reverse a group of K nodes and for each group join the tail of the prev group to the head + * of the next group. */ public class ReverseNodesKGroup { public static class ListNode { int val; ListNode next; - ListNode(int x) { val = x; } + + ListNode(int x) { + val = x; + } } private ListNode newHead, newStart, prev; - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { ListNode node = new ListNode(1); node.next = new ListNode(2); node.next.next = new ListNode(3); node.next.next.next = new ListNode(4); node.next.next.next.next = new ListNode(5); ListNode result = new ReverseNodesKGroup().reverseKGroup(node, 2); - while(result != null){ + while (result != null) { System.out.println(result.val + " "); result = result.next; } } public ListNode reverseKGroup(ListNode head, int k) { - if(head == null) return null; + if (head == null) return null; ListNode node = head; int count = 0; - while(node != null){ + while (node != null) { node = node.next; count++; } - if(k > count) return head; + if (k > count) return head; int N = count / k; newStart = head; ListNode tail = null; ListNode result = null; - while(N -- > 0){ + while (N-- > 0) { tail = reverse(newStart, 1, k); tail.next = null; - if(result == null) + if (result == null) result = newHead; //save the head only once - if(prev != null){ + if (prev != null) { prev.next = newHead; } prev = tail; } - if(tail != null) + if (tail != null) tail.next = newStart; return result; } /** * Reverse k nodes - * @param node head node + * + * @param node head node * @param count count - * @param k K + * @param k K * @return */ - private ListNode reverse(ListNode node, int count, int k){ - if(count == k){ + private ListNode reverse(ListNode node, int count, int k) { + if (count == k) { newStart = node.next; //new start node newHead = node; //mark this as the new head - } - else{ + } else { ListNode nNode = reverse(node.next, count + 1, k); nNode.next = node; } diff --git a/problems/src/linked_list/SwapNodesInPairs.java b/problems/src/linked_list/SwapNodesInPairs.java index fa65c7b3..4a9bba13 100644 --- a/problems/src/linked_list/SwapNodesInPairs.java +++ b/problems/src/linked_list/SwapNodesInPairs.java @@ -3,23 +3,24 @@ /** * Created by gouthamvidyapradhan on 13/08/2017. * Given a linked list, swap every two adjacent nodes and return its head. - - For example, - Given 1->2->3->4, you should return the list as 2->1->4->3. - - Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. + *

+ * For example, + * Given 1->2->3->4, you should return the list as 2->1->4->3. + *

+ * Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. */ public class SwapNodesInPairs { - public static class ListNode{ + public static class ListNode { int val; ListNode next; - ListNode(int x){ + + ListNode(int x) { val = x; } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { ListNode node = new ListNode(1); node.next = new ListNode(2); node.next.next = new ListNode(3); @@ -27,24 +28,24 @@ public static void main(String[] args) throws Exception{ node.next.next.next.next = new ListNode(5); node.next.next.next.next.next = new ListNode(6); ListNode head = new SwapNodesInPairs().swapPairs(node); - while(head != null){ + while (head != null) { System.out.println(head.val); head = head.next; } } public ListNode swapPairs(ListNode head) { - if(head == null || head.next == null) + if (head == null || head.next == null) return head; ListNode newHead = head.next; ListNode curr = head.next; ListNode prev = head; ListNode prevPrev = new ListNode(-1); //dummy node - while(curr != null){ + while (curr != null) { prev.next = curr.next; curr.next = prev; prevPrev.next = curr; - if(prev.next != null){ + if (prev.next != null) { curr = prev.next.next; prev = prev.next; prevPrev = prevPrev.next.next; diff --git a/problems/src/math/AddDigits.java b/problems/src/math/AddDigits.java index c7fb605e..596714e0 100644 --- a/problems/src/math/AddDigits.java +++ b/problems/src/math/AddDigits.java @@ -3,23 +3,22 @@ /** * Created by gouthamvidyapradhan on 02/08/2017. * Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. - - For example: - - Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. - - Follow up: - Could you do it without any loop/recursion in O(1) runtime? - + *

+ * For example: + *

+ * Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. + *

+ * Follow up: + * Could you do it without any loop/recursion in O(1) runtime? */ public class AddDigits { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new AddDigits().addDigits(38)); } public int addDigits(int num) { - if(num == 0) return 0; + if (num == 0) return 0; return num % 9 == 0 ? 9 : num % 9; } diff --git a/problems/src/math/AddTwoNumbers.java b/problems/src/math/AddTwoNumbers.java index 1d30a8fa..a2387ab4 100644 --- a/problems/src/math/AddTwoNumbers.java +++ b/problems/src/math/AddTwoNumbers.java @@ -2,28 +2,25 @@ /** * Created by gouthamvidyapradhan on 13/03/2017. - You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. - - You may assume the two numbers do not contain any leading zero, except the number 0 itself. - - Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) - Output: 7 -> 0 -> 8 + * You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. + *

+ * You may assume the two numbers do not contain any leading zero, except the number 0 itself. + *

+ * Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) + * Output: 7 -> 0 -> 8 */ -public class AddTwoNumbers -{ - public static class ListNode - { +public class AddTwoNumbers { + public static class ListNode { int val; ListNode next; - ListNode(int x) - { + + ListNode(int x) { val = x; next = null; } } - public static void main(String[] args) - { + public static void main(String[] args) { ListNode node = new ListNode(2); node.next = new ListNode(4); node.next.next = new ListNode(4); @@ -35,16 +32,14 @@ public static void main(String[] args) ListNode result = new AddTwoNumbers().addTwoNumbers(node, node1); } - private ListNode addTwoNumbers(ListNode l1, ListNode l2) - { - if(l1 == null && l2 == null) return null; + private ListNode addTwoNumbers(ListNode l1, ListNode l2) { + if (l1 == null && l2 == null) return null; ListNode first = l1; ListNode second = l2; int carry = 0; ListNode head = new ListNode(0); ListNode prev = head; - while(first != null && second != null) - { + while (first != null && second != null) { int q = (first.val + second.val + carry) / 10; int r = (first.val + second.val + carry) % 10; carry = q; @@ -55,8 +50,7 @@ private ListNode addTwoNumbers(ListNode l1, ListNode l2) second = second.next; } - while(first != null) - { + while (first != null) { int q = (first.val + carry) / 10; int r = (first.val + carry) % 10; carry = q; @@ -66,8 +60,7 @@ private ListNode addTwoNumbers(ListNode l1, ListNode l2) first = first.next; } - while(second != null) - { + while (second != null) { int q = (second.val + carry) / 10; int r = (second.val + carry) % 10; carry = q; @@ -77,7 +70,7 @@ private ListNode addTwoNumbers(ListNode l1, ListNode l2) second = second.next; } - if(carry != 0) + if (carry != 0) prev.next = new ListNode(carry); return head.next; diff --git a/problems/src/math/CountPrimes.java b/problems/src/math/CountPrimes.java index 3b1c4c0a..a72140d1 100644 --- a/problems/src/math/CountPrimes.java +++ b/problems/src/math/CountPrimes.java @@ -4,39 +4,33 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. - Description: - - Count the number of prime numbers less than a non-negative number, n. + * Description: + *

+ * Count the number of prime numbers less than a non-negative number, n. */ -public class CountPrimes -{ +public class CountPrimes { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new CountPrimes().countPrimes(999187)); } - public int countPrimes(int n) - { - if(n == 0 || n == 1 || n == 2) return 0; - else if(n == 3) return 1; + public int countPrimes(int n) { + if (n == 0 || n == 1 || n == 2) return 0; + else if (n == 3) return 1; BitSet set = new BitSet(); n = n - 1; - int sqRt = (int)Math.sqrt(n); + int sqRt = (int) Math.sqrt(n); int count = n; - for(int i = 2; i <= sqRt; i ++) - { - if(!set.get(i)) - { - for(int j = 2; (i * j) <= n; j ++) - { - if(!set.get(i * j)) - { - count --; + for (int i = 2; i <= sqRt; i++) { + if (!set.get(i)) { + for (int j = 2; (i * j) <= n; j++) { + if (!set.get(i * j)) { + count--; set.set(i * j); } } diff --git a/problems/src/math/ExcelSheetColumnTitle.java b/problems/src/math/ExcelSheetColumnTitle.java index 8c1c4175..21c43c4c 100644 --- a/problems/src/math/ExcelSheetColumnTitle.java +++ b/problems/src/math/ExcelSheetColumnTitle.java @@ -3,39 +3,41 @@ /** * Created by gouthamvidyapradhan on 12/08/2017. * Given a positive integer, return its corresponding column title as appear in an Excel sheet. - - For example: - - 1 -> A - 2 -> B - 3 -> C - ... - 26 -> Z - 27 -> AA - 28 -> AB + *

+ * For example: + *

+ * 1 -> A + * 2 -> B + * 3 -> C + * ... + * 26 -> Z + * 27 -> AA + * 28 -> AB */ public class ExcelSheetColumnTitle { private static final String CONST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new ExcelSheetColumnTitle().convertToTitle(52)); } public String convertToTitle(int n) { StringBuilder ans = new StringBuilder(); - while(n > 0){ + while (n > 0) { int mod = n % 26; n /= 26; - if(mod == 0){ + if (mod == 0) { ans.append('Z'); n -= 1; - }else{ + } else { ans.append(CONST.charAt(mod - 1)); } } diff --git a/problems/src/math/RomanToInteger.java b/problems/src/math/RomanToInteger.java index 46067513..9b3a87d8 100644 --- a/problems/src/math/RomanToInteger.java +++ b/problems/src/math/RomanToInteger.java @@ -5,18 +5,19 @@ /** * Created by gouthamvidyapradhan on 12/08/2017. - * + *

* Given a roman numeral, convert it to an integer. - - Input is guaranteed to be within the range from 1 to 3999. + *

+ * Input is guaranteed to be within the range from 1 to 3999. */ public class RomanToInteger { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new RomanToInteger().romanToInt("DXCIX")); } @@ -32,11 +33,11 @@ public int romanToInt(String s) { String str = new StringBuilder(s).reverse().toString(); int sum = 0, prev = -1; - for(int i = 0, l = str.length(); i < l; i++){ + for (int i = 0, l = str.length(); i < l; i++) { int curr = map.get(str.charAt(i)); - if(curr < prev){ + if (curr < prev) { sum -= curr; - } else{ + } else { sum += curr; } prev = curr; diff --git a/problems/src/math/RotateFunction.java b/problems/src/math/RotateFunction.java index 775b5dc3..e0789341 100644 --- a/problems/src/math/RotateFunction.java +++ b/problems/src/math/RotateFunction.java @@ -2,55 +2,51 @@ /** * Created by gouthamvidyapradhan on 18/03/2017. - Given an array of integers A and let n to be its length. - - Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we define a "rotation function" F on A as follow: - - F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]. - - Calculate the maximum value of F(0), F(1), ..., F(n-1). - - Note: - n is guaranteed to be less than 105. - - Example: - - A = [4, 3, 2, 6] - - F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25 - F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16 - F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23 - F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26 - - So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26. + * Given an array of integers A and let n to be its length. + *

+ * Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we define a "rotation function" F on A as follow: + *

+ * F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]. + *

+ * Calculate the maximum value of F(0), F(1), ..., F(n-1). + *

+ * Note: + * n is guaranteed to be less than 105. + *

+ * Example: + *

+ * A = [4, 3, 2, 6] + *

+ * F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25 + * F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16 + * F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23 + * F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26 + *

+ * So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26. */ -public class RotateFunction -{ +public class RotateFunction { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] a = {4, 3, 2, 6}; System.out.println(new RotateFunction().maxRotateFunction(a)); } - public int maxRotateFunction(int[] A) - { - if(A.length == 0 || A.length == 1) return 0; + public int maxRotateFunction(int[] A) { + if (A.length == 0 || A.length == 1) return 0; int max = Integer.MIN_VALUE; int l = A.length; int sum = 0, prodSum = 0; - for(int i = 0; i < l; i ++) - { + for (int i = 0; i < l; i++) { prodSum += (A[i] * i); sum += A[i]; } max = Math.max(max, prodSum); - for(int i = 0; i < l - 1; i ++) - { + for (int i = 0; i < l - 1; i++) { prodSum = (prodSum - sum + A[i] + ((l - 1) * A[i])); max = Math.max(max, prodSum); } diff --git a/problems/src/math/WaterAndJugProblem.java b/problems/src/math/WaterAndJugProblem.java index c53af0ca..37572a85 100644 --- a/problems/src/math/WaterAndJugProblem.java +++ b/problems/src/math/WaterAndJugProblem.java @@ -5,31 +5,31 @@ /** * Created by gouthamvidyapradhan on 29/07/2017. * You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available. You need to determine whether it is possible to measure exactly z litres using these two jugs. - - If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end. - - Operations allowed: - - Fill any of the jugs completely with water. - Empty any of the jugs. - Pour water from one jug into another till the other jug is completely full or the first jug itself is empty. - Example 1: (From the famous "Die Hard" example) - - Input: x = 3, y = 5, z = 4 - Output: True - Example 2: - - Input: x = 2, y = 6, z = 5 - Output: False - + *

+ * If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end. + *

+ * Operations allowed: + *

+ * Fill any of the jugs completely with water. + * Empty any of the jugs. + * Pour water from one jug into another till the other jug is completely full or the first jug itself is empty. + * Example 1: (From the famous "Die Hard" example) + *

+ * Input: x = 3, y = 5, z = 4 + * Output: True + * Example 2: + *

+ * Input: x = 2, y = 6, z = 5 + * Output: False */ public class WaterAndJugProblem { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new WaterAndJugProblem().canMeasureWater(0, 0, 1)); } diff --git a/problems/src/stack/LargestRectangleInHistogram.java b/problems/src/stack/LargestRectangleInHistogram.java index cbe14b4a..985b2e6e 100644 --- a/problems/src/stack/LargestRectangleInHistogram.java +++ b/problems/src/stack/LargestRectangleInHistogram.java @@ -5,43 +5,42 @@ /** * Created by gouthamvidyapradhan on 20/06/2017. * Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. - - For example, - Given heights = [2,1,5,6,2,3], - return 10. (min of index 2 and 3 multiplied by two) - - Solution O(N): - - 1) Create an empty stack. - - 2) Start from first bar, and do following for every bar ‘hist[i]’ where ‘i’ varies from 0 to n-1. - a) If stack is empty or hist[i] is higher than the bar at top of stack, then push ‘i’ to stack. - b) If this bar is smaller than the top of stack, then keep removing the top of stack while top of the stack is greater. Let the removed bar be hist[tp]. - Calculate area of rectangle with hist[tp] as smallest bar. For hist[tp], the ‘left index’ is previous (previous to tp) item in stack and ‘right index’ is ‘i’ (current index). - - 3) If the stack is not empty, then one by one remove all bars from stack and do step 2.b for every removed bar. - + *

+ * For example, + * Given heights = [2,1,5,6,2,3], + * return 10. (min of index 2 and 3 multiplied by two) + *

+ * Solution O(N): + *

+ * 1) Create an empty stack. + *

+ * 2) Start from first bar, and do following for every bar ‘hist[i]’ where ‘i’ varies from 0 to n-1. + * a) If stack is empty or hist[i] is higher than the bar at top of stack, then push ‘i’ to stack. + * b) If this bar is smaller than the top of stack, then keep removing the top of stack while top of the stack is greater. Let the removed bar be hist[tp]. + * Calculate area of rectangle with hist[tp] as smallest bar. For hist[tp], the ‘left index’ is previous (previous to tp) item in stack and ‘right index’ is ‘i’ (current index). + *

+ * 3) If the stack is not empty, then one by one remove all bars from stack and do step 2.b for every removed bar. */ public class LargestRectangleInHistogram { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] A = {2, 3}; System.out.println(new LargestRectangleInHistogram().largestRectangleArea(A)); } public int largestRectangleArea(int[] heights) { - if(heights.length == 0) return 0; + if (heights.length == 0) return 0; int maxArea = Integer.MIN_VALUE; Stack stack = new Stack<>(); int i = 0; - for(; i < heights.length; i ++) { - while(!stack.isEmpty() && heights[stack.peek()] >= heights[i]) { + for (; i < heights.length; i++) { + while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) { int top = stack.pop(); int base = stack.isEmpty() ? i : i - stack.peek() - 1; maxArea = Math.max(maxArea, base * heights[top]); } stack.push(i); } - while(!stack.isEmpty()) { + while (!stack.isEmpty()) { int top = stack.pop(); int base = stack.isEmpty() ? i : i - stack.peek() - 1; maxArea = Math.max(maxArea, base * heights[top]); diff --git a/problems/src/stack/MinStack.java b/problems/src/stack/MinStack.java index a5ea3f25..5cd66d68 100644 --- a/problems/src/stack/MinStack.java +++ b/problems/src/stack/MinStack.java @@ -4,42 +4,41 @@ /** * Created by gouthamvidyapradhan on 08/03/2017. - Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. - - push(x) -- Push element x onto stack. - pop() -- Removes the element on top of the stack. - top() -- Get the top element. - getMin() -- Retrieve the minimum element in the stack. - Example: - MinStack minStack = new MinStack(); - minStack.push(-2); - minStack.push(0); - minStack.push(-3); - minStack.getMin(); --> Returns -3. - minStack.pop(); - minStack.top(); --> Returns 0. - minStack.getMin(); --> Returns -2. + * Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. + *

+ * push(x) -- Push element x onto stack. + * pop() -- Removes the element on top of the stack. + * top() -- Get the top element. + * getMin() -- Retrieve the minimum element in the stack. + * Example: + * MinStack minStack = new MinStack(); + * minStack.push(-2); + * minStack.push(0); + * minStack.push(-3); + * minStack.getMin(); --> Returns -3. + * minStack.pop(); + * minStack.top(); --> Returns 0. + * minStack.getMin(); --> Returns -2. */ -public class MinStack -{ - class Node - { +public class MinStack { + class Node { int value, min; - Node(int value, int min) - { + + Node(int value, int min) { this.value = value; this.min = min; } } private Stack stack = new Stack<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); @@ -50,38 +49,30 @@ public static void main(String[] args) throws Exception System.out.println(minStack.getMin()); } - public MinStack() - { + public MinStack() { } - public void push(int x) - { + public void push(int x) { Node node; - if(!stack.isEmpty()) - { + if (!stack.isEmpty()) { Node top = stack.peek(); node = new Node(x, Math.min(top.min, x)); - } - else - { + } else { node = new Node(x, x); } stack.push(node); } - public void pop() - { + public void pop() { stack.pop(); } - public int top() - { + public int top() { return stack.peek().value; } - public int getMin() - { + public int getMin() { return stack.peek().min; } diff --git a/problems/src/stack/MyQueue.java b/problems/src/stack/MyQueue.java index 911a9bca..0b29d36e 100644 --- a/problems/src/stack/MyQueue.java +++ b/problems/src/stack/MyQueue.java @@ -5,21 +5,22 @@ /** * Created by gouthamvidyapradhan on 29/07/2017. * Implement the following operations of a queue using stacks. - - push(x) -- Push element x to the back of queue. - pop() -- Removes the element from in front of queue. - peek() -- Get the front element. - empty() -- Return whether the queue is empty. - - Notes: - You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid. - Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack. - You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). + *

+ * push(x) -- Push element x to the back of queue. + * pop() -- Removes the element from in front of queue. + * peek() -- Get the front element. + * empty() -- Return whether the queue is empty. + *

+ * Notes: + * You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid. + * Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack. + * You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). */ public class MyQueue { private Stack stack; - public static void main(String[] args) throws Exception{ + + public static void main(String[] args) throws Exception { MyQueue myQueue = new MyQueue(); myQueue.push(5); myQueue.push(12); @@ -32,43 +33,53 @@ public static void main(String[] args) throws Exception{ System.out.println(myQueue.pop()); } - /** Initialize your data structure here. */ + /** + * Initialize your data structure here. + */ public MyQueue() { stack = new Stack<>(); } - /** Push element x to the back of queue. */ + /** + * Push element x to the back of queue. + */ public void push(int x) { stack.push(x); } - /** Removes the element from in front of queue and returns that element. */ + /** + * Removes the element from in front of queue and returns that element. + */ public int pop() { Stack auxStack = new Stack<>(); - while(!stack.isEmpty()){ + while (!stack.isEmpty()) { auxStack.push(stack.pop()); } int result = auxStack.pop(); - while(!auxStack.isEmpty()){ + while (!auxStack.isEmpty()) { stack.push(auxStack.pop()); } return result; } - /** Get the front element. */ + /** + * Get the front element. + */ public int peek() { Stack auxStack = new Stack<>(); - while(!stack.isEmpty()){ + while (!stack.isEmpty()) { auxStack.push(stack.pop()); } int result = auxStack.peek(); - while(!auxStack.isEmpty()){ + while (!auxStack.isEmpty()) { stack.push(auxStack.pop()); } return result; } - /** Returns whether the queue is empty. */ + /** + * Returns whether the queue is empty. + */ public boolean empty() { return stack.isEmpty(); } diff --git a/problems/src/stack/ValidParentheses.java b/problems/src/stack/ValidParentheses.java index fdabe184..d3a6213a 100644 --- a/problems/src/stack/ValidParentheses.java +++ b/problems/src/stack/ValidParentheses.java @@ -6,22 +6,20 @@ /** * Created by gouthamvidyapradhan on 25/02/2017. - Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. - - The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. + * Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. + *

+ * The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. */ -public class ValidParentheses -{ - public static void main(String[] args) - { +public class ValidParentheses { + public static void main(String[] args) { System.out.println(hasBalancedBrackets("(h[e")); } + private static Map MAP = new HashMap<>(); // METHOD SIGNATURE BEGINS, THIS METHOD IS REQUIRED - public static int hasBalancedBrackets(String str) - { - if(str == null) return 1; + public static int hasBalancedBrackets(String str) { + if (str == null) return 1; MAP.put(')', '('); MAP.put('}', '{'); @@ -29,10 +27,8 @@ public static int hasBalancedBrackets(String str) MAP.put(']', '['); Stack stack = new Stack<>(); - for(int i = 0, l = str.length(); i < l; i ++) - { - switch (str.charAt(i)) - { + for (int i = 0, l = str.length(); i < l; i++) { + switch (str.charAt(i)) { case '(': case '{': case '[': @@ -44,9 +40,9 @@ public static int hasBalancedBrackets(String str) case '}': case ']': case '>': - if(stack.isEmpty()) return 0; + if (stack.isEmpty()) return 0; char top = stack.pop(); - if(top != MAP.get(str.charAt(i))) return 0; + if (top != MAP.get(str.charAt(i))) return 0; break; default: //ignore diff --git a/problems/src/string/CompareVersionNumbers.java b/problems/src/string/CompareVersionNumbers.java index 8d7a814a..82419240 100644 --- a/problems/src/string/CompareVersionNumbers.java +++ b/problems/src/string/CompareVersionNumbers.java @@ -5,46 +5,46 @@ /** * Created by pradhang on 7/11/2017. * Compare two version numbers version1 and version2. - If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. - - You may assume that the version strings are non-empty and contain only digits and the . character. - The . character does not represent a decimal point and is used to separate number sequences. - For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. - - Here is an example of version numbers ordering: - - 0.1 < 1.1 < 1.2 < 13.37 + * If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. + *

+ * You may assume that the version strings are non-empty and contain only digits and the . character. + * The . character does not represent a decimal point and is used to separate number sequences. + * For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. + *

+ * Here is an example of version numbers ordering: + *

+ * 0.1 < 1.1 < 1.2 < 13.37 */ public class CompareVersionNumbers { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new CompareVersionNumbers().compareVersion("1.11.1", "1.11")); } public int compareVersion(String version1, String version2) { StringTokenizer st1 = new StringTokenizer(version1, "."); StringTokenizer st2 = new StringTokenizer(version2, "."); - while(st1.hasMoreTokens() & st2.hasMoreTokens()){ + while (st1.hasMoreTokens() & st2.hasMoreTokens()) { int token1 = Integer.parseInt(st1.nextToken()); int token2 = Integer.parseInt(st2.nextToken()); - if(token1 > token2) + if (token1 > token2) return 1; - else if(token2 > token1) + else if (token2 > token1) return -1; } - if(st1.countTokens() > st2.countTokens()){ - while(st1.hasMoreTokens()){ - if(Integer.parseInt(st1.nextToken()) > 0) + if (st1.countTokens() > st2.countTokens()) { + while (st1.hasMoreTokens()) { + if (Integer.parseInt(st1.nextToken()) > 0) return 1; } - } - else if(st2.countTokens() > st1.countTokens()){ - while(st2.hasMoreTokens()){ - if(Integer.parseInt(st2.nextToken()) > 0) + } else if (st2.countTokens() > st1.countTokens()) { + while (st2.hasMoreTokens()) { + if (Integer.parseInt(st2.nextToken()) > 0) return -1; } } diff --git a/problems/src/string/ExcelSheetColumnNumber.java b/problems/src/string/ExcelSheetColumnNumber.java index db08bab8..9431f510 100644 --- a/problems/src/string/ExcelSheetColumnNumber.java +++ b/problems/src/string/ExcelSheetColumnNumber.java @@ -3,30 +3,31 @@ /** * Created by gouthamvidyapradhan on 07/07/2017. * Given a column title as appear in an Excel sheet, return its corresponding column number. - - For example: - - A -> 1 - B -> 2 - C -> 3 - ... - Z -> 26 - AA -> 27 - AB -> 28 + *

+ * For example: + *

+ * A -> 1 + * B -> 2 + * C -> 3 + * ... + * Z -> 26 + * AA -> 27 + * AB -> 28 */ public class ExcelSheetColumnNumber { String CONST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - public static void main(String[] args) throws Exception{ + + public static void main(String[] args) throws Exception { System.out.println(new ExcelSheetColumnNumber().titleToNumber("AAB")); } public int titleToNumber(String s) { int total = 0; int j = 0; - for(int i = s.length() - 1; i >= 0; i --){ + for (int i = s.length() - 1; i >= 0; i--) { char c = s.charAt(i); int pos = CONST.indexOf(c) + 1; - int pow = (int)Math.pow(26, j++); + int pow = (int) Math.pow(26, j++); total += (pow * pos); } return total; diff --git a/problems/src/string/FirstUniqueCharacterInAString.java b/problems/src/string/FirstUniqueCharacterInAString.java index fc04dc06..08aa90ad 100644 --- a/problems/src/string/FirstUniqueCharacterInAString.java +++ b/problems/src/string/FirstUniqueCharacterInAString.java @@ -2,40 +2,38 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. - - Examples: - - s = "leetcode" - return 0. - - s = "loveleetcode", - return 2. - Note: You may assume the string contain only lowercase letters. + * Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. + *

+ * Examples: + *

+ * s = "leetcode" + * return 0. + *

+ * s = "loveleetcode", + * return 2. + * Note: You may assume the string contain only lowercase letters. */ -public class FirstUniqueCharacterInAString -{ +public class FirstUniqueCharacterInAString { int[] CHAR = new int[256]; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new FirstUniqueCharacterInAString().firstUniqChar("loveleetcode")); } - public int firstUniqChar(String s) - { - if(s == null || s.isEmpty()) return -1; + public int firstUniqChar(String s) { + if (s == null || s.isEmpty()) return -1; - for(int i = 0, l = s.length(); i < l; i ++) + for (int i = 0, l = s.length(); i < l; i++) CHAR[s.charAt(i)]++; - for(int i = 0, l = s.length(); i < l; i ++) - { - if(CHAR[s.charAt(i)] == 1) + for (int i = 0, l = s.length(); i < l; i++) { + if (CHAR[s.charAt(i)] == 1) return i; } diff --git a/problems/src/string/ImplementStrStr.java b/problems/src/string/ImplementStrStr.java index b273a814..374908d8 100644 --- a/problems/src/string/ImplementStrStr.java +++ b/problems/src/string/ImplementStrStr.java @@ -3,34 +3,34 @@ /** * Created by gouthamvidyapradhan on 24/06/2017. * Implement strStr(). - - Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. - - Solution O(N ^ 2) + *

+ * Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. + *

+ * Solution O(N ^ 2) */ public class ImplementStrStr { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new ImplementStrStr().strStr("AABB", "")); } public int strStr(String haystack, String needle) { - if(haystack.isEmpty() && needle.isEmpty()) return 0; - if(needle.isEmpty()) return 0; - for(int i = 0, l = haystack.length(); i < l; i ++){ - if(haystack.charAt(i) == needle.charAt(0)){ - if(isEqual(haystack, needle, i)) + if (haystack.isEmpty() && needle.isEmpty()) return 0; + if (needle.isEmpty()) return 0; + for (int i = 0, l = haystack.length(); i < l; i++) { + if (haystack.charAt(i) == needle.charAt(0)) { + if (isEqual(haystack, needle, i)) return i; } } return -1; } - private boolean isEqual(String haystack, String needle, int i){ + private boolean isEqual(String haystack, String needle, int i) { int hL = haystack.length(); int nL = needle.length(); int j = 0; - while(i < hL && j < nL){ - if(haystack.charAt(i) != needle.charAt(j)) + while (i < hL && j < nL) { + if (haystack.charAt(i) != needle.charAt(j)) return false; i++; j++; diff --git a/problems/src/string/RepeatedSubstringPattern.java b/problems/src/string/RepeatedSubstringPattern.java index 0245e4a6..9acc361a 100644 --- a/problems/src/string/RepeatedSubstringPattern.java +++ b/problems/src/string/RepeatedSubstringPattern.java @@ -2,59 +2,54 @@ /** * Created by gouthamvidyapradhan on 25/03/2017. - Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000. - - Example 1: - Input: "abab" - - Output: True - - Explanation: It's the substring "ab" twice. - Example 2: - Input: "aba" - - Output: False - Example 3: - Input: "abcabcabcabc" - - Output: True - - Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.) + * Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000. + *

+ * Example 1: + * Input: "abab" + *

+ * Output: True + *

+ * Explanation: It's the substring "ab" twice. + * Example 2: + * Input: "aba" + *

+ * Output: False + * Example 3: + * Input: "abcabcabcabc" + *

+ * Output: True + *

+ * Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.) */ -public class RepeatedSubstringPattern -{ +public class RepeatedSubstringPattern { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new RepeatedSubstringPattern().repeatedSubstringPattern("a")); } - public boolean repeatedSubstringPattern(String s) - { + public boolean repeatedSubstringPattern(String s) { boolean found; - for(int i = 1, l = s.length(); i < l; i ++) - { + for (int i = 1, l = s.length(); i < l; i++) { found = true; String subI = s.substring(0, i); int j = i; - if(j >= l) return false; - while(j < l) - { - if((j + i) >= l + 1) + if (j >= l) return false; + while (j < l) { + if ((j + i) >= l + 1) return false; - String subJ = s.substring(j , j + i); - if(!subI.equals(subJ)) - { + String subJ = s.substring(j, j + i); + if (!subI.equals(subJ)) { found = false; break; } j += i; } - if(found) return true; + if (found) return true; } return false; } diff --git a/problems/src/string/ReverseWordsII.java b/problems/src/string/ReverseWordsII.java index 0f6de4de..a948fa7b 100644 --- a/problems/src/string/ReverseWordsII.java +++ b/problems/src/string/ReverseWordsII.java @@ -2,76 +2,65 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. - Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters. - - The input string does not contain leading or trailing spaces and the words are always separated by a single space. - - For example, - Given s = "the sky is blue", - return "blue is sky the". - - Could you do it in-place without allocating extra space? + * Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters. + *

+ * The input string does not contain leading or trailing spaces and the words are always separated by a single space. + *

+ * For example, + * Given s = "the sky is blue", + * return "blue is sky the". + *

+ * Could you do it in-place without allocating extra space? */ -public class ReverseWordsII -{ +public class ReverseWordsII { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - char[] c = {'t','h','e', ' ', 's', 'k', 'y', ' ', 'i', 's', ' ', 'b', 'l', 'u', 'e'}; + public static void main(String[] args) throws Exception { + char[] c = {'t', 'h', 'e', ' ', 's', 'k', 'y', ' ', 'i', 's', ' ', 'b', 'l', 'u', 'e'}; new ReverseWordsII().reverseWords(c); for (char i : c) System.out.print(i); } - public void reverseWords(char[] s) - { - for(int i = 0, j = s.length - 1; i < j; i ++, j --) - { + public void reverseWords(char[] s) { + for (int i = 0, j = s.length - 1; i < j; i++, j--) { char temp = s[i]; s[i] = s[j]; s[j] = temp; } - for(int i = 0, j = 0, l = s.length; i < l;) - { - if(s[i] == ' ') - { - if(s[i - 1] == ' ') - { + for (int i = 0, j = 0, l = s.length; i < l; ) { + if (s[i] == ' ') { + if (s[i - 1] == ' ') { j = i; - i ++; j ++; - } - else - { + i++; + j++; + } else { i = i - 1; - for(int p = j, q = i; p < q; p ++, q--) - { + for (int p = j, q = i; p < q; p++, q--) { char temp = s[p]; s[p] = s[q]; s[q] = temp; } i = i + 1; j = i; - i ++; j ++; + i++; + j++; } - } - else if(i == l - 1) - { - for(int p = j, q = i; p < q; p ++, q--) - { + } else if (i == l - 1) { + for (int p = j, q = i; p < q; p++, q--) { char temp = s[p]; s[p] = s[q]; s[q] = temp; } j = i; - i ++; j ++; - } - else - { - i ++; + i++; + j++; + } else { + i++; } } } diff --git a/problems/src/string/ReverseWordsInAString.java b/problems/src/string/ReverseWordsInAString.java index 9d4822bb..a29b6850 100644 --- a/problems/src/string/ReverseWordsInAString.java +++ b/problems/src/string/ReverseWordsInAString.java @@ -7,40 +7,40 @@ /** * Created by gouthamvidyapradhan on 04/07/2017. * Given an input string, reverse the string word by word. - - For example, - Given s = "the sky is blue", - return "blue is sky the". - - Clarification: - What constitutes a word? - A sequence of non-space characters constitutes a word. - Could the input string contain leading or trailing spaces? - Yes. However, your reversed string should not contain leading or trailing spaces. - How about multiple spaces between two words? - Reduce them to a single space in the reversed string. + *

+ * For example, + * Given s = "the sky is blue", + * return "blue is sky the". + *

+ * Clarification: + * What constitutes a word? + * A sequence of non-space characters constitutes a word. + * Could the input string contain leading or trailing spaces? + * Yes. However, your reversed string should not contain leading or trailing spaces. + * How about multiple spaces between two words? + * Reduce them to a single space in the reversed string. */ public class ReverseWordsInAString { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new ReverseWordsInAString().reverseWords(" the sky is blue")); } public String reverseWords(String s) { - if(s == null || s.isEmpty()) return ""; + if (s == null || s.isEmpty()) return ""; StringBuilder sb = new StringBuilder(s.trim()); String reverse = sb.reverse().toString(); StringTokenizer st = new StringTokenizer(reverse, " "); List list = new ArrayList<>(); - while(st.hasMoreTokens()){ + while (st.hasMoreTokens()) { list.add(st.nextToken()); } - for(int i = 0, l = list.size(); i < l; i ++){ + for (int i = 0, l = list.size(); i < l; i++) { String str = list.get(i); String newStr = new StringBuilder(str).reverse().toString(); list.set(i, newStr); } StringBuilder result = new StringBuilder(); - for(String str : list){ + for (String str : list) { result.append(str).append(" "); } return result.toString().trim(); diff --git a/problems/src/string/SimplifyPath.java b/problems/src/string/SimplifyPath.java index ebd3be19..7905249d 100644 --- a/problems/src/string/SimplifyPath.java +++ b/problems/src/string/SimplifyPath.java @@ -6,46 +6,46 @@ /** * Created by gouthamvidyapradhan on 28/07/2017. - * + *

* Given an absolute path for a file (Unix-style), simplify it. - - For example, - path = "/home/", => "/home" - path = "/a/./b/../../c/", => "/c" - - Corner Cases: - Did you consider the case where path = "/../"? - In this case, you should return "/". - Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". - In this case, you should ignore redundant slashes and return "/home/foo". + *

+ * For example, + * path = "/home/", => "/home" + * path = "/a/./b/../../c/", => "/c" + *

+ * Corner Cases: + * Did you consider the case where path = "/../"? + * In this case, you should return "/". + * Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". + * In this case, you should ignore redundant slashes and return "/home/foo". */ public class SimplifyPath { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new SimplifyPath().simplifyPath("/home/")); } public String simplifyPath(String path) { - if(path == null || path.isEmpty()) return "/"; + if (path == null || path.isEmpty()) return "/"; StringTokenizer st = new StringTokenizer(path, "/"); Deque dQueue = new ArrayDeque<>(); - while(st.hasMoreTokens()){ + while (st.hasMoreTokens()) { String token = st.nextToken(); - if(token.trim().equals("..")){ - if(!dQueue.isEmpty()) + if (token.trim().equals("..")) { + if (!dQueue.isEmpty()) dQueue.pop(); - } else if(token.trim().equals(".")){ + } else if (token.trim().equals(".")) { //ignore - } - else dQueue.push(token); + } else dQueue.push(token); } - if(dQueue.isEmpty()) return "/"; + if (dQueue.isEmpty()) return "/"; StringBuilder finalStr = new StringBuilder(); - while(!dQueue.isEmpty()){ + while (!dQueue.isEmpty()) { finalStr.append("/").append(dQueue.removeLast()); } return finalStr.toString(); diff --git a/problems/src/string/StringToInteger.java b/problems/src/string/StringToInteger.java index e172f121..f9d790b0 100644 --- a/problems/src/string/StringToInteger.java +++ b/problems/src/string/StringToInteger.java @@ -2,67 +2,55 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. - Implement atoi to convert a string to an integer. - - Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. - - Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. + * Implement atoi to convert a string to an integer. + *

+ * Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. + *

+ * Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. */ -public class StringToInteger -{ +public class StringToInteger { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new StringToInteger().myAtoi(" 2147483649a sdfasdf")); } - public int myAtoi(String str) - { + public int myAtoi(String str) { boolean isPositive = true; - if(str == null || str.trim().isEmpty()) return 0; + if (str == null || str.trim().isEmpty()) return 0; str = str.trim(); - if(str.charAt(0) == '+') - { + if (str.charAt(0) == '+') { isPositive = true; str = str.substring(1, str.length()); - } - else if(str.charAt(0) == '-') - { + } else if (str.charAt(0) == '-') { isPositive = false; str = str.substring(1, str.length()); - } - - else if(str.charAt(0) > '9' || str.charAt(0) < '0') + } else if (str.charAt(0) > '9' || str.charAt(0) < '0') return 0; int i = 0; - for(int l = str.length(); i < l; i ++) - { - if(str.charAt(i) > '9' || str.charAt(i) < '0') + for (int l = str.length(); i < l; i++) { + if (str.charAt(i) > '9' || str.charAt(i) < '0') break; } str = str.substring(0, i); long num = 0; - for(int j = 0, l = str.length(); j < l; j++) - { + for (int j = 0, l = str.length(); j < l; j++) { int n = (str.charAt(j) - '0'); num *= 10; num += n; - if(isPositive) - { - if(num > Integer.MAX_VALUE) return Integer.MAX_VALUE; - } - else - { - if((num * -1) < Integer.MIN_VALUE) return Integer.MIN_VALUE; + if (isPositive) { + if (num > Integer.MAX_VALUE) return Integer.MAX_VALUE; + } else { + if ((num * -1) < Integer.MIN_VALUE) return Integer.MIN_VALUE; } } - if(isPositive) - return (int)num; - else return (int)(num * -1); + if (isPositive) + return (int) num; + else return (int) (num * -1); } diff --git a/problems/src/string/TextJustification.java b/problems/src/string/TextJustification.java index 420bd24c..74c35307 100644 --- a/problems/src/string/TextJustification.java +++ b/problems/src/string/TextJustification.java @@ -5,72 +5,61 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified. - - You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters. - - Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right. - - For the last line of text, it should be left justified and no extra space is inserted between words. - - For example, - words: ["This", "is", "an", "example", "of", "text", "justification."] - L: 16. - - Return the formatted lines as: - [ - "This is an", - "example of text", - "justification. " - ] - Note: Each word is guaranteed not to exceed L in length. + * Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified. + *

+ * You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters. + *

+ * Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right. + *

+ * For the last line of text, it should be left justified and no extra space is inserted between words. + *

+ * For example, + * words: ["This", "is", "an", "example", "of", "text", "justification."] + * L: 16. + *

+ * Return the formatted lines as: + * [ + * "This is an", + * "example of text", + * "justification. " + * ] + * Note: Each word is guaranteed not to exceed L in length. */ -public class TextJustification -{ - public List fullJustify(String[] words, int L) - { +public class TextJustification { + public List fullJustify(String[] words, int L) { int wCount = 0, charCount = 0; List line = new ArrayList<>(); List result = new ArrayList<>(); StringBuilder sb = new StringBuilder(); - for(int i = 0, l = words.length; i < l; i++) - { + for (int i = 0, l = words.length; i < l; i++) { String next = words[i]; - if( (L - (charCount + wCount)) >= next.length()) - { + if ((L - (charCount + wCount)) >= next.length()) { line.add(next); charCount += next.length(); wCount++; - } - else - { + } else { //justify and add to list sb.append(line.get(0)); StringBuilder space = new StringBuilder(); - if(line.size() > 1) - { + if (line.size() > 1) { int spaceCount = (L - charCount) / (wCount - 1); int remaining = (L - charCount) % (wCount - 1); - for(int j = 0; j < spaceCount; j++) + for (int j = 0; j < spaceCount; j++) space.append(' '); - for(int k = 1, kl = line.size(); k < kl; k++) - { + for (int k = 1, kl = line.size(); k < kl; k++) { sb.append(space); - if(remaining > 0) - { + if (remaining > 0) { sb.append(' '); --remaining; } sb.append(line.get(k)); } - } - else - { + } else { int balance = L - (charCount + (wCount - 1)); - for(int j = 0; j < balance; j ++) + for (int j = 0; j < balance; j++) sb.append(' '); } result.add(sb.toString()); @@ -81,17 +70,15 @@ public List fullJustify(String[] words, int L) wCount = 1; } } - if(!line.isEmpty()) - { + if (!line.isEmpty()) { sb.append(line.get(0)); - for(int i = 1, l = line.size(); i < l; i++) - { + for (int i = 1, l = line.size(); i < l; i++) { sb.append(' '); sb.append(line.get(i)); } } int balance = L - (charCount + (wCount - 1)); - for(int i = 0; i < balance; i ++) + for (int i = 0; i < balance; i++) sb.append(' '); result.add(sb.toString()); return result; diff --git a/problems/src/string/ValidPalindrome.java b/problems/src/string/ValidPalindrome.java index 1a565826..3144d001 100644 --- a/problems/src/string/ValidPalindrome.java +++ b/problems/src/string/ValidPalindrome.java @@ -3,40 +3,39 @@ /** * Created by gouthamvidyapradhan on 13/07/2017. * Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. - - For example, - "A man, a plan, a canal: Panama" is a palindrome. - "race a car" is not a palindrome. - - Note: - Have you consider that the string might be empty? This is a good question to ask during an interview. - - For the purpose of this problem, we define empty string as valid palindrome. - - + *

+ * For example, + * "A man, a plan, a canal: Panama" is a palindrome. + * "race a car" is not a palindrome. + *

+ * Note: + * Have you consider that the string might be empty? This is a good question to ask during an interview. + *

+ * For the purpose of this problem, we define empty string as valid palindrome. */ public class ValidPalindrome { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { System.out.println(new ValidPalindrome().isPalindrome("989 ")); } public boolean isPalindrome(String s) { - if(s == null || s.isEmpty()) return true; + if (s == null || s.isEmpty()) return true; s = s.toLowerCase(); - for(int i = 0,j = s.length() - 1; i < j; ){ + for (int i = 0, j = s.length() - 1; i < j; ) { char f = s.charAt(i); char l = s.charAt(j); - if(!(f >= 'a' && f <= 'z') && !(f >= '0' && f <= '9')){ + if (!(f >= 'a' && f <= 'z') && !(f >= '0' && f <= '9')) { i++; continue; } - if(!(l >= 'a' && l <= 'z') && !(l >= '0' && l <= '9')){ + if (!(l >= 'a' && l <= 'z') && !(l >= '0' && l <= '9')) { j--; continue; } - if(f != l) + if (f != l) return false; - i++; j --; + i++; + j--; } return true; } diff --git a/problems/src/string/ZigZagConversion.java b/problems/src/string/ZigZagConversion.java index b017431e..f88c9aff 100644 --- a/problems/src/string/ZigZagConversion.java +++ b/problems/src/string/ZigZagConversion.java @@ -6,51 +6,50 @@ /** * Created by gouthamvidyapradhan on 19/05/2017. - The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) - - P A H N - A P L S I I G - Y I R - And then read line by line: "PAHNAPLSIIGYIR" - Write the code that will take a string and make this conversion given a number of rows: - - string convert(string text, int nRows); - convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". + * The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) + *

+ * P A H N + * A P L S I I G + * Y I R + * And then read line by line: "PAHNAPLSIIGYIR" + * Write the code that will take a string and make this conversion given a number of rows: + *

+ * string convert(string text, int nRows); + * convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". */ -public class ZigZagConversion -{ +public class ZigZagConversion { /** * Main method + * * @param args */ - public static void main(String[] args) - { + public static void main(String[] args) { System.out.println(new ZigZagConversion().convert("PAYPALISHIRING", 5)); } /** * Convert and return the result - * @param s input string + * + * @param s input string * @param numRows max rows * @return Result string */ public String convert(String s, int numRows) { - if(s == null || s.length() <= numRows || numRows == 1) return s; + if (s == null || s.length() <= numRows || numRows == 1) return s; List list = new ArrayList<>(); char[] A = new char[numRows]; int direction = 1; // 1 indicates forward, 0 indicates backwards int n = 1; A[0] = s.charAt(0); - for(int j = 1; j < numRows;) { - if(n >= s.length()) break; + for (int j = 1; j < numRows; ) { + if (n >= s.length()) break; A[j] = s.charAt(n++); - if(j == numRows - 1) { + if (j == numRows - 1) { list.add(String.valueOf(A)); A = new char[numRows]; Arrays.fill(A, ' '); direction = 0; - } - else if(j == 0) { + } else if (j == 0) { list.add(String.valueOf(A)); A = new char[numRows]; Arrays.fill(A, ' '); @@ -58,11 +57,11 @@ else if(j == 0) { } j = direction == 1 ? j + 1 : j - 1; } - if(!String.valueOf(A).trim().isEmpty()) + if (!String.valueOf(A).trim().isEmpty()) list.add(String.valueOf(A)); char[] arr = new char[s.length()]; int k = 0; - for(int j = 0; j < numRows; j ++) { + for (int j = 0; j < numRows; j++) { for (String aList : list) { if (aList.charAt(j) != ' ') arr[k++] = aList.charAt(j); diff --git a/problems/src/tree/BinarayTreeRightSideView.java b/problems/src/tree/BinarayTreeRightSideView.java index d4aa5ad9..821cd279 100644 --- a/problems/src/tree/BinarayTreeRightSideView.java +++ b/problems/src/tree/BinarayTreeRightSideView.java @@ -5,37 +5,39 @@ /** * Created by gouthamvidyapradhan on 12/03/2017. - Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. - - For example: - Given the following binary tree, - 1 <--- - / \ - 2 3 <--- - \ \ - 5 4 <--- - You should return [1, 3, 4]. + * Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. + *

+ * For example: + * Given the following binary tree, + * 1 <--- + * / \ + * 2 3 <--- + * \ \ + * 5 4 <--- + * You should return [1, 3, 4]. */ -public class BinarayTreeRightSideView -{ - public static class TreeNode - { +public class BinarayTreeRightSideView { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private int maxHeigh = Integer.MIN_VALUE; List list = new ArrayList<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(2); root.left = new TreeNode(3); root.right = new TreeNode(4); @@ -49,19 +51,15 @@ public static void main(String[] args) throws Exception List list = new BinarayTreeRightSideView().rightSideView(root); } - public List rightSideView(TreeNode root) - { - if(root == null) return list; + public List rightSideView(TreeNode root) { + if (root == null) return list; dfs(root, 0); return list; } - private void dfs(TreeNode node, int height) - { - if(node != null) - { - if(height > maxHeigh) - { + private void dfs(TreeNode node, int height) { + if (node != null) { + if (height > maxHeigh) { list.add(node.val); maxHeigh = height; } diff --git a/problems/src/tree/BinaryTreeInorderTraversal.java b/problems/src/tree/BinaryTreeInorderTraversal.java index f2314336..42aedb08 100644 --- a/problems/src/tree/BinaryTreeInorderTraversal.java +++ b/problems/src/tree/BinaryTreeInorderTraversal.java @@ -1,33 +1,36 @@ package tree; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; /** * Created by gouthamvidyapradhan on 06/08/2017. * Given a binary tree, return the inorder traversal of its nodes' values. - - For example: - Given binary tree [1,null,2,3], - 1 - \ - 2 - / - 3 - return [1,3,2]. - - Note: Recursive solution is trivial, could you do it iteratively? - - + *

+ * For example: + * Given binary tree [1,null,2,3], + * 1 + * \ + * 2 + * / + * 3 + * return [1,3,2]. + *

+ * Note: Recursive solution is trivial, could you do it iteratively? */ public class BinaryTreeInorderTraversal { public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(3); root.left = new TreeNode(4); root.left.left = new TreeNode(5); @@ -45,8 +48,8 @@ public List inorderTraversal(TreeNode root) { Stack stack = new Stack<>(); TreeNode curr = root; List result = new ArrayList<>(); - while(curr != null || !stack.isEmpty()){ - while(curr != null){ + while (curr != null || !stack.isEmpty()) { + while (curr != null) { stack.push(curr); curr = curr.left; } diff --git a/problems/src/tree/BinaryTreeMaximumPathSum.java b/problems/src/tree/BinaryTreeMaximumPathSum.java index 2180737a..c2d5ce30 100644 --- a/problems/src/tree/BinaryTreeMaximumPathSum.java +++ b/problems/src/tree/BinaryTreeMaximumPathSum.java @@ -2,35 +2,38 @@ /** * Created by gouthamvidyapradhan on 03/04/2017. - Given a binary tree, find the maximum path sum. - - For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root. - - For example: - Given the below binary tree, - - 1 - / \ - 2 3 - Return 6. + * Given a binary tree, find the maximum path sum. + *

+ * For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root. + *

+ * For example: + * Given the below binary tree, + *

+ * 1 + * / \ + * 2 3 + * Return 6. */ -public class BinaryTreeMaximumPathSum -{ +public class BinaryTreeMaximumPathSum { public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private int max = Integer.MIN_VALUE; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(5); root.left = new TreeNode(4); root.left.left = new TreeNode(3); @@ -40,16 +43,15 @@ public static void main(String[] args) throws Exception root.right.left.left = new TreeNode(9); System.out.println(new BinaryTreeMaximumPathSum().maxPathSum(root)); } - public int maxPathSum(TreeNode root) - { - if(root == null) return 0; + + public int maxPathSum(TreeNode root) { + if (root == null) return 0; dfs(root); return max; } - private int dfs(TreeNode root) - { - if(root == null) return 0; + private int dfs(TreeNode root) { + if (root == null) return 0; int left = dfs(root.left); int right = dfs(root.right); max = Math.max(max, root.val); diff --git a/problems/src/tree/BoundaryOfBinaryTree.java b/problems/src/tree/BoundaryOfBinaryTree.java index b219798b..a4a96f34 100644 --- a/problems/src/tree/BoundaryOfBinaryTree.java +++ b/problems/src/tree/BoundaryOfBinaryTree.java @@ -4,66 +4,69 @@ /** * Created by gouthamvidyapradhan on 27/03/2017. - Given a binary tree, return the values of its boundary in anti-clockwise direction starting from root. Boundary includes left boundary, leaves, and right boundary in order without duplicate nodes. - - Left boundary is defined as the path from root to the left-most node. Right boundary is defined as the path from root to the right-most node. If the root doesn't have left subtree or right subtree, then the root itself is left boundary or right boundary. Note this definition only applies to the input binary tree, and not applies to any subtrees. - - The left-most node is defined as a leaf node you could reach when you always firstly travel to the left subtree if exists. If not, travel to the right subtree. Repeat until you reach a leaf node. - - The right-most node is also defined by the same way with left and right exchanged. - - Example 1 - Input: - 1 - \ - 2 - / \ - 3 4 - - Ouput: - [1, 3, 4, 2] - - Explanation: - The root doesn't have left subtree, so the root itself is left boundary. - The leaves are node 3 and 4. - The right boundary are node 1,2,4. Note the anti-clockwise direction means you should output reversed right boundary. - So order them in anti-clockwise without duplicates and we have [1,3,4,2]. - Example 2 - Input: - ____1_____ - / \ - 2 3 - / \ / - 4 5 6 - / \ / \ - 7 8 9 10 - - Ouput: - [1,2,4,7,8,9,10,6,3] - - Explanation: - The left boundary are node 1,2,4. (4 is the left-most node according to definition) - The leaves are node 4,7,8,9,10. - The right boundary are node 1,3,6,10. (10 is the right-most node). - So order them in anti-clockwise without duplicate nodes we have [1,2,4,7,8,9,10,6,3]. + * Given a binary tree, return the values of its boundary in anti-clockwise direction starting from root. Boundary includes left boundary, leaves, and right boundary in order without duplicate nodes. + *

+ * Left boundary is defined as the path from root to the left-most node. Right boundary is defined as the path from root to the right-most node. If the root doesn't have left subtree or right subtree, then the root itself is left boundary or right boundary. Note this definition only applies to the input binary tree, and not applies to any subtrees. + *

+ * The left-most node is defined as a leaf node you could reach when you always firstly travel to the left subtree if exists. If not, travel to the right subtree. Repeat until you reach a leaf node. + *

+ * The right-most node is also defined by the same way with left and right exchanged. + *

+ * Example 1 + * Input: + * 1 + * \ + * 2 + * / \ + * 3 4 + *

+ * Ouput: + * [1, 3, 4, 2] + *

+ * Explanation: + * The root doesn't have left subtree, so the root itself is left boundary. + * The leaves are node 3 and 4. + * The right boundary are node 1,2,4. Note the anti-clockwise direction means you should output reversed right boundary. + * So order them in anti-clockwise without duplicates and we have [1,3,4,2]. + * Example 2 + * Input: + * ____1_____ + * / \ + * 2 3 + * / \ / + * 4 5 6 + * / \ / \ + * 7 8 9 10 + *

+ * Ouput: + * [1,2,4,7,8,9,10,6,3] + *

+ * Explanation: + * The left boundary are node 1,2,4. (4 is the left-most node according to definition) + * The leaves are node 4,7,8,9,10. + * The right boundary are node 1,3,6,10. (10 is the right-most node). + * So order them in anti-clockwise without duplicate nodes we have [1,2,4,7,8,9,10,6,3]. */ -public class BoundaryOfBinaryTree -{ +public class BoundaryOfBinaryTree { public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private Set done = new HashSet<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(1); /*root.right = new TreeNode(2); root.right.right = new TreeNode(3); @@ -82,18 +85,15 @@ public static void main(String[] args) throws Exception System.out.println(new BoundaryOfBinaryTree().boundaryOfBinaryTree(root)); } - public List boundaryOfBinaryTree(TreeNode root) - { - if(root == null) return new ArrayList<>(); + public List boundaryOfBinaryTree(TreeNode root) { + if (root == null) return new ArrayList<>(); List antiClockwiseCollection = new ArrayList<>(); List collection = new ArrayList<>(); - if(root.left != null) + if (root.left != null) leftShoulder(root, collection); - else - { - if(!done.contains(root)) - { + else { + if (!done.contains(root)) { done.add(root); collection.add(root.val); } @@ -105,12 +105,10 @@ public List boundaryOfBinaryTree(TreeNode root) antiClockwiseCollection.addAll(collection); collection.clear(); - if(root.right != null) + if (root.right != null) rightShoulder(root, collection); - else - { - if(!done.contains(root)) - { + else { + if (!done.contains(root)) { done.add(root); collection.add(root.val); } @@ -118,42 +116,36 @@ public List boundaryOfBinaryTree(TreeNode root) Stack stack = new Stack<>(); stack.addAll(collection); - while(!stack.isEmpty()) + while (!stack.isEmpty()) antiClockwiseCollection.add(stack.pop()); return new ArrayList<>(antiClockwiseCollection); } - private void leftShoulder(TreeNode node, List list) - { - if(node == null) return; - if(!done.contains(node)) - { + private void leftShoulder(TreeNode node, List list) { + if (node == null) return; + if (!done.contains(node)) { list.add(node.val); done.add(node); } - if(node.left != null) leftShoulder(node.left, list); - else if(node.right != null) leftShoulder(node.right, list); + if (node.left != null) leftShoulder(node.left, list); + else if (node.right != null) leftShoulder(node.right, list); } - private void rightShoulder(TreeNode node, List list) - { - if(node == null) return; - if(!done.contains(node)) - { + private void rightShoulder(TreeNode node, List list) { + if (node == null) return; + if (!done.contains(node)) { list.add(node.val); done.add(node); } - if(node.right != null) rightShoulder(node.right, list); - else if(node.left != null) rightShoulder(node.left, list); + if (node.right != null) rightShoulder(node.right, list); + else if (node.left != null) rightShoulder(node.left, list); } - private void leafNode(TreeNode node, List list) - { - if(node == null) return; - if(node.left == null && node.right == null) - if(!done.contains(node)) - { + private void leafNode(TreeNode node, List list) { + if (node == null) return; + if (node.left == null && node.right == null) + if (!done.contains(node)) { list.add(node.val); done.add(node); } diff --git a/problems/src/tree/ClosestBinarySearchTreeValue.java b/problems/src/tree/ClosestBinarySearchTreeValue.java index 3576b231..b64113fa 100644 --- a/problems/src/tree/ClosestBinarySearchTreeValue.java +++ b/problems/src/tree/ClosestBinarySearchTreeValue.java @@ -3,25 +3,26 @@ /** * Created by gouthamvidyapradhan on 10/05/2017. * Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target. - - Note: - Given target value is a floating point. - You are guaranteed to have only one unique value in the BST that is closest to the target. - - Solution: Simple dfs recursive algorithm to find the closest match. - Worst case time complexity is O(h) where h is height of the tree + *

+ * Note: + * Given target value is a floating point. + * You are guaranteed to have only one unique value in the BST that is closest to the target. + *

+ * Solution: Simple dfs recursive algorithm to find the closest match. + * Worst case time complexity is O(h) where h is height of the tree */ -public class ClosestBinarySearchTreeValue -{ +public class ClosestBinarySearchTreeValue { /** * TreeNode */ - public static class TreeNode - { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private double absDiff = Double.MAX_VALUE; @@ -29,11 +30,11 @@ public static class TreeNode /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(10); root.left = new TreeNode(9); root.left.left = new TreeNode(8); @@ -42,19 +43,18 @@ public static void main(String[] args) throws Exception /** * Find closest - * @param root Root node + * + * @param root Root node * @param target double target * @return closest value */ - public int closestValue(TreeNode root, double target) - { - if(root == null) return closest; - if(Math.abs(target - root.val) < absDiff) - { + public int closestValue(TreeNode root, double target) { + if (root == null) return closest; + if (Math.abs(target - root.val) < absDiff) { absDiff = Math.abs(target - root.val); closest = root.val; } - if(root.val > target) + if (root.val > target) return closestValue(root.left, target); else return closestValue(root.right, target); } diff --git a/problems/src/tree/ConstructStringFromBinaryTree.java b/problems/src/tree/ConstructStringFromBinaryTree.java index c83708f3..d390eb03 100644 --- a/problems/src/tree/ConstructStringFromBinaryTree.java +++ b/problems/src/tree/ConstructStringFromBinaryTree.java @@ -3,52 +3,54 @@ /** * Created by gouthamvidyapradhan on 10/06/2017. * Accepted - You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way. - - The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree. - - Example 1: - Input: Binary tree: [1,2,3,4] - 1 - / \ - 2 3 - / - 4 - - Output: "1(2(4))(3)" - - Explanation: Originallay it needs to be "1(2(4)())(3()())", - but you need to omit all the unnecessary empty parenthesis pairs. - And it will be "1(2(4))(3)". - Example 2: - Input: Binary tree: [1,2,3,null,4] - 1 - / \ - 2 3 - \ - 4 - - Output: "1(2()(4))(3)" - - Explanation: Almost the same as the first example, - except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output. + * You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way. + *

+ * The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree. + *

+ * Example 1: + * Input: Binary tree: [1,2,3,4] + * 1 + * / \ + * 2 3 + * / + * 4 + *

+ * Output: "1(2(4))(3)" + *

+ * Explanation: Originallay it needs to be "1(2(4)())(3()())", + * but you need to omit all the unnecessary empty parenthesis pairs. + * And it will be "1(2(4))(3)". + * Example 2: + * Input: Binary tree: [1,2,3,null,4] + * 1 + * / \ + * 2 3 + * \ + * 4 + *

+ * Output: "1(2()(4))(3)" + *

+ * Explanation: Almost the same as the first example, + * except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output. */ -public class ConstructStringFromBinaryTree -{ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } +public class ConstructStringFromBinaryTree { + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode t = new TreeNode(1); t.left = new TreeNode(2); t.left.left = new TreeNode(4); @@ -56,17 +58,16 @@ public static void main(String[] args) throws Exception System.out.println(new ConstructStringFromBinaryTree().tree2str(t)); } - public String tree2str(TreeNode t) - { - if(t == null) return ""; + public String tree2str(TreeNode t) { + if (t == null) return ""; String left = tree2str(t.left); String right = tree2str(t.right); - if(left.equals("") && right.equals("")) + if (left.equals("") && right.equals("")) return String.valueOf(t.val); - if(left.equals("")) + if (left.equals("")) left = "()"; else left = "(" + left + ")"; - if(!right.equals("")) + if (!right.equals("")) right = "(" + right + ")"; return t.val + left + right; } diff --git a/problems/src/tree/ConvertSortedArrayToBST.java b/problems/src/tree/ConvertSortedArrayToBST.java index 4690acec..5c9f7bbe 100644 --- a/problems/src/tree/ConvertSortedArrayToBST.java +++ b/problems/src/tree/ConvertSortedArrayToBST.java @@ -2,32 +2,31 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + * Given an array where elements are sorted in ascending order, convert it to a height balanced BST. */ -public class ConvertSortedArrayToBST -{ - public class TreeNode - { +public class ConvertSortedArrayToBST { + public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public TreeNode sortedArrayToBST(int[] nums) - { - if(nums.length == 0) return null; + public TreeNode sortedArrayToBST(int[] nums) { + if (nums.length == 0) return null; return build(0, nums.length - 1, nums); } - private TreeNode build(int s, int e, int[] nums) - { - if(s > e) return null; + private TreeNode build(int s, int e, int[] nums) { + if (s > e) return null; int m = (e - s) / 2; int node = nums[s + m]; TreeNode root = new TreeNode(node); - if(s == e) + if (s == e) return root; root.left = build(s, s + m - 1, nums); diff --git a/problems/src/tree/FindBottomLeftTreeValue.java b/problems/src/tree/FindBottomLeftTreeValue.java index 83509ee5..0624e351 100644 --- a/problems/src/tree/FindBottomLeftTreeValue.java +++ b/problems/src/tree/FindBottomLeftTreeValue.java @@ -3,43 +3,45 @@ /** * Created by gouthamvidyapradhan on 30/08/2017. * Given a binary tree, find the leftmost value in the last row of the tree. - - Example 1: - Input: - - 2 - / \ - 1 3 - - Output: - 1 - Example 2: - Input: - - 1 - / \ - 2 3 - / / \ - 4 5 6 - / - 7 - - Output: - 7 - Note: You may assume the tree (i.e., the given root node) is not NULL. - - + *

+ * Example 1: + * Input: + *

+ * 2 + * / \ + * 1 3 + *

+ * Output: + * 1 + * Example 2: + * Input: + *

+ * 1 + * / \ + * 2 3 + * / / \ + * 4 5 6 + * / + * 7 + *

+ * Output: + * 7 + * Note: You may assume the tree (i.e., the given root node) is not NULL. */ public class FindBottomLeftTreeValue { private int max = 0, result; + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(1); root.left = new TreeNode(2); root.left.left = new TreeNode(4); @@ -55,9 +57,9 @@ public int findBottomLeftValue(TreeNode root) { return result; } - private void preorder(TreeNode node, int level){ - if(node != null){ - if(level > max){ + private void preorder(TreeNode node, int level) { + if (node != null) { + if (level > max) { result = node.val; max = level; } diff --git a/problems/src/tree/FlattenBinaryTree.java b/problems/src/tree/FlattenBinaryTree.java index b4b06ffb..65024e51 100644 --- a/problems/src/tree/FlattenBinaryTree.java +++ b/problems/src/tree/FlattenBinaryTree.java @@ -1,63 +1,67 @@ package tree; + /** * Created by gouthamvidyapradhan on 04/07/2017. * Given a binary tree, flatten it to a linked list in-place. - - For example, - Given - - 1 - / \ - 2 5 - / \ \ - 3 4 6 - - The flattened tree should look like: - 1 - \ - 2 - \ - 3 - \ - 4 - \ - 5 - \ - 6 - - Solution: Do a pre-order traversal and maintain head and tail of a linked list at each recursive step. - i. Join the current node to the head of the left sub-list to form the current node as the new head. - ii. Join the tail of the left sub-list to the head of the right sub-list. - iii. Mark the left of the current node as null + *

+ * For example, + * Given + *

+ * 1 + * / \ + * 2 5 + * / \ \ + * 3 4 6 + *

+ * The flattened tree should look like: + * 1 + * \ + * 2 + * \ + * 3 + * \ + * 4 + * \ + * 5 + * \ + * 6 + *

+ * Solution: Do a pre-order traversal and maintain head and tail of a linked list at each recursive step. + * i. Join the current node to the head of the left sub-list to form the current node as the new head. + * ii. Join the tail of the left sub-list to the head of the right sub-list. + * iii. Mark the left of the current node as null */ public class FlattenBinaryTree { /** * Class to keep track of head and tail */ - private class LinkNode{ + private class LinkNode { TreeNode head; TreeNode tail; - LinkNode(TreeNode head, TreeNode tail){ + + LinkNode(TreeNode head, TreeNode tail) { this.head = head; this.tail = tail; } } - public static class TreeNode - { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(3); root.left = new TreeNode(2); root.right = new TreeNode(1); new FlattenBinaryTree().flatten(root); - System.out.print(root.val+ " "); + System.out.print(root.val + " "); System.out.print(root.right.val + " "); System.out.print(root.right.right.val); } @@ -66,23 +70,20 @@ public void flatten(TreeNode root) { preOrder(root); } - private LinkNode preOrder(TreeNode node){ - if(node == null) return null; + private LinkNode preOrder(TreeNode node) { + if (node == null) return null; LinkNode left = preOrder(node.left); LinkNode right = preOrder(node.right); LinkNode lNode; - if(left == null && right == null){ + if (left == null && right == null) { lNode = new LinkNode(node, node); - } - else if(left == null){ + } else if (left == null) { node.right = right.head; lNode = new LinkNode(node, right.tail); - } - else if(right == null){ + } else if (right == null) { node.right = left.head; lNode = new LinkNode(node, left.tail); - } - else { + } else { node.right = left.head; left.tail.right = right.head; lNode = new LinkNode(node, right.tail); diff --git a/problems/src/tree/InorderSuccessorInBST.java b/problems/src/tree/InorderSuccessorInBST.java index 6f214dc8..79399792 100644 --- a/problems/src/tree/InorderSuccessorInBST.java +++ b/problems/src/tree/InorderSuccessorInBST.java @@ -2,31 +2,32 @@ /** * Created by gouthamvidyapradhan on 14/05/2017. - Given a binary search tree and a node in it, find the in-order successor of that node in the BST. - - Note: If the given node has no in-order successor in the tree, return null. - - Solution: The below solution works with worst case time complexity of O(h) where h is the height of the tree. - If the current node is <= target_node, recursively iterate the right of the current node. - else if the current node is > target_node then mark the current node as the successor and recursively iterate the left of the current node. + * Given a binary search tree and a node in it, find the in-order successor of that node in the BST. + *

+ * Note: If the given node has no in-order successor in the tree, return null. + *

+ * Solution: The below solution works with worst case time complexity of O(h) where h is the height of the tree. + * If the current node is <= target_node, recursively iterate the right of the current node. + * else if the current node is > target_node then mark the current node as the successor and recursively iterate the left of the current node. */ -public class InorderSuccessorInBST -{ - public static class TreeNode - { +public class InorderSuccessorInBST { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(10); root.left = new TreeNode(5); root.left.left = new TreeNode(3); @@ -37,33 +38,33 @@ public static void main(String[] args) throws Exception root.right.left.right = new TreeNode(14); root.right.right = new TreeNode(17); TreeNode ans = new InorderSuccessorInBST().inorderSuccessor(root, root.right.left.right); - if(ans != null) + if (ans != null) System.out.println(ans.val); else System.out.println(ans); } /** * Find successor + * * @param root root node - * @param p target + * @param p target * @return successor */ - public TreeNode inorderSuccessor(TreeNode root, TreeNode p) - { + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { return inOrder(root, p, null); } /** * Inorder traversal - * @param curr current node - * @param target target node + * + * @param curr current node + * @param target target node * @param successor successor * @return successor node */ - private TreeNode inOrder(TreeNode curr, TreeNode target, TreeNode successor) - { - if(curr == null) return successor; - if(curr.val <= target.val) + private TreeNode inOrder(TreeNode curr, TreeNode target, TreeNode successor) { + if (curr == null) return successor; + if (curr.val <= target.val) return inOrder(curr.right, target, successor); return inOrder(curr.left, target, curr); //make the current node as successor } diff --git a/problems/src/tree/LCA.java b/problems/src/tree/LCA.java index 9cfd76b5..c34799f9 100644 --- a/problems/src/tree/LCA.java +++ b/problems/src/tree/LCA.java @@ -2,47 +2,47 @@ /** * Created by gouthamvidyapradhan on 21/03/2017. - Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. - - According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” - - _______3______ - / \ - ___5__ ___1__ - / \ / \ - 6 _2 0 8 - / \ - 7 4 - For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition. + * Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. + *

+ * According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” + *

+ * _______3______ + * / \ + * ___5__ ___1__ + * / \ / \ + * 6 _2 0 8 + * / \ + * 7 4 + * For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition. */ -public class LCA -{ +public class LCA { public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } - } + + TreeNode(int x) { + val = x; + } + } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) - { - if(root != null) - { - if(root.equals(p) || root.equals(q)) return root; + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root != null) { + if (root.equals(p) || root.equals(q)) return root; TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); - if(left != null && right != null) return root; - else if(left != null) return left; + if (left != null && right != null) return root; + else if (left != null) return left; else return right; } return null; diff --git a/problems/src/tree/LargestBSTSubtree.java b/problems/src/tree/LargestBSTSubtree.java index 69b18bfe..43c6dfe8 100644 --- a/problems/src/tree/LargestBSTSubtree.java +++ b/problems/src/tree/LargestBSTSubtree.java @@ -2,37 +2,34 @@ /** * Created by gouthamvidyapradhan on 08/05/2017. - * + *

* Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it. - - Note: - A subtree must include all of its descendants. - Here's an example: - 10 - / \ - 5 15 - / \ \ - 1 8 7 - The Largest BST Subtree in this case is the highlighted one (5-1-8). - The return value is the subtree's size, which is 3. - - Follow up: - Can you figure out ways to solve it with O(n) time complexity? - - Solution: The below solution works with O(n). Validate the BST property from the leaf node and increment the count, as soon as a violation - of BST property is found terminate the count. - * + *

+ * Note: + * A subtree must include all of its descendants. + * Here's an example: + * 10 + * / \ + * 5 15 + * / \ \ + * 1 8 7 + * The Largest BST Subtree in this case is the highlighted one (5-1-8). + * The return value is the subtree's size, which is 3. + *

+ * Follow up: + * Can you figure out ways to solve it with O(n) time complexity? + *

+ * Solution: The below solution works with O(n). Validate the BST property from the leaf node and increment the count, as soon as a violation + * of BST property is found terminate the count. */ -public class LargestBSTSubtree -{ +public class LargestBSTSubtree { /** * Range class */ - private class Range - { + private class Range { int min, max, count; - Range(int min, int max, int count) - { + + Range(int min, int max, int count) { this.min = min; this.max = max; this.count = count; @@ -42,12 +39,14 @@ private class Range /** * TreeNode */ - public static class TreeNode - { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** @@ -57,11 +56,11 @@ public static class TreeNode /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(10); root.left = new TreeNode(9); root.left.left = new TreeNode(8); @@ -70,54 +69,48 @@ public static void main(String[] args) throws Exception /** * Largest subtree count + * * @param root root node * @return count */ - public int largestBSTSubtree(TreeNode root) - { + public int largestBSTSubtree(TreeNode root) { getCount(root); return count; } /** * Get count + * * @param node root node * @return Range */ - private Range getCount(TreeNode node) - { - if(node == null) return null; + private Range getCount(TreeNode node) { + if (node == null) return null; Range left = getCount(node.left); Range right = getCount(node.right); - if(left == null && right == null) - { + if (left == null && right == null) { count = Math.max(count, 1); return new Range(node.val, node.val, 1); - } - else if(left == null) - { - if(node.val < right.min && right.count != -1) //check for -1 ensures that there is no violation of BST property + } else if (left == null) { + if (node.val < right.min && right.count != -1) //check for -1 ensures that there is no violation of BST property return countMaxAndBuildNewRange(right.count + 1, node.val, right.max); - } - else if(right == null) - { - if(node.val > left.max && left.count != -1) + } else if (right == null) { + if (node.val > left.max && left.count != -1) return countMaxAndBuildNewRange(left.count + 1, left.min, node.val); - } - else if(node.val > left.max && node.val < right.min && right.count != -1 && left.count != -1) + } else if (node.val > left.max && node.val < right.min && right.count != -1 && left.count != -1) return countMaxAndBuildNewRange(left.count + right.count + 1, left.min, right.max); return new Range(0, 0, -1); //violation of BST property } /** * Record max and build new range + * * @param sum total sum * @param min min * @param max max * @return new Range */ - private Range countMaxAndBuildNewRange(int sum, int min, int max) - { + private Range countMaxAndBuildNewRange(int sum, int min, int max) { count = Math.max(count, sum); return new Range(min, max, sum); } diff --git a/problems/src/tree/LowestCommonAncestorBST.java b/problems/src/tree/LowestCommonAncestorBST.java index 3ba76954..d8e9091c 100644 --- a/problems/src/tree/LowestCommonAncestorBST.java +++ b/problems/src/tree/LowestCommonAncestorBST.java @@ -2,45 +2,44 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. - - According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” - - _______6______ - / \ - ___2__ ___8__ - / \ / \ - 0 _4 7 9 - / \ - 3 5 - For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. + * Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. + *

+ * According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” + *

+ * _______6______ + * / \ + * ___2__ ___8__ + * / \ / \ + * 0 _4 7 9 + * / \ + * 3 5 + * For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. */ -public class LowestCommonAncestorBST -{ - class TreeNode - { +public class LowestCommonAncestorBST { + class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { } - private TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) - { - if(root == null) return null; + private TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) return null; - if(p.val == root.val || q.val == root.val) return root; + if (p.val == root.val || q.val == root.val) return root; - else if((p.val < root.val && q.val > root.val) || (q.val < root.val && p.val > root.val)) + else if ((p.val < root.val && q.val > root.val) || (q.val < root.val && p.val > root.val)) return root; - else if(p.val < root.val && q.val < root.val) + else if (p.val < root.val && q.val < root.val) return lowestCommonAncestor(root.left, p, q); else diff --git a/problems/src/tree/MaximumBinaryTree.java b/problems/src/tree/MaximumBinaryTree.java index 8af8cc6f..4af5a666 100644 --- a/problems/src/tree/MaximumBinaryTree.java +++ b/problems/src/tree/MaximumBinaryTree.java @@ -3,27 +3,26 @@ /** * Created by gouthamvidyapradhan on 19/08/2017. * Given an integer array with no duplicates. A maximum tree building on this array is defined as follow: - - The root is the maximum number in the array. - The left subtree is the maximum tree constructed from left part subarray divided by the maximum number. - The right subtree is the maximum tree constructed from right part subarray divided by the maximum number. - Construct the maximum tree by the given array and output the root node of this tree. - - Example 1: - Input: [3,2,1,6,0,5] - Output: return the tree root node representing the following tree: - - 6 - / \ - 3 5 - \ / - 2 0 - \ - 1 - - Note: - The size of the given array will be in the range [1,1000]. - + *

+ * The root is the maximum number in the array. + * The left subtree is the maximum tree constructed from left part subarray divided by the maximum number. + * The right subtree is the maximum tree constructed from right part subarray divided by the maximum number. + * Construct the maximum tree by the given array and output the root node of this tree. + *

+ * Example 1: + * Input: [3,2,1,6,0,5] + * Output: return the tree root node representing the following tree: + *

+ * 6 + * / \ + * 3 5 + * \ / + * 2 0 + * \ + * 1 + *

+ * Note: + * The size of the given array will be in the range [1,1000]. */ public class MaximumBinaryTree { @@ -31,17 +30,22 @@ public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private int[][] max; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ - int[] nums = {3,2,1,6,0,5}; + public static void main(String[] args) throws Exception { + int[] nums = {3, 2, 1, 6, 0, 5}; TreeNode root = new MaximumBinaryTree().constructMaximumBinaryTree(nums); System.out.println(root.val); //print root } @@ -51,22 +55,22 @@ public TreeNode constructMaximumBinaryTree(int[] nums) { max = new int[nums.length][nums.length]; //pre-fill with initial values - for(int i = 0; i < nums.length; i ++){ + for (int i = 0; i < nums.length; i++) { max[i][i] = i; } //pre-calculate max for range index - for(int i = 0; i < nums.length; i ++){ - for(int j = i + 1; j < nums.length; j++){ - max[i][j] = nums[max[i][j - 1]] > nums[j] ? max[i][j - 1] : j; + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + max[i][j] = nums[max[i][j - 1]] > nums[j] ? max[i][j - 1] : j; } } return build(0, nums.length - 1, nums); } - private TreeNode build(int s, int e, int[] nums){ - if(s <= e){ + private TreeNode build(int s, int e, int[] nums) { + if (s <= e) { int val = nums[max[s][e]]; TreeNode n = new TreeNode(val); n.left = build(s, max[s][e] - 1, nums); diff --git a/problems/src/tree/MostFrequentSubtreeSum.java b/problems/src/tree/MostFrequentSubtreeSum.java index b68f3a0f..aa8a2250 100644 --- a/problems/src/tree/MostFrequentSubtreeSum.java +++ b/problems/src/tree/MostFrequentSubtreeSum.java @@ -7,43 +7,45 @@ /** * Created by gouthamvidyapradhan on 27/03/2017. - Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order. - - Examples 1 - Input: - - 5 - / \ - 2 -3 - return [2, -3, 4], since all the values happen only once, return all of them in any order. - Examples 2 - Input: - - 5 - / \ - 2 -5 - return [2], since 2 happens twice, however -5 only occur once. - Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer. + * Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order. + *

+ * Examples 1 + * Input: + *

+ * 5 + * / \ + * 2 -3 + * return [2, -3, 4], since all the values happen only once, return all of them in any order. + * Examples 2 + * Input: + *

+ * 5 + * / \ + * 2 -5 + * return [2], since 2 happens twice, however -5 only occur once. + * Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer. */ -public class MostFrequentSubtreeSum -{ - static class TreeNode - { +public class MostFrequentSubtreeSum { + static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private Map> fList = new HashMap<>(); private Map fCount = new HashMap<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { MostFrequentSubtreeSum mfs = new MostFrequentSubtreeSum(); TreeNode node = new TreeNode(5); //node.left = new TreeNode(2); @@ -51,37 +53,34 @@ public static void main(String[] args) throws Exception int[] result = mfs.findFrequentTreeSum(node); } - public int[] findFrequentTreeSum(TreeNode root) - { + public int[] findFrequentTreeSum(TreeNode root) { int[] resArr = new int[0]; - if(root == null) return resArr; + if (root == null) return resArr; postOrder(root); - for (Map.Entry entry : fCount.entrySet()) - { + for (Map.Entry entry : fCount.entrySet()) { int frequency = entry.getValue(); List list = fList.get(frequency); - if(list == null) + if (list == null) list = new ArrayList<>(); list.add(entry.getKey()); fList.put(frequency, list); } int max = Integer.MIN_VALUE; List result; - for(int key : fList.keySet()) + for (int key : fList.keySet()) max = Math.max(max, key); result = fList.get(max); resArr = new int[result.size()]; - for(int i = 0, l = resArr.length; i < l; i ++) + for (int i = 0, l = resArr.length; i < l; i++) resArr[i] = result.get(i); return resArr; } - private int postOrder(TreeNode root) - { - if(root == null) return 0; + private int postOrder(TreeNode root) { + if (root == null) return 0; int sum = postOrder(root.left) + postOrder(root.right) + root.val; Integer fSum = fCount.get(sum); - if(fSum == null) + if (fSum == null) fCount.put(sum, 1); else fCount.put(sum, fSum + 1); return sum; diff --git a/problems/src/tree/NextRightPointer.java b/problems/src/tree/NextRightPointer.java index 2c73016d..5f12415f 100644 --- a/problems/src/tree/NextRightPointer.java +++ b/problems/src/tree/NextRightPointer.java @@ -1,46 +1,49 @@ package tree; -import java.util.*; + +import java.util.ArrayDeque; +import java.util.Queue; /** * Created by gouthamvidyapradhan on 07/07/2017. - * - Given a binary tree - - struct TreeLinkNode { - TreeLinkNode *left; - TreeLinkNode *right; - TreeLinkNode *next; - } - Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. - - Initially, all next pointers are set to NULL. - - Note: - - You may only use constant extra space. - You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). - For example, - Given the following perfect binary tree, - 1 - / \ - 2 3 - / \ / \ - 4 5 6 7 - After calling your function, the tree should look like: - 1 -> NULL - / \ - 2 -> 3 -> NULL - / \ / \ - 4->5->6->7 -> NULL - -Solution: Perform a level order traversal using BFS, keep track of prev node at each level. Link the prev node to - current node if both the nodes are in the same level. + *

+ * Given a binary tree + *

+ * struct TreeLinkNode { + * TreeLinkNode *left; + * TreeLinkNode *right; + * TreeLinkNode *next; + * } + * Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. + *

+ * Initially, all next pointers are set to NULL. + *

+ * Note: + *

+ * You may only use constant extra space. + * You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). + * For example, + * Given the following perfect binary tree, + * 1 + * / \ + * 2 3 + * / \ / \ + * 4 5 6 7 + * After calling your function, the tree should look like: + * 1 -> NULL + * / \ + * 2 -> 3 -> NULL + * / \ / \ + * 4->5->6->7 -> NULL + *

+ * Solution: Perform a level order traversal using BFS, keep track of prev node at each level. Link the prev node to + * current node if both the nodes are in the same level. */ public class NextRightPointer { - private class LevelNode{ + private class LevelNode { int level; TreeLinkNode node; - LevelNode(TreeLinkNode node, int level){ + + LevelNode(TreeLinkNode node, int level) { this.node = node; this.level = level; } @@ -49,10 +52,13 @@ private class LevelNode{ public static class TreeLinkNode { int val; TreeLinkNode left, right, next; - TreeLinkNode(int x) { val = x; } + + TreeLinkNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeLinkNode node = new TreeLinkNode(2); node.left = new TreeLinkNode(1); node.right = new TreeLinkNode(3); @@ -67,12 +73,12 @@ public void connect(TreeLinkNode root) { LevelNode zero = new LevelNode(root, 0); queue.offer(zero); LevelNode prev = null; - while(!queue.isEmpty()){ + while (!queue.isEmpty()) { LevelNode levelNode = queue.poll(); - if(levelNode.node == null) break; + if (levelNode.node == null) break; TreeLinkNode curr = levelNode.node; - if(prev != null){ - if(prev.level == levelNode.level){ + if (prev != null) { + if (prev.level == levelNode.level) { prev.node.next = levelNode.node; } } diff --git a/problems/src/tree/PathSumIII.java b/problems/src/tree/PathSumIII.java index 455579bb..c1c7c870 100644 --- a/problems/src/tree/PathSumIII.java +++ b/problems/src/tree/PathSumIII.java @@ -5,68 +5,65 @@ /** * Created by gouthamvidyapradhan on 08/04/2017. - You are given a binary tree in which each node contains an integer value. - - Find the number of paths that sum to a given value. - - The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes). - - The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. - - Example: - - root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 - - 10 - / \ - 5 -3 - / \ \ - 3 2 11 - / \ \ - 3 -2 1 - - Return 3. The paths that sum to 8 are: - - 1. 5 -> 3 - 2. 5 -> 2 -> 1 - 3. -3 -> 11 + * You are given a binary tree in which each node contains an integer value. + *

+ * Find the number of paths that sum to a given value. + *

+ * The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes). + *

+ * The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. + *

+ * Example: + *

+ * root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 + *

+ * 10 + * / \ + * 5 -3 + * / \ \ + * 3 2 11 + * / \ \ + * 3 -2 1 + *

+ * Return 3. The paths that sum to 8 are: + *

+ * 1. 5 -> 3 + * 2. 5 -> 2 -> 1 + * 3. -3 -> 11 */ -public class PathSumIII -{ +public class PathSumIII { /** * */ - public static class TreeNode - { + public static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } private Map pathCount = new HashMap<>(); private int totalCount; - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode node = new TreeNode(1); System.out.println(new PathSumIII().pathSum(node, 0)); } - public int pathSum(TreeNode root, int sum) - { - if(root == null) return 0; + public int pathSum(TreeNode root, int sum) { + if (root == null) return 0; dfs(root, sum, 0); return totalCount; } - private void dfs(TreeNode root, int target, int pSum) - { - if(root != null) - { + private void dfs(TreeNode root, int target, int pSum) { + if (root != null) { pSum += root.val; - if(pSum == target) totalCount++; + if (pSum == target) totalCount++; totalCount += pathCount.getOrDefault(pSum - target, 0); pathCount.put(pSum, pathCount.getOrDefault(pSum, 0) + 1); dfs(root.left, target, pSum); diff --git a/problems/src/tree/PostorderToBT.java b/problems/src/tree/PostorderToBT.java index 8a36f0df..bb724d88 100644 --- a/problems/src/tree/PostorderToBT.java +++ b/problems/src/tree/PostorderToBT.java @@ -5,13 +5,12 @@ /** * Created by gouthamvidyapradhan on 23/02/2017. - Given inorder and postorder traversal of a tree, construct the binary tree. - - Note: - You may assume that duplicates do not exist in the tree. + * Given inorder and postorder traversal of a tree, construct the binary tree. + *

+ * Note: + * You may assume that duplicates do not exist in the tree. */ -public class PostorderToBT -{ +public class PostorderToBT { private Map INDEX = new HashMap<>(); private static int postIndex; @@ -20,45 +19,43 @@ public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int in[] = new int[]{1, 2}; int post[] = new int[]{1, 2}; TreeNode root = new PostorderToBT().buildTree(in, post); new PostorderToBT().preorderPrint(root); } - public TreeNode buildTree(int[] inorder, int[] postorder) - { + public TreeNode buildTree(int[] inorder, int[] postorder) { int count = 0; - for(int i : inorder) + for (int i : inorder) INDEX.put(i, count++); postIndex = postorder.length - 1; return build(0, inorder.length - 1, postorder); } - private void preorderPrint(TreeNode root) - { - if(root != null) - { + private void preorderPrint(TreeNode root) { + if (root != null) { System.out.print(root.val + " "); preorderPrint(root.left); preorderPrint(root.right); } } - private TreeNode build(int s, int e, int[] postorder) - { - if(postIndex >= 0 && s <= e) - { + private TreeNode build(int s, int e, int[] postorder) { + if (postIndex >= 0 && s <= e) { int poi = postorder[postIndex]; int ini = INDEX.get(poi); @@ -66,7 +63,7 @@ private TreeNode build(int s, int e, int[] postorder) TreeNode node = new TreeNode(poi); postIndex--; - if(s == e) + if (s == e) return node; //leaf node node.right = build(ini + 1, e, postorder); diff --git a/problems/src/tree/PreorderToBT.java b/problems/src/tree/PreorderToBT.java index fd2992ca..5982da4e 100644 --- a/problems/src/tree/PreorderToBT.java +++ b/problems/src/tree/PreorderToBT.java @@ -5,51 +5,52 @@ /** * Created by gouthamvidyapradhan on 25/02/2017. - Given preorder and inorder traversal of a tree, construct the binary tree. - - Note: - You may assume that duplicates do not exist in the tree. + * Given preorder and inorder traversal of a tree, construct the binary tree. + *

+ * Note: + * You may assume that duplicates do not exist in the tree. */ -public class PreorderToBT -{ +public class PreorderToBT { public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } Map MAP = new HashMap<>(); private int index = 0, totalLen = 0; + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] perorder = {7,-10,-4,3,-1,2,-8,11}; - int[] inorder = {-4,-10,3,-1,7,11,-8,2}; + public static void main(String[] args) throws Exception { + int[] perorder = {7, -10, -4, 3, -1, 2, -8, 11}; + int[] inorder = {-4, -10, 3, -1, 7, 11, -8, 2}; new PreorderToBT().buildTree(perorder, inorder); } - public TreeNode buildTree(int[] preorder, int[] inorder) - { - for(int i = 0, l = inorder.length; i < l; i ++) + public TreeNode buildTree(int[] preorder, int[] inorder) { + for (int i = 0, l = inorder.length; i < l; i++) MAP.put(inorder[i], i); totalLen = preorder.length; return build(preorder, 0, inorder.length - 1); } - private TreeNode build(int[] preorder, int s, int e) - { + private TreeNode build(int[] preorder, int s, int e) { if (s > e || index >= totalLen) return null; int n = preorder[index++]; int pos = MAP.get(n); TreeNode node = new TreeNode(n); - if(s == e) return node; + if (s == e) return node; node.left = build(preorder, s, pos - 1); node.right = build(preorder, pos + 1, e); diff --git a/problems/src/tree/SortedArrayToBST.java b/problems/src/tree/SortedArrayToBST.java index c89d6ef1..18eb0b6f 100644 --- a/problems/src/tree/SortedArrayToBST.java +++ b/problems/src/tree/SortedArrayToBST.java @@ -2,56 +2,54 @@ /** * Created by gouthamvidyapradhan on 25/02/2017. - Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + * Given an array where elements are sorted in ascending order, convert it to a height balanced BST. */ -public class SortedArrayToBST -{ +public class SortedArrayToBST { public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] A = {1, 2, 3, 4, 5, 6}; new SortedArrayToBST().sortedArrayToBST(A); } - public TreeNode sortedArrayToBST(int[] nums) - { - if(nums.length == 0) return null; + public TreeNode sortedArrayToBST(int[] nums) { + if (nums.length == 0) return null; TreeNode root = new SortedArrayToBST().build(0, nums.length - 1, nums); preorder(root); return root; } - private void preorder(TreeNode node) - { - if(node != null) - { + private void preorder(TreeNode node) { + if (node != null) { preorder(node.left); System.out.println(node.val); preorder(node.right); } } - private TreeNode build(int s, int e, int[] nums) - { - if(s > e) return null; + private TreeNode build(int s, int e, int[] nums) { + if (s > e) return null; int m = (e - s) / 2; int node = nums[s + m]; TreeNode root = new TreeNode(node); - if(s == e) + if (s == e) return root; root.left = build(s, s + m - 1, nums); diff --git a/problems/src/tree/SubtreeOfAnotherTree.java b/problems/src/tree/SubtreeOfAnotherTree.java index 9c27a515..0d94d926 100644 --- a/problems/src/tree/SubtreeOfAnotherTree.java +++ b/problems/src/tree/SubtreeOfAnotherTree.java @@ -1,67 +1,69 @@ package tree; + /** * Created by gouthamvidyapradhan on 07/07/2017. - Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself. - - Example 1: - Given tree s: - - 3 - / \ - 4 5 - / \ - 1 2 - Given tree t: - 4 - / \ - 1 2 - Return true, because t has the same structure and node values with a subtree of s. - Example 2: - Given tree s: - - 3 - / \ - 4 5 - / \ - 1 2 - / - 0 - Given tree t: - 4 - / \ - 1 2 - Return false. - + * Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself. + *

+ * Example 1: + * Given tree s: + *

+ * 3 + * / \ + * 4 5 + * / \ + * 1 2 + * Given tree t: + * 4 + * / \ + * 1 2 + * Return true, because t has the same structure and node values with a subtree of s. + * Example 2: + * Given tree s: + *

+ * 3 + * / \ + * 4 5 + * / \ + * 1 2 + * / + * 0 + * Given tree t: + * 4 + * / \ + * 1 2 + * Return false. */ public class SubtreeOfAnotherTree { public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { } public boolean isSubtree(TreeNode s, TreeNode t) { - if(s != null){ - if(s.val == t.val) { - if(equal(s, t)) + if (s != null) { + if (s.val == t.val) { + if (equal(s, t)) return true; else return (isSubtree(s.left, t) || isSubtree(s.right, t)); - } - else return (isSubtree(s.left, t) || isSubtree(s.right, t)); + } else return (isSubtree(s.left, t) || isSubtree(s.right, t)); } return false; } - private boolean equal(TreeNode s, TreeNode t){ + private boolean equal(TreeNode s, TreeNode t) { if (s == null && t == null) return true; - else if(s == null || t == null) + else if (s == null || t == null) return false; - else if(s.val != t.val) return false; + else if (s.val != t.val) return false; else return equal(s.left, t.left) && equal(s.right, t.right); } diff --git a/problems/src/tree/SymmetricTree.java b/problems/src/tree/SymmetricTree.java index 7e1c7265..287db22a 100644 --- a/problems/src/tree/SymmetricTree.java +++ b/problems/src/tree/SymmetricTree.java @@ -3,22 +3,21 @@ /** * Created by gouthamvidyapradhan on 14/08/2017. * Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). - - For example, this binary tree [1,2,2,3,4,4,3] is symmetric: - - 1 - / \ - 2 2 - / \ / \ - 3 4 4 3 - - But the following [1,2,2,null,3,null,3] is not: - 1 - / \ - 2 2 - \ \ - 3 3 - + *

+ * For example, this binary tree [1,2,2,3,4,4,3] is symmetric: + *

+ * 1 + * / \ + * 2 2 + * / \ / \ + * 3 4 4 3 + *

+ * But the following [1,2,2,null,3,null,3] is not: + * 1 + * / \ + * 2 2 + * \ \ + * 3 3 */ public class SymmetricTree { @@ -26,15 +25,19 @@ static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { TreeNode node = new TreeNode(3); node.left = new TreeNode(4); node.right = new TreeNode(5); @@ -42,7 +45,7 @@ public static void main(String[] args) throws Exception{ } public boolean isSymmetric(TreeNode root) { - if(root == null) return true; + if (root == null) return true; return dfs(root.left, root.right); } diff --git a/problems/src/tree/ValidBinarySearchTree.java b/problems/src/tree/ValidBinarySearchTree.java index b355bf0b..4ab6893a 100644 --- a/problems/src/tree/ValidBinarySearchTree.java +++ b/problems/src/tree/ValidBinarySearchTree.java @@ -2,54 +2,53 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a binary tree, determine if it is a valid binary search tree (BST). - - Assume a BST is defined as follows: - - The left subtree of a node contains only nodes with keys less than the node's key. - The right subtree of a node contains only nodes with keys greater than the node's key. - Both the left and right subtrees must also be binary search trees. - Example 1: - 2 - / \ - 1 3 - Binary tree [2,1,3], return true. - Example 2: - 1 - / \ - 2 3 - Binary tree [1,2,3], return false. + * Given a binary tree, determine if it is a valid binary search tree (BST). + *

+ * Assume a BST is defined as follows: + *

+ * The left subtree of a node contains only nodes with keys less than the node's key. + * The right subtree of a node contains only nodes with keys greater than the node's key. + * Both the left and right subtrees must also be binary search trees. + * Example 1: + * 2 + * / \ + * 1 3 + * Binary tree [2,1,3], return true. + * Example 2: + * 1 + * / \ + * 2 3 + * Binary tree [1,2,3], return false. */ -public class ValidBinarySearchTree -{ - class Range - { +public class ValidBinarySearchTree { + class Range { long low, high; } - static class TreeNode - { + static class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(Integer.MIN_VALUE); root.right = new TreeNode(Integer.MAX_VALUE); System.out.println(new ValidBinarySearchTree().isValidBST(root)); } - private boolean isValidBST(TreeNode root) - { - if(root == null || + private boolean isValidBST(TreeNode root) { + if (root == null || (root.right == null && root.left == null)) return true; Range range = new Range(); range.high = Long.MAX_VALUE; @@ -57,25 +56,20 @@ private boolean isValidBST(TreeNode root) return validate(root, range); } - private boolean validate(TreeNode root, Range range) - { - if((root.val > range.low) && (root.val < range.high)) - { + private boolean validate(TreeNode root, Range range) { + if ((root.val > range.low) && (root.val < range.high)) { long temp = range.high; - if(root.left != null) - { + if (root.left != null) { range.high = root.val; - if(!validate(root.left, range)) return false; + if (!validate(root.left, range)) return false; } - if(root.right != null) - { + if (root.right != null) { range.high = temp; range.low = root.val; - if(!validate(root.right, range)) return false; + if (!validate(root.right, range)) return false; } return true; - } - else return false; + } else return false; } } diff --git a/problems/src/tree/ZigZagTraversal.java b/problems/src/tree/ZigZagTraversal.java index 216acdd4..60100c2f 100644 --- a/problems/src/tree/ZigZagTraversal.java +++ b/problems/src/tree/ZigZagTraversal.java @@ -7,20 +7,20 @@ /** * Created by pradhang on 7/11/2017. * Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). - - For example: - Given binary tree [3,9,20,null,null,15,7], - 3 - / \ - 9 20 - / \ - 15 7 - return its zigzag level order traversal as: - [ - [3], - [20,9], - [15,7] - ] + *

+ * For example: + * Given binary tree [3,9,20,null,null,15,7], + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * return its zigzag level order traversal as: + * [ + * [3], + * [20,9], + * [15,7] + * ] */ public class ZigZagTraversal { @@ -28,28 +28,32 @@ public class TreeNode { int val; TreeNode left; TreeNode right; - TreeNode(int x) { val = x; } + + TreeNode(int x) { + val = x; + } } - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { } + public List> zigzagLevelOrder(TreeNode root) { List> result = new ArrayList<>(); - if(root == null) return result; + if (root == null) return result; dfs(root, 0, result); return result; } @SuppressWarnings("unchecked") - private void dfs(TreeNode root, int level, List> result){ - if(root != null){ + private void dfs(TreeNode root, int level, List> result) { + if (root != null) { LinkedList subList; - if(level >= result.size()){ + if (level >= result.size()) { subList = new LinkedList<>(); result.add(subList); - }else subList = (LinkedList)result.get(level); - if(level % 2 == 0) + } else subList = (LinkedList) result.get(level); + if (level % 2 == 0) subList.addFirst(root.val); //add to right else subList.add(root.val); //add to left dfs(root.right, level + 1, result); diff --git a/problems/src/two_pointers/FourSum.java b/problems/src/two_pointers/FourSum.java index 639da11b..3df8ee11 100644 --- a/problems/src/two_pointers/FourSum.java +++ b/problems/src/two_pointers/FourSum.java @@ -6,66 +6,55 @@ /** * Created by gouthamvidyapradhan on 29/03/2017. - Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. - - Note: The solution set must not contain duplicate quadruplets. - - For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. - - A solution set is: - [ - [-1, 0, 0, 1], - [-2, -1, 1, 2], - [-2, 0, 0, 2] - ] + * Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. + *

+ * Note: The solution set must not contain duplicate quadruplets. + *

+ * For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. + *

+ * A solution set is: + * [ + * [-1, 0, 0, 1], + * [-2, -1, 1, 2], + * [-2, 0, 0, 2] + * ] */ -public class FourSum -{ +public class FourSum { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { int[] nums = {1, 0, -1, 0, -2, 2}; System.out.println(new FourSum().fourSum(nums, 0)); } - public List> fourSum(int[] nums, int target) - { + public List> fourSum(int[] nums, int target) { List> result = new ArrayList<>(); - if(nums.length < 4) return result; + if (nums.length < 4) return result; Arrays.sort(nums); - for(int i = 0; i < nums.length - 3; i++) - { - if(i == 0 || nums[i] != nums[i - 1]) - { - for(int j = i + 1; j < nums.length - 2; j ++) - { - if(j == i + 1 || nums[j] != nums[j - 1]) - { + for (int i = 0; i < nums.length - 3; i++) { + if (i == 0 || nums[i] != nums[i - 1]) { + for (int j = i + 1; j < nums.length - 2; j++) { + if (j == i + 1 || nums[j] != nums[j - 1]) { int k = j + 1, l = nums.length - 1; - while(k < l) - { - if(k != j + 1 && nums[k] == nums[k + 1]) - { - k++; continue; + while (k < l) { + if (k != j + 1 && nums[k] == nums[k + 1]) { + k++; + continue; } int sum = nums[i] + nums[j] + nums[k] + nums[l]; - if(sum == target) - { + if (sum == target) { result.add(Arrays.asList(nums[i], nums[j], nums[k], nums[l])); - k++; l --; - } - else if(sum < target) - { - k ++; - } - else - { - l --; + k++; + l--; + } else if (sum < target) { + k++; + } else { + l--; } } } diff --git a/problems/src/two_pointers/LongestSubstringWitoutRepeats.java b/problems/src/two_pointers/LongestSubstringWitoutRepeats.java index 67b389bb..fb20367b 100644 --- a/problems/src/two_pointers/LongestSubstringWitoutRepeats.java +++ b/problems/src/two_pointers/LongestSubstringWitoutRepeats.java @@ -7,38 +7,35 @@ /** * Created by gouthamvidyapradhan on 09/03/2017. - Given a string, find the length of the longest substring without repeating characters. - - Examples: - - Given "abcabcbb", the answer is "abc", which the length is 3. - - Given "bbbbb", the answer is "b", with the length of 1. - - Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. + * Given a string, find the length of the longest substring without repeating characters. + *

+ * Examples: + *

+ * Given "abcabcbb", the answer is "abc", which the length is 3. + *

+ * Given "bbbbb", the answer is "b", with the length of 1. + *

+ * Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. */ -public class LongestSubstringWitoutRepeats -{ +public class LongestSubstringWitoutRepeats { Set set = new HashSet<>(); + /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { + public static void main(String[] args) throws Exception { System.out.println(new LongestSubstringWitoutRepeats().lengthOfLongestSubstring("asdfsdfsdfsdfasdfdjdjjdjjdjjjjjajsdjjdjdjjd")); } - private int lengthOfLongestSubstring(String s) - { - if(s == null || s.isEmpty()) return 0; + private int lengthOfLongestSubstring(String s) { + if (s == null || s.isEmpty()) return 0; Map map = new HashMap<>(); int i = 0, max = Integer.MIN_VALUE; - for(int j = 0, l = s.length(); j < l; j ++) - { - if(map.keySet().contains(s.charAt(j))) - { + for (int j = 0, l = s.length(); j < l; j++) { + if (map.keySet().contains(s.charAt(j))) { i = Math.max(map.get(s.charAt(j)) + 1, i); } map.put(s.charAt(j), j); diff --git a/problems/src/two_pointers/MoveZeroes.java b/problems/src/two_pointers/MoveZeroes.java index 309bbb1d..9805b6df 100644 --- a/problems/src/two_pointers/MoveZeroes.java +++ b/problems/src/two_pointers/MoveZeroes.java @@ -4,17 +4,16 @@ * Created by gouthamvidyapradhan on 13/06/2017. * Accepted * Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. - - For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. - - Note: - You must do this in-place without making a copy of the array. - Minimize the total number of operations. + *

+ * For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. + *

+ * Note: + * You must do this in-place without making a copy of the array. + * Minimize the total number of operations. */ -public class MoveZeroes -{ +public class MoveZeroes { public static void main(String[] args) throws Exception { - int[] nums = {0,0,0,0,1,0,1,0,2}; + int[] nums = {0, 0, 0, 0, 1, 0, 1, 0, 2}; new MoveZeroes().moveZeroes(nums); for (int n : nums) System.out.print(n); @@ -22,15 +21,15 @@ public static void main(String[] args) throws Exception { public void moveZeroes(int[] nums) { int i = 0; - for(int j = 0, l = nums.length; j < l;) { - if(nums[j] == 0) + for (int j = 0, l = nums.length; j < l; ) { + if (nums[j] == 0) j++; else { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; - i ++; - j ++; + i++; + j++; } } while (i < nums.length) diff --git a/problems/src/two_pointers/RemoveDuplicates.java b/problems/src/two_pointers/RemoveDuplicates.java index 96eb7131..9d1e9741 100644 --- a/problems/src/two_pointers/RemoveDuplicates.java +++ b/problems/src/two_pointers/RemoveDuplicates.java @@ -3,26 +3,27 @@ /** * Created by gouthamvidyapradhan on 04/07/2017. * Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. - - Do not allocate extra space for another array, you must do this in place with constant memory. - - For example, - Given input array nums = [1,1,2], - - Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. + *

+ * Do not allocate extra space for another array, you must do this in place with constant memory. + *

+ * For example, + * Given input array nums = [1,1,2], + *

+ * Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. */ public class RemoveDuplicates { - public static void main(String[] args) throws Exception{ + public static void main(String[] args) throws Exception { int[] nums = {1, 1, 2}; int N = new RemoveDuplicates().removeDuplicates(nums); - for(int i = 0; i < N; i ++) + for (int i = 0; i < N; i++) System.out.print(nums[i] + " "); } + public int removeDuplicates(int[] nums) { - if(nums.length == 1) return 1; + if (nums.length == 1) return 1; int size = 1; - for(int j = 0, i = 1; i < nums.length; i ++){ - if(nums[i] != nums[i - 1]){ + for (int j = 0, i = 1; i < nums.length; i++) { + if (nums[i] != nums[i - 1]) { size++; j++; nums[j] = nums[i]; diff --git a/problems/src/two_pointers/ThreeSum.java b/problems/src/two_pointers/ThreeSum.java index 9e105ae7..22d91ad9 100644 --- a/problems/src/two_pointers/ThreeSum.java +++ b/problems/src/two_pointers/ThreeSum.java @@ -6,55 +6,48 @@ /** * Created by gouthamvidyapradhan on 29/03/2017. - Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. - - Note: The solution set must not contain duplicate triplets. - - For example, given array S = [-1, 0, 1, 2, -1, -4], - - A solution set is: - [ - [-1, 0, 1], - [-1, -1, 2] - ] + * Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. + *

+ * Note: The solution set must not contain duplicate triplets. + *

+ * For example, given array S = [-1, 0, 1, 2, -1, -4], + *

+ * A solution set is: + * [ + * [-1, 0, 1], + * [-1, -1, 2] + * ] */ -public class ThreeSum -{ +public class ThreeSum { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] nums = {-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4,-1,0,1,2,-1,-4}; + public static void main(String[] args) throws Exception { + int[] nums = {-1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4, -1, 0, 1, 2, -1, -4}; System.out.println(new ThreeSum().threeSum(nums)); } - public List> threeSum(int[] nums) - { + public List> threeSum(int[] nums) { List> result = new ArrayList<>(); - if(nums.length < 3) return result; + if (nums.length < 3) return result; Arrays.sort(nums); - for(int i = 0, l = nums.length; i < l - 2; i ++) - { - if(i == 0 || nums[i] != nums[i - 1]) - { + for (int i = 0, l = nums.length; i < l - 2; i++) { + if (i == 0 || nums[i] != nums[i - 1]) { int j = i + 1, k = l - 1; - while(k > j) - { - if(j != i + 1 && nums[j] == nums[j - 1]) - { - j ++; + while (k > j) { + if (j != i + 1 && nums[j] == nums[j - 1]) { + j++; continue; } int sum = nums[i] + nums[j] + nums[k]; - if(sum == 0) - { + if (sum == 0) { result.add(Arrays.asList(nums[i], nums[j], nums[k])); - k--; j++; - } - else if(sum > 0) k--; + k--; + j++; + } else if (sum > 0) k--; else j++; } } diff --git a/problems/src/two_pointers/ThreeSumClosest.java b/problems/src/two_pointers/ThreeSumClosest.java index df8cfce9..769db5c8 100644 --- a/problems/src/two_pointers/ThreeSumClosest.java +++ b/problems/src/two_pointers/ThreeSumClosest.java @@ -5,11 +5,11 @@ /** * Created by gouthamvidyapradhan on 13/06/2017. * Accepted - Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. - - For example, given array S = {-1 2 1 -4}, and target = 1. - - The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). + * Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. + *

+ * For example, given array S = {-1 2 1 -4}, and target = 1. + *

+ * The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). */ public class ThreeSumClosest { @@ -21,32 +21,30 @@ public static void main(String[] args) { public int threeSumClosest(int[] a, int target) { Arrays.sort(a); int min = Integer.MAX_VALUE, ans = -1; - for(int i = 0, l = a.length; i < l - 2; i ++) { - if(i == 0 || ! (a[i] == a[i - 1])) { + for (int i = 0, l = a.length; i < l - 2; i++) { + if (i == 0 || !(a[i] == a[i - 1])) { int j = i + 1, k = l - 1; - while(k > j) { - if(j != i + 1 && (a[j] == a[j - 1])) { - j ++; + while (k > j) { + if (j != i + 1 && (a[j] == a[j - 1])) { + j++; continue; } int sum = a[i] + a[j] + a[k]; - if(sum < target) { + if (sum < target) { int diff = Math.abs(sum - target); - if(diff < min) { + if (diff < min) { min = diff; ans = sum; } j++; - } - else if(sum > target) { + } else if (sum > target) { int diff = Math.abs(sum - target); - if(diff < min) { + if (diff < min) { min = diff; ans = sum; } k--; - } - else{ + } else { return sum; } } diff --git a/problems/src/two_pointers/TrappingRainWater.java b/problems/src/two_pointers/TrappingRainWater.java index d45cb2ad..3fda5a3c 100644 --- a/problems/src/two_pointers/TrappingRainWater.java +++ b/problems/src/two_pointers/TrappingRainWater.java @@ -2,27 +2,25 @@ /** * Created by gouthamvidyapradhan on 08/03/2017. - Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. - - For example, - Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. + * Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. + *

+ * For example, + * Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. */ -public class TrappingRainWater -{ +public class TrappingRainWater { /** * Main method + * * @param args * @throws Exception */ - public static void main(String[] args) throws Exception - { - int[] height = {0,1,0,2,1,0,1,3,2,1,2,1}; + public static void main(String[] args) throws Exception { + int[] height = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1}; System.out.println(new TrappingRainWater().trap(height)); } - private int trap(int[] height) - { - if(height.length == 0) return 0; + private int trap(int[] height) { + if (height.length == 0) return 0; int[] left = new int[height.length]; int[] right = new int[height.length]; @@ -32,22 +30,18 @@ private int trap(int[] height) int total = 0; - for(int i = 1, l = height.length; i < l; i ++) - { + for (int i = 1, l = height.length; i < l; i++) { left[i] = Math.max(max, height[i - 1]); max = left[i]; } max = 0; - for(int i = height.length - 2; i >= 0; i --) - { + for (int i = height.length - 2; i >= 0; i--) { right[i] = Math.max(max, height[i + 1]); max = right[i]; } - for(int i = 0, l = height.length; i < l; i++) - { + for (int i = 0, l = height.length; i < l; i++) { int min = Math.min(left[i], right[i]); - if(min > height[i]) - { + if (min > height[i]) { total += (min - height[i]); } }