└── src ├── topinterviewquestions ├── Problem_0136_SingleNumber.java ├── Problem_0172_FactorialTrailingZeroes.java ├── Problem_0371_SumOfTwoIntegers.java ├── Problem_0344_ReverseString.java ├── Problem_0237_DeleteNodeInLinkedList.java ├── Problem_0171_ExcelSheetColumnNumber.java ├── Problem_0066_PlusOne.java ├── Problem_0326_PowerOfThree.java ├── Problem_0122_BestTimeToBuyAndSellStockII.java ├── Problem_0011_ContainerWithMostWater.java ├── Problem_0283_MoveZeroes.java ├── Problem_0169_MajorityElement.java ├── Problem_0206_ReverseLinkedList.java ├── Problem_0104_MaximumDepthOfBinaryTree.java ├── Problem_0121_BestTimeToBuyAndSellStock.java ├── Problem_0387_FirstUniqueCharacterInString.java ├── Problem_0026_RemoveDuplicatesFromSortedArray.java ├── Problem_0055_JumpGame.java ├── Problem_0204_CountPrimes.java ├── Problem_0007_ReverseInteger.java ├── Problem_0069_SqrtX.java ├── Problem_0001_TwoSum.java ├── Problem_0242_ValidAnagram.java ├── Problem_0287_FindTheDuplicateNumber.java ├── Problem_0088_MergeSortedArray.java ├── Problem_0152_MaximumProductSubarray.java ├── Problem_0412_FizzBuzz.java ├── Problem_0045_JumpGameII.java ├── Problem_0075_SortColors.java ├── Problem_0268_MissingNumber.java ├── Problem_0062_UniquePaths.java ├── Problem_0240_SearchA2DMatrixII.java ├── Problem_0041_FirstMissingPositive.java ├── Problem_0118_PascalTriangle.java ├── Problem_0277_FindTheCelebrity.java ├── Problem_0012_IntegerToRoman.java ├── Problem_0042_TrappingRainWater.java ├── Problem_0162_FindPeakElement.java ├── Problem_0191_NumberOf1Bits.java ├── Problem_0019_RemoveNthNodeFromEndofList.java ├── Problem_0128_LongestConsecutiveSequence.java ├── Problem_0014_LongestCommonPrefix.java ├── Problem_0123_BestTimeToBuyAndSellStockIII.java ├── Problem_0036_ValidSudoku.java ├── Problem_0101_SymmetricTree.java ├── Problem_0048_RotateImage.java ├── Problem_0384_ShuffleAnArray.java ├── Problem_0020_ValidParentheses.java ├── Problem_0300_LongestIncreasingSubsequence.java ├── Problem_0155_MinStack.java ├── Problem_0334_IncreasingTripletSubsequence.java ├── Problem_0239_SlidingWindowMaximum.java ├── Problem_0454_4SumII.java ├── Problem_0108_ConvertSortedArrayToBinarySearchTree.java ├── Problem_0021_MergeTwoSortedLists.java ├── Problem_0340_LongestSubstringWithAtMostKDistinctCharacters.java ├── Problem_0038_CountAndSay.java ├── Problem_0003_LongestSubstringWithoutRepeatingCharacters.java ├── Problem_0141_LinkedListCycle.java ├── Problem_0213_HouseRobberII.java ├── Problem_0163_MissingRanges.java ├── Problem_0200_NumberOfIslands.java ├── Problem_0202_HappyNumber.java ├── Problem_0013_RomanToInteger.java ├── Problem_0198_HouseRobber.java ├── Problem_0230_KthSmallestElementInBST.java ├── Problem_0150_EvaluateReversePolishNotation.java ├── Problem_0084_LargestRectangleInHistogram.java ├── Problem_0098_ValidateBinarySearchTree.java ├── Problem_0094_BinaryTreeInorderTraversal.java ├── Problem_0160_IntersectionOfTwoLinkedLists.java ├── Problem_0285_InorderSuccessorInBST.java ├── Problem_0179_LargestNumber.java ├── Problem_0328_OddEvenLinkedList.java ├── Problem_0348_DesignTicTacToe.java ├── Problem_0102_BinaryTreeLevelOrderTraversal.java ├── Problem_0076_MinimumWindowSubstring.java ├── Problem_0251_Flatten2DVector.java ├── Problem_0079_WordSearch.java ├── Problem_0078_Subsets.java ├── Problem_0234_PalindromeLinkedList.java ├── Problem_0350_IntersectionOfTwoArraysII.java ├── Problem_0166_FractionToRecurringDecimal.java ├── Problem_0238_ProductOfArrayExceptSelf.java ├── Problem_0125_ValidPalindrome.java ├── Problem_0295_FindMedianFromDataStream.java ├── Problem_0105_ConstructBinaryTreeFromPreorderAndInorderTraversal.java ├── Problem_0070_ClimbingStairs.java ├── Problem_0023_MergeKSortedLists.java ├── Problem_0034_FindFirstAndLastPositionOfElementInSortedArray.java ├── Problem_0002_AddTwoNumbers.java ├── Problem_0138_CopyListWithRandomPointer.java ├── Problem_0054_SpiralMatrix.java ├── Problem_0347_TopKFrequentElements.java ├── Problem_0028_ImplementStrStr.java ├── Problem_0017_LetterCombinationsOfAPhoneNumber.java ├── Problem_0253_MeetingRoomsII.java ├── Problem_0236_LowestCommonAncestorOfBinaryTree.java ├── Problem_0380_InsertDeleteGetRandom.java ├── Problem_0103_BinaryTreeZigzagLevelOrderTraversal.java ├── Problem_0189_RotateArray.java ├── Problem_0033_SearchInRotatedSortedArray.java ├── Problem_0215_KthLargestElementInAnArray.java ├── Problem_0005_LongestPalindromicSubstring.java ├── Problem_0687_LongestUnivaluePath.java ├── Problem_0053_MaximumSubarray.java ├── Problem_0050_PowXN.java ├── Problem_0188_BestTimeToBuyAndSellStockIV.java ├── Problem_0289_GameOfLife.java ├── Problem_0308_RangeSumQuery2DMutable.java ├── Problem_0116_PopulatingNextRightPointersInEachNode.java ├── Problem_0049_GroupAnagrams.java ├── Problem_0056_MergeIntervals.java ├── Problem_0207_CourseSchedule.java ├── Problem_0124_BinaryTreeMaximumPathSum.java ├── Problem_0208_Trie.java ├── Problem_0279_PerfectSquares.java ├── Problem_0227_BasicCalculatorII.java ├── Problem_0037_SudokuSolver.java ├── Problem_0217_ContainsDuplicate.java ├── Problem_0190_ReverseBits.java ├── Problem_0315_CountOfSmallerNumbersAfterSelf.java ├── Problem_0149_MaxPointsOnALine.java ├── Problem_0022_GenerateParentheses.java ├── Problem_0322_CoinChange.java ├── Problem_0210_CourseScheduleII.java ├── Problem_0073_SetMatrixZeroes.java ├── Problem_0269_AlienDictionary.java ├── Problem_0046_Permutations.java ├── Problem_0131_PalindromePartitioning.java ├── Problem_0772_BasicCalculatorIII.java ├── Problem_0008_StringToInteger.java ├── Problem_0029_DivideTwoIntegers.java ├── Problem_0015_3Sum.java ├── Problem_0091_DecodeWays.java ├── Problem_0218_TheSkylineProblem.java ├── Problem_0297_SerializeAndDeserializeBinaryTree.java ├── Problem_0140_WordBreakII.java ├── Problem_0004_MedianOfTwoSortedArrays.java ├── Problem_0329_LongestIncreasingPathInAMatrix.java ├── Problem_0044_WildcardMatching.java ├── Problem_0378_KthSmallestElementInSortedMatrix.java ├── Problem_0148_SortList.java ├── Problem_0130_SurroundedRegions.java ├── Problem_0324_WiggleSortII.java ├── Problem_0395_LongestSubstringWithAtLeastKRepeatingCharacters.java ├── Problem_0341_FlattenNestedListIterator.java ├── Problem_0673_NumberOfLongestIncreasingSubsequence.java ├── Problem_0212_WordSearchII.java └── Problem_0127_WordLadder.java └── followup ├── PrintStar.java ├── MaxSum.java ├── IndexTreeTest.java ├── FollowIndexTree.java ├── Code03_Array.java ├── Code04_Painting.java ├── Code02_Drive.java ├── AddDevideNum.java ├── AddDevideNum2.java └── KN.java /src/topinterviewquestions/Problem_0136_SingleNumber.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0136_SingleNumber { 4 | 5 | public static int singleNumber(int[] nums) { 6 | int eor = 0; 7 | for (int num : nums) { 8 | eor ^= num; 9 | } 10 | return eor; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0172_FactorialTrailingZeroes.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0172_FactorialTrailingZeroes { 4 | 5 | public static int trailingZeroes(int n) { 6 | int ans = 0; 7 | while (n != 0) { 8 | n /= 5; 9 | ans += n; 10 | } 11 | return ans; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0371_SumOfTwoIntegers.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0371_SumOfTwoIntegers { 4 | 5 | public static int getSum(int a, int b) { 6 | int sum = a; 7 | while (b != 0) { 8 | sum = a ^ b; 9 | b = (a & b) << 1; 10 | a = sum; 11 | } 12 | return sum; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0344_ReverseString.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0344_ReverseString { 4 | 5 | public void reverseString(char[] s) { 6 | int l = 0; 7 | int r = s.length - 1; 8 | while (l < r) { 9 | char tmp = s[l]; 10 | s[l++] = s[r]; 11 | s[r--] = tmp; 12 | } 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0237_DeleteNodeInLinkedList.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0237_DeleteNodeInLinkedList { 4 | 5 | public static class ListNode { 6 | int val; 7 | ListNode next; 8 | } 9 | 10 | public void deleteNode(ListNode node) { 11 | node.val = node.next.val; 12 | node.next = node.next.next; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0171_ExcelSheetColumnNumber.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0171_ExcelSheetColumnNumber { 4 | 5 | // 这道题反过来也要会写 6 | public static int titleToNumber(String s) { 7 | char[] str = s.toCharArray(); 8 | int ans = 0; 9 | for (int i = 0; i < str.length; i++) { 10 | ans = ans * 26 + (str[i] - 'A') + 1; 11 | } 12 | return ans; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0066_PlusOne.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0066_PlusOne { 4 | 5 | public static int[] plusOne(int[] digits) { 6 | int n = digits.length; 7 | for (int i = n - 1; i >= 0; i--) { 8 | if (digits[i] < 9) { 9 | digits[i]++; 10 | return digits; 11 | } 12 | digits[i] = 0; 13 | } 14 | int[] ans = new int[n + 1]; 15 | ans[0] = 1; 16 | return ans; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0326_PowerOfThree.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0326_PowerOfThree { 4 | 5 | // 如果一个数字是3的某次幂,那么这个数一定只含有3这个质数因子 6 | // 1162261467是int型范围内,最大的3的幂,它是3的19次方 7 | // 这个1162261467只含有3这个质数因子,如果n也是只含有3这个质数因子,那么 8 | // 1162261467 % n == 0 9 | // 反之如果1162261467 % n != 0 说明n一定含有其他因子 10 | public static boolean isPowerOfThree(int n) { 11 | return (n > 0 && 1162261467 % n == 0); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0122_BestTimeToBuyAndSellStockII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0122_BestTimeToBuyAndSellStockII { 4 | 5 | public static int maxProfit(int[] prices) { 6 | if (prices == null || prices.length == 0) { 7 | return 0; 8 | } 9 | int ans = 0; 10 | for (int i = 1; i < prices.length; i++) { 11 | ans += Math.max(prices[i] - prices[i-1], 0); 12 | } 13 | return ans; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0011_ContainerWithMostWater.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0011_ContainerWithMostWater { 4 | 5 | public static int maxArea(int[] h) { 6 | int max = 0; 7 | int l = 0; 8 | int r = h.length - 1; 9 | while (l < r) { 10 | max = Math.max(max, Math.min(h[l], h[r]) * (r - l)); 11 | if (h[l] > h[r]) { 12 | r--; 13 | } else { 14 | l++; 15 | } 16 | } 17 | return max; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0283_MoveZeroes.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0283_MoveZeroes { 4 | 5 | public static void moveZeroes(int[] nums) { 6 | int to = 0; 7 | for (int i = 0; i < nums.length; i++) { 8 | if (nums[i] != 0) { 9 | swap(nums, to++, i); 10 | } 11 | } 12 | } 13 | 14 | public static void swap(int[] arr, int i, int j) { 15 | int tmp = arr[i]; 16 | arr[i] = arr[j]; 17 | arr[j] = tmp; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0169_MajorityElement.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0169_MajorityElement { 4 | 5 | public static int majorityElement(int[] nums) { 6 | int cand = 0; 7 | int HP = 0; 8 | for (int i = 0; i < nums.length; i++) { 9 | if (HP == 0) { 10 | cand = nums[i]; 11 | HP = 1; 12 | } else if (nums[i] == cand) { 13 | HP++; 14 | } else { 15 | HP--; 16 | } 17 | } 18 | return cand; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0206_ReverseLinkedList.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0206_ReverseLinkedList { 4 | 5 | public static class ListNode { 6 | int val; 7 | ListNode next; 8 | } 9 | 10 | public static ListNode reverseList(ListNode head) { 11 | ListNode pre = null; 12 | ListNode next = null; 13 | while (head != null) { 14 | next = head.next; 15 | head.next = pre; 16 | pre = head; 17 | head = next; 18 | } 19 | return pre; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0104_MaximumDepthOfBinaryTree.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0104_MaximumDepthOfBinaryTree { 4 | 5 | /* 6 | * 注意最小高度比这个复杂,要额外小心判断空 7 | * */ 8 | public static class TreeNode { 9 | int val; 10 | TreeNode left; 11 | TreeNode right; 12 | } 13 | 14 | public static int maxDepth(TreeNode root) { 15 | if (root == null) { 16 | return 0; 17 | } 18 | return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0121_BestTimeToBuyAndSellStock.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0121_BestTimeToBuyAndSellStock { 4 | 5 | public static int maxProfit(int[] prices) { 6 | if (prices == null || prices.length == 0) { 7 | return 0; 8 | } 9 | // 0...i 最小值 10 | int min = prices[0]; 11 | int ans = 0; 12 | for (int i = 0; i < prices.length; i++) { 13 | min = Math.min(min, prices[i]); 14 | ans = Math.max(ans, prices[i] - min); 15 | } 16 | return ans; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0387_FirstUniqueCharacterInString.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0387_FirstUniqueCharacterInString { 4 | 5 | public int firstUniqChar(String s) { 6 | char[] str = s.toCharArray(); 7 | int N = str.length; 8 | int count[] = new int[26]; 9 | for (int i = 0; i < N; i++) { 10 | count[str[i] - 'a']++; 11 | } 12 | for (int i = 0; i < N; i++) { 13 | if (count[str[i] - 'a'] == 1) { 14 | return i; 15 | } 16 | } 17 | return -1; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0026_RemoveDuplicatesFromSortedArray.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0026_RemoveDuplicatesFromSortedArray { 4 | 5 | public static int removeDuplicates(int[] nums) { 6 | if (nums == null) { 7 | return 0; 8 | } 9 | if (nums.length < 2) { 10 | return nums.length; 11 | } 12 | int done = 0; 13 | for (int i = 1; i < nums.length; i++) { 14 | if (nums[i] != nums[done]) { 15 | nums[++done] = nums[i]; 16 | } 17 | } 18 | return done + 1; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0055_JumpGame.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0055_JumpGame { 4 | 5 | public static boolean canJump(int[] nums) { 6 | if (nums == null || nums.length < 2) { 7 | return true; 8 | } 9 | int max = nums[0]; 10 | for (int i = 1; i < nums.length; i++) { 11 | // if (max >= nums.length - 1) { 12 | // return true; 13 | // } 14 | if (i > max) { 15 | return false; 16 | } 17 | max = Math.max(max, i + nums[i]); 18 | } 19 | return true; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0204_CountPrimes.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0204_CountPrimes { 4 | 5 | public static int countPrimes(int n) { 6 | if (n < 3) { 7 | return 0; 8 | } 9 | boolean[] f = new boolean[n]; 10 | int count = n / 2; 11 | for (int i = 3; i * i < n; i += 2) { 12 | if (f[i]) { 13 | continue; 14 | } 15 | for (int j = i * i; j < n; j += 2 * i) { 16 | if (!f[j]) { 17 | --count; 18 | f[j] = true; 19 | } 20 | } 21 | } 22 | return count; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0007_ReverseInteger.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0007_ReverseInteger { 4 | 5 | public static int reverse(int x) { 6 | boolean neg = ((x >>> 31) & 1) == 1; 7 | x = neg ? x : -x; 8 | int m = Integer.MIN_VALUE / 10; 9 | int o = Integer.MIN_VALUE % 10; 10 | int res = 0; 11 | while (x != 0) { 12 | if (res < m || (res == m && x % 10 < o)) { 13 | return 0; 14 | } 15 | res = res * 10 + x % 10; 16 | x /= 10; 17 | } 18 | return neg ? res : Math.abs(res); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0069_SqrtX.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0069_SqrtX { 4 | 5 | // x一定非负,输入可以保证 6 | public static int mySqrt(int x) { 7 | if (x == 0) { 8 | return 0; 9 | } 10 | if (x < 3) { 11 | return 1; 12 | } 13 | long ans = 1; 14 | long L = 1; 15 | long R = x; 16 | long M = 0; 17 | while (L <= R) { 18 | M = (L + R) / 2; 19 | if (M * M <= x) { 20 | ans = M; 21 | L = M + 1; 22 | } else { 23 | R = M - 1; 24 | } 25 | } 26 | return (int) ans; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0001_TwoSum.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Problem_0001_TwoSum { 6 | 7 | public static int[] twoSum(int[] nums, int target) { 8 | // key 某个之前的数 value 这个数出现的位置 9 | HashMap map = new HashMap<>(); 10 | for (int i = 0; i < nums.length; i++) { 11 | if (map.containsKey(target - nums[i])) { 12 | return new int[] { map.get(target - nums[i]), i }; 13 | } 14 | map.put(nums[i], i); 15 | } 16 | return new int[] { -1, -1 }; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0242_ValidAnagram.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0242_ValidAnagram { 4 | 5 | public static boolean isAnagram(String s, String t) { 6 | if (s.length() != t.length()) { 7 | return false; 8 | } 9 | char[] str = s.toCharArray(); 10 | char[] tar = t.toCharArray(); 11 | int[] count = new int[256]; 12 | for (char cha : str) { 13 | count[cha]++; 14 | } 15 | for (char cha : tar) { 16 | if (--count[cha] < 0) { 17 | return false; 18 | } 19 | } 20 | return true; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0287_FindTheDuplicateNumber.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0287_FindTheDuplicateNumber { 4 | 5 | public static int findDuplicate(int[] nums) { 6 | if (nums == null || nums.length < 2) { 7 | return -1; 8 | } 9 | int slow = nums[0]; 10 | int fast = nums[nums[0]]; 11 | while (slow != fast) { 12 | slow = nums[slow]; 13 | fast = nums[nums[fast]]; 14 | } 15 | fast = 0; 16 | while (slow != fast) { 17 | fast = nums[fast]; 18 | slow = nums[slow]; 19 | } 20 | return slow; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0088_MergeSortedArray.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0088_MergeSortedArray { 4 | 5 | public static void merge(int[] nums1, int m, int[] nums2, int n) { 6 | int index = nums1.length; 7 | while (m > 0 && n > 0) { 8 | if (nums1[m - 1] >= nums2[n - 1]) { 9 | nums1[--index] = nums1[--m]; 10 | } else { 11 | nums1[--index] = nums2[--n]; 12 | } 13 | } 14 | while (m > 0) { 15 | nums1[--index] = nums1[--m]; 16 | } 17 | while (n > 0) { 18 | nums1[--index] = nums2[--n]; 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0152_MaximumProductSubarray.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0152_MaximumProductSubarray { 4 | 5 | public static int maxProduct(int[] nums) { 6 | int ans = nums[0]; 7 | int min = nums[0]; 8 | int max = nums[0]; 9 | for (int i = 1; i < nums.length; i++) { 10 | int curmin = Math.min(nums[i], Math.min(min * nums[i], max * nums[i])); 11 | int curmax = Math.max(nums[i], Math.max(min * nums[i], max * nums[i])); 12 | min = curmin; 13 | max = curmax; 14 | ans = Math.max(ans, max); 15 | } 16 | return ans; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0412_FizzBuzz.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Problem_0412_FizzBuzz { 7 | 8 | public static List fizzBuzz(int n) { 9 | ArrayList ans = new ArrayList<>(); 10 | for (int i = 1; i <= n; i++) { 11 | if (i % 15 == 0) { 12 | ans.add("FizzBuzz"); 13 | } else if (i % 5 == 0) { 14 | ans.add("Buzz"); 15 | } else if (i % 3 == 0) { 16 | ans.add("Fizz"); 17 | } else { 18 | ans.add(String.valueOf(i)); 19 | } 20 | } 21 | return ans; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0045_JumpGameII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0045_JumpGameII { 4 | 5 | public static int jump(int[] arr) { 6 | if (arr == null || arr.length == 0) { 7 | return 0; 8 | } 9 | int step = 0; 10 | int cur = 0; 11 | int next = arr[0]; 12 | for (int i = 1; i < arr.length; i++) { 13 | // if(next >= arr.length - 1){ 14 | // return step + 1; 15 | // } 16 | if (cur < i) { 17 | step++; 18 | cur = next; 19 | } 20 | next = Math.max(next, i + arr[i]); 21 | } 22 | return step; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0075_SortColors.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0075_SortColors { 4 | public static void sortColors(int[] nums) { 5 | int less = -1; 6 | int more = nums.length; 7 | int index = 0; 8 | while (index < more) { 9 | if (nums[index] == 1) { 10 | index++; 11 | } else if (nums[index] == 0) { 12 | swap(nums, index++, ++less); 13 | } else { 14 | swap(nums, index, --more); 15 | } 16 | } 17 | } 18 | 19 | public static void swap(int[] nums, int i, int j) { 20 | int tmp = nums[i]; 21 | nums[i] = nums[j]; 22 | nums[j] = tmp; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0268_MissingNumber.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0268_MissingNumber { 4 | 5 | public static int missingNumber(int[] arr) { 6 | int l = 0; 7 | int r = arr.length; 8 | while (l < r) { 9 | if (arr[l] == l) { 10 | l++; 11 | } else if (arr[l] < l || arr[l] >= r || arr[arr[l]] == arr[l]) { 12 | swap(arr, l, --r); 13 | } else { 14 | swap(arr, l, arr[l]); 15 | } 16 | } 17 | return l; 18 | } 19 | 20 | public static void swap(int[] arr, int i, int j) { 21 | int tmp = arr[i]; 22 | arr[i] = arr[j]; 23 | arr[j] = tmp; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0062_UniquePaths.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0062_UniquePaths { 4 | 5 | public static int uniquePaths(int m, int n) { 6 | int part = n - 1; 7 | int all = m + n - 2; 8 | long o1 = 1; 9 | long o2 = 1; 10 | for (int i = part + 1, j = 1; i <= all || j <= all - part; i++, j++) { 11 | o1 *= i; 12 | o2 *= j; 13 | long gcd = gcd(o1,o2); 14 | o1 /= gcd; 15 | o2 /= gcd; 16 | } 17 | return (int)o1; 18 | } 19 | 20 | // 调用的时候,请保证初次调用时,m和n都不为0 21 | public static long gcd(long m, long n) { 22 | return n == 0 ? m : gcd(n, m % n); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0240_SearchA2DMatrixII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0240_SearchA2DMatrixII { 4 | 5 | public static boolean searchMatrix(int[][] m, int target) { 6 | if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) { 7 | return false; 8 | } 9 | int N = m.length; 10 | int M = m[0].length; 11 | int row = 0; 12 | int col = M - 1; 13 | while (row < N && col >= 0) { 14 | if (m[row][col] > target) { 15 | col--; 16 | } else if (m[row][col] < target) { 17 | row++; 18 | } else { 19 | return true; 20 | } 21 | } 22 | return false; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0041_FirstMissingPositive.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0041_FirstMissingPositive { 4 | public static int firstMissingPositive(int[] arr) { 5 | int l = 0; 6 | int r = arr.length; 7 | while (l < r) { 8 | if (arr[l] == l + 1) { 9 | l++; 10 | } else if (arr[l] <= l || arr[l] > r || arr[arr[l] - 1] == arr[l]) { 11 | swap(arr,l,--r); 12 | } else { 13 | swap(arr, l, arr[l] - 1); 14 | } 15 | } 16 | return l + 1; 17 | } 18 | 19 | public static void swap(int[] arr, int i, int j) { 20 | int tmp = arr[i]; 21 | arr[i] = arr[j]; 22 | arr[j] = tmp; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0118_PascalTriangle.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Problem_0118_PascalTriangle { 7 | 8 | public static List> generate(int numRows) { 9 | List> ans = new ArrayList<>(); 10 | for (int i = 0; i < numRows; i++) { 11 | ans.add(new ArrayList<>()); 12 | ans.get(i).add(1); 13 | } 14 | for (int i = 1; i < numRows; i++) { 15 | for (int j = 1; j < i; j++) { 16 | ans.get(i).add(ans.get(i - 1).get(j - 1) + ans.get(i - 1).get(j)); 17 | } 18 | ans.get(i).add(1); 19 | } 20 | return ans; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0277_FindTheCelebrity.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0277_FindTheCelebrity { 4 | 5 | // 提交时不要提交这个函数,只提交下面的方法 6 | public static boolean knows(int x, int i) { 7 | return true; 8 | } 9 | 10 | public int findCelebrity(int n) { 11 | int cand = 0; 12 | for (int i = 0; i < n; ++i) { 13 | if (knows(cand, i)) { 14 | cand = i; 15 | } 16 | } 17 | for (int i = 0; i < cand; ++i) { 18 | if (knows(cand, i)) { 19 | return -1; 20 | } 21 | } 22 | for (int i = 0; i < n; ++i) { 23 | if (!knows(i, cand)) { 24 | return -1; 25 | } 26 | } 27 | return cand; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0012_IntegerToRoman.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0012_IntegerToRoman { 4 | 5 | public static String intToRoman(int num) { 6 | String[][] c = { 7 | { "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" }, 8 | { "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" }, 9 | { "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" }, 10 | { "", "M", "MM", "MMM" } }; 11 | StringBuilder roman = new StringBuilder(); 12 | roman 13 | .append(c[3][num / 1000 % 10]) 14 | .append(c[2][num / 100 % 10]) 15 | .append(c[1][num / 10 % 10]) 16 | .append(c[0][num % 10]); 17 | return roman.toString(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0042_TrappingRainWater.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0042_TrappingRainWater { 4 | 5 | public static int trap(int[] arr) { 6 | if (arr == null || arr.length < 3) { 7 | return 0; 8 | } 9 | int N = arr.length; 10 | int L = 1; 11 | int leftMax = arr[0]; 12 | int R = N - 2; 13 | int rightMax = arr[N - 1]; 14 | int water = 0; 15 | while (L <= R) { 16 | if (leftMax <= rightMax) { 17 | water += Math.max(0, leftMax - arr[L]); 18 | leftMax = Math.max(leftMax, arr[L++]); 19 | } else { 20 | water += Math.max(0, rightMax - arr[R]); 21 | rightMax = Math.max(rightMax, arr[R--]); 22 | } 23 | } 24 | return water; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0162_FindPeakElement.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0162_FindPeakElement { 4 | 5 | public static int findPeakElement(int[] nums) { 6 | int N = nums.length; 7 | if (N < 2) { 8 | return 0; 9 | } 10 | if (nums[0] > nums[1]) { 11 | return 0; 12 | } 13 | if (nums[N - 1] > nums[N - 2]) { 14 | return N - 1; 15 | } 16 | int L = 1; 17 | int R = N - 2; 18 | int M = 0; 19 | while (L < R) { 20 | M = (L + R) / 2; 21 | if (nums[M - 1] < nums[M] && nums[M] > nums[M + 1]) { 22 | return M; 23 | } else if (nums[M - 1] > nums[M]) { 24 | R = M - 1; 25 | } else { 26 | L = M + 1; 27 | } 28 | } 29 | return L; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0191_NumberOf1Bits.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0191_NumberOf1Bits { 4 | 5 | 6 | public static int hammingWeight1(int n) { 7 | int bits = 0; 8 | int rightOne = 0; 9 | while(n != 0) { 10 | bits++; 11 | rightOne = n & (-n); 12 | n ^= rightOne; 13 | } 14 | return bits; 15 | } 16 | 17 | public static int hammingWeight2(int n) { 18 | n = (n & 0x55555555) + ((n >>> 1) & 0x55555555); 19 | n = (n & 0x33333333) + ((n >>> 2) & 0x33333333); 20 | n = (n & 0x0f0f0f0f) + ((n >>> 4) & 0x0f0f0f0f); 21 | n = (n & 0x00ff00ff) + ((n >>> 8) & 0x00ff00ff); 22 | n = (n & 0x0000ffff) + ((n >>> 16) & 0x0000ffff); 23 | return n; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0019_RemoveNthNodeFromEndofList.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0019_RemoveNthNodeFromEndofList { 4 | 5 | public static class ListNode { 6 | public int val; 7 | public ListNode next; 8 | } 9 | 10 | public static ListNode removeNthFromEnd(ListNode head, int n) { 11 | ListNode cur = head; 12 | ListNode pre = null; 13 | while (cur != null) { 14 | n--; 15 | if (n == -1) { 16 | pre = head; 17 | } 18 | if (n < -1) { 19 | pre = pre.next; 20 | } 21 | cur = cur.next; 22 | } 23 | if (n > 0) { 24 | return head; 25 | } 26 | if (pre == null) { 27 | return head.next; 28 | } 29 | pre.next = pre.next.next; 30 | return head; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0128_LongestConsecutiveSequence.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Problem_0128_LongestConsecutiveSequence { 6 | 7 | public static int longestConsecutive(int[] nums) { 8 | HashMap map = new HashMap<>(); 9 | int len = 0; 10 | for (int num : nums) { 11 | if (!map.containsKey(num)) { 12 | map.put(num, 1); 13 | int preLen = map.containsKey(num - 1) ? map.get(num - 1) : 0; 14 | int posLen = map.containsKey(num + 1) ? map.get(num + 1) : 0; 15 | int all = preLen + posLen + 1; 16 | map.put(num - preLen, all); 17 | map.put(num + posLen, all); 18 | len = Math.max(len, all); 19 | } 20 | } 21 | return len; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0014_LongestCommonPrefix.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0014_LongestCommonPrefix { 4 | 5 | public static String longestCommonPrefix(String[] strs) { 6 | if (strs == null || strs.length == 0) { 7 | return ""; 8 | } 9 | char[] chs = strs[0].toCharArray(); 10 | int min = Integer.MAX_VALUE; 11 | for (String str : strs) { 12 | char[] tmp = str.toCharArray(); 13 | int index = 0; 14 | while (index < tmp.length && index < chs.length) { 15 | if (chs[index] != tmp[index]) { 16 | break; 17 | } 18 | index++; 19 | } 20 | min = Math.min(index, min); 21 | if (min == 0) { 22 | return ""; 23 | } 24 | } 25 | return strs[0].substring(0, min); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0123_BestTimeToBuyAndSellStockIII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0123_BestTimeToBuyAndSellStockIII { 4 | 5 | public static int maxProfit(int[] prices) { 6 | if (prices == null || prices.length < 2) { 7 | return 0; 8 | } 9 | int ans = 0; 10 | int doneOnceMinusBuyMax = -prices[0]; 11 | int doneOnceMax = 0;// 0 : [0] - [0] 12 | int min = prices[0]; 13 | for (int i = 1; i < prices.length; i++) { 14 | ans = Math.max(ans, doneOnceMinusBuyMax + prices[i]); 15 | min = Math.min(min, prices[i]); 16 | doneOnceMax = Math.max(doneOnceMax, prices[i] - min); 17 | doneOnceMinusBuyMax = Math.max(doneOnceMinusBuyMax, doneOnceMax - prices[i]); 18 | } 19 | return ans; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0036_ValidSudoku.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0036_ValidSudoku { 4 | 5 | public static boolean isValidSudoku(char[][] board) { 6 | boolean[][] row = new boolean[9][10]; 7 | boolean[][] col = new boolean[9][10]; 8 | boolean[][] bucket = new boolean[9][10]; 9 | for (int i = 0; i < 9; i++) { 10 | for (int j = 0; j < 9; j++) { 11 | int bid = 3 * (i / 3) + (j / 3); 12 | if (board[i][j] != '.') { 13 | int num = board[i][j] - '0'; 14 | if (row[i][num] || col[j][num] || bucket[bid][num]) { 15 | return false; 16 | } 17 | row[i][num] = true; 18 | col[j][num] = true; 19 | bucket[bid][num] = true; 20 | } 21 | } 22 | } 23 | return true; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0101_SymmetricTree.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0101_SymmetricTree { 4 | 5 | public static class TreeNode { 6 | int val; 7 | TreeNode left; 8 | TreeNode right; 9 | } 10 | 11 | public boolean isSymmetric(TreeNode root) { 12 | return isMirror(root, root); 13 | } 14 | 15 | // 一棵树是原始树 head1 16 | // 另一棵是翻面树 head2 17 | public static boolean isMirror(TreeNode head1, TreeNode head2) { 18 | if (head1 == null && head2 == null) { 19 | return true; 20 | } 21 | if (head1 != null && head2 != null) { 22 | return head1.val == head2.val 23 | && isMirror(head1.left, head2.right) 24 | && isMirror(head1.right, head2.left); 25 | } 26 | // 一个为空,一个不为空 false 27 | return false; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0048_RotateImage.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0048_RotateImage { 4 | 5 | public static void rotate(int[][] matrix) { 6 | // matrix.len == matrix[0].len 7 | int tR = 0; 8 | int tC = 0; 9 | int dR = matrix.length - 1; 10 | int dC = matrix[0].length - 1; 11 | while (tR < dR) { 12 | rotateEdge(matrix, tR++, tC++, dR--, dC--); 13 | } 14 | } 15 | 16 | public static void rotateEdge(int[][] m, int tR, int tC, int dR, int dC) { 17 | int times = dC - tC; 18 | int tmp = 0; 19 | for (int i = 0; i != times; i++) { 20 | tmp = m[tR][tC + i]; 21 | m[tR][tC + i] = m[dR - i][tC]; 22 | m[dR - i][tC] = m[dR][dC - i]; 23 | m[dR][dC - i] = m[tR + i][dC]; 24 | m[tR + i][dC] = tmp; 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0384_ShuffleAnArray.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0384_ShuffleAnArray { 4 | 5 | class Solution { 6 | private int[] origin; 7 | private int[] shuffle; 8 | private int N; 9 | 10 | public Solution(int[] nums) { 11 | origin = nums; 12 | N = nums.length; 13 | shuffle = new int[N]; 14 | for (int i = 0; i < N; i++) { 15 | shuffle[i] = origin[i]; 16 | } 17 | } 18 | 19 | public int[] reset() { 20 | return origin; 21 | } 22 | 23 | public int[] shuffle() { 24 | for (int i = N - 1; i >= 0; i--) { 25 | int r = (int) (Math.random() * (i + 1)); 26 | int tmp = shuffle[r]; 27 | shuffle[r] = shuffle[i]; 28 | shuffle[i] = tmp; 29 | } 30 | return shuffle; 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0020_ValidParentheses.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.Stack; 4 | 5 | public class Problem_0020_ValidParentheses { 6 | 7 | public static boolean isValid(String s) { 8 | if (s == null || s.length() == 0) { 9 | return true; 10 | } 11 | char[] str = s.toCharArray(); 12 | Stack stack = new Stack<>(); 13 | for (int i = 0; i < str.length; i++) { 14 | char cha = str[i]; 15 | if (cha == '(' || cha == '[' || cha == '{') { 16 | stack.add(cha == '(' ? ')' : (cha == '[' ? ']' : '}')); 17 | } else { 18 | if (stack.isEmpty()) { 19 | return false; 20 | } 21 | char last = stack.pop(); 22 | if (cha != last) { 23 | return false; 24 | } 25 | } 26 | } 27 | return stack.isEmpty(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0300_LongestIncreasingSubsequence.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0300_LongestIncreasingSubsequence { 4 | 5 | public static int lengthOfLIS(int[] arr) { 6 | if (arr == null || arr.length == 0) { 7 | return 0; 8 | } 9 | int[] ends = new int[arr.length]; 10 | ends[0] = arr[0]; 11 | int right = 0; 12 | int l = 0; 13 | int r = 0; 14 | int m = 0; 15 | int max = 1; 16 | for (int i = 1; i < arr.length; i++) { 17 | l = 0; 18 | r = right; 19 | while (l <= r) { 20 | m = (l + r) / 2; 21 | if (arr[i] > ends[m]) { 22 | l = m + 1; 23 | } else { 24 | r = m - 1; 25 | } 26 | } 27 | right = Math.max(right, l); 28 | ends[l] = arr[i]; 29 | max = Math.max(max, l + 1); 30 | } 31 | return max; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0155_MinStack.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.Stack; 4 | 5 | /* 6 | * 在leetcode上提交时,把文字替换成下面的代码 7 | * 然后把类名、构造方法名从Problem_0155_MinStack改为MinStack即可 8 | */ 9 | public class Problem_0155_MinStack { 10 | 11 | private Stack data; 12 | private Stack min; 13 | 14 | public Problem_0155_MinStack() { 15 | data = new Stack<>(); 16 | min = new Stack<>(); 17 | } 18 | 19 | public void push(int x) { 20 | data.push(x); 21 | if (min.isEmpty()) { 22 | min.push(x); 23 | } else { 24 | min.push(Math.min(min.peek(), x)); 25 | } 26 | } 27 | 28 | public void pop() { 29 | data.pop(); 30 | min.pop(); 31 | } 32 | 33 | public int top() { 34 | return data.peek(); 35 | } 36 | 37 | public int getMin() { 38 | return min.peek(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0334_IncreasingTripletSubsequence.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0334_IncreasingTripletSubsequence { 4 | 5 | public static boolean increasingTriplet(int[] arr) { 6 | if (arr == null || arr.length < 3) { 7 | return false; 8 | } 9 | int[] ends = new int[3]; 10 | ends[0] = arr[0]; 11 | int right = 0; 12 | int l = 0; 13 | int r = 0; 14 | int m = 0; 15 | for (int i = 1; i < arr.length; i++) { 16 | l = 0; 17 | r = right; 18 | while (l <= r) { 19 | m = (l + r) / 2; 20 | if (arr[i] > ends[m]) { 21 | l = m + 1; 22 | } else { 23 | r = m - 1; 24 | } 25 | } 26 | right = Math.max(right, l); 27 | if (right > 1) { 28 | return true; 29 | } 30 | ends[l] = arr[i]; 31 | } 32 | return false; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0239_SlidingWindowMaximum.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class Problem_0239_SlidingWindowMaximum { 6 | 7 | public static int[] maxSlidingWindow(int[] arr, int w) { 8 | if (arr == null || w < 1 || arr.length < w) { 9 | return null; 10 | } 11 | LinkedList qmax = new LinkedList(); 12 | int[] res = new int[arr.length - w + 1]; 13 | int index = 0; 14 | for (int R = 0; R < arr.length; R++) { 15 | while (!qmax.isEmpty() && arr[qmax.peekLast()] <= arr[R]) { 16 | qmax.pollLast(); 17 | } 18 | qmax.addLast(R); 19 | if (qmax.peekFirst() == R - w) { 20 | qmax.pollFirst(); 21 | } 22 | if (R >= w - 1) { 23 | res[index++] = arr[qmax.peekFirst()]; 24 | } 25 | } 26 | return res; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0454_4SumII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Problem_0454_4SumII { 6 | 7 | public static int fourSumCount(int[] A, int[] B, int[] C, int[] D) { 8 | HashMap map = new HashMap<>(); 9 | int sum = 0; 10 | for (int i = 0; i < A.length; i++) { 11 | for (int j = 0; j < B.length; j++) { 12 | sum = A[i] + B[j]; 13 | if (!map.containsKey(sum)) { 14 | map.put(sum, 1); 15 | } else { 16 | map.put(sum, map.get(sum) + 1); 17 | } 18 | } 19 | } 20 | int ans = 0; 21 | for (int i = 0; i < C.length; i++) { 22 | for (int j = 0; j < D.length; j++) { 23 | sum = C[i] + D[j]; 24 | if (map.containsKey(-sum)) { 25 | ans += map.get(-sum); 26 | } 27 | } 28 | } 29 | return ans; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0108_ConvertSortedArrayToBinarySearchTree.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0108_ConvertSortedArrayToBinarySearchTree { 4 | 5 | public static class TreeNode { 6 | int val; 7 | TreeNode left; 8 | TreeNode right; 9 | 10 | TreeNode(int val) { 11 | this.val = val; 12 | } 13 | } 14 | 15 | public TreeNode sortedArrayToBST(int[] nums) { 16 | return process(nums, 0, nums.length - 1); 17 | } 18 | 19 | public static TreeNode process(int[] nums, int L, int R) { 20 | if (L > R) { 21 | return null; 22 | } 23 | if (L == R) { 24 | return new TreeNode(nums[L]); 25 | } 26 | int M = (L + R) / 2; 27 | TreeNode head = new TreeNode(nums[M]); 28 | head.left = process(nums, L, M - 1); 29 | head.right = process(nums, M + 1, R); 30 | return head; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0021_MergeTwoSortedLists.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0021_MergeTwoSortedLists { 4 | 5 | public static class ListNode { 6 | public int val; 7 | public ListNode next; 8 | } 9 | 10 | public static ListNode mergeTwoLists(ListNode l1, ListNode l2) { 11 | if (l1 == null || l2 == null) { 12 | return l1 == null ? l2 : l1; 13 | } 14 | ListNode head = l1.val <= l2.val ? l1 : l2; 15 | ListNode cur1 = head.next; 16 | ListNode cur2 = head == l1 ? l2 : l1; 17 | ListNode pre = head; 18 | while (cur1 != null && cur2 != null) { 19 | if (cur1.val <= cur2.val) { 20 | pre.next = cur1; 21 | cur1 = cur1.next; 22 | } else { 23 | pre.next = cur2; 24 | cur2 = cur2.next; 25 | } 26 | pre = pre.next; 27 | } 28 | pre.next = cur1 != null ? cur1 : cur2; 29 | return head; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0340_LongestSubstringWithAtMostKDistinctCharacters.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0340_LongestSubstringWithAtMostKDistinctCharacters { 4 | 5 | public static int lengthOfLongestSubstringKDistinct(String s, int k) { 6 | if (s == null || s.length() == 0 || k < 1) { 7 | return 0; 8 | } 9 | char[] str = s.toCharArray(); 10 | int N = str.length; 11 | int[] count = new int[256]; 12 | int diff = 0; 13 | int R = 0; 14 | int ans = 0; 15 | for (int i = 0; i < N; i++) { 16 | // R 窗口的右边界 17 | while (R < N && (diff < k || (diff == k && count[str[R]] > 0))) { 18 | diff += count[str[R]] == 0 ? 1 : 0; 19 | count[str[R++]]++; 20 | } 21 | // R 来到违规的第一个位置 22 | ans = Math.max(ans, R - i); 23 | diff -= count[str[i]] == 1 ? 1 : 0; 24 | count[str[i]]--; 25 | } 26 | return ans; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0038_CountAndSay.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0038_CountAndSay { 4 | 5 | public static String countAndSay(int n) { 6 | if (n < 1) { 7 | return ""; 8 | } 9 | if (n == 1) { 10 | return "1"; 11 | } 12 | char[] last = countAndSay(n - 1).toCharArray(); 13 | StringBuilder ans = new StringBuilder(); 14 | int times = 1; 15 | for (int i = 1; i < last.length; i++) { 16 | if (last[i - 1] == last[i]) { 17 | times++; 18 | } else { 19 | ans.append(String.valueOf(times)); 20 | ans.append(String.valueOf(last[i - 1])); 21 | times = 1; 22 | } 23 | } 24 | ans.append(String.valueOf(times)); 25 | ans.append(String.valueOf(last[last.length - 1])); 26 | return ans.toString(); 27 | } 28 | 29 | public static void main(String[] args) { 30 | System.out.println(countAndSay(20)); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0003_LongestSubstringWithoutRepeatingCharacters.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0003_LongestSubstringWithoutRepeatingCharacters { 4 | 5 | public static int lengthOfLongestSubstring(String s) { 6 | if (s == null || s.equals("")) { 7 | return 0; 8 | } 9 | char[] str = s.toCharArray(); 10 | // map (a, ?) (b, ?) 11 | // a, 17 12 | // map[97] = 17 13 | int[] map = new int[256]; 14 | for (int i = 0; i < 256; i++) { 15 | map[i] = -1; 16 | } 17 | // 收集答案 18 | int len = 0; 19 | int pre = -1; // i-1位置结尾的情况下,往左推,推不动的位置是谁 20 | int cur = 0; 21 | for (int i = 0; i != str.length; i++) { 22 | // i位置结尾的情况下,往左推,推不动的位置是谁 23 | // pre (i-1信息) -> pre(i 结尾信息) 24 | pre = Math.max(pre, map[str[i]]); 25 | cur = i - pre; 26 | len = Math.max(len, cur); 27 | map[str[i]] = i; 28 | } 29 | return len; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0141_LinkedListCycle.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0141_LinkedListCycle { 4 | 5 | public static class ListNode { 6 | int val; 7 | ListNode next; 8 | } 9 | 10 | public static boolean hasCycle(ListNode head) { 11 | return getFirstLoopNode(head) != null; 12 | } 13 | 14 | public static ListNode getFirstLoopNode(ListNode head) { 15 | if (head == null || head.next == null || head.next.next == null) { 16 | return null; 17 | } 18 | ListNode slow = head.next; 19 | ListNode fast = head.next.next; 20 | while (slow != fast) { 21 | if (fast.next == null || fast.next.next == null) { 22 | return null; 23 | } 24 | fast = fast.next.next; 25 | slow = slow.next; 26 | } 27 | fast = head; 28 | while (slow != fast) { 29 | slow = slow.next; 30 | fast = fast.next; 31 | } 32 | return slow; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0213_HouseRobberII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0213_HouseRobberII { 4 | 5 | public static int rob(int[] nums) { 6 | if (nums == null || nums.length == 0) { 7 | return 0; 8 | } 9 | if (nums.length == 1) { 10 | return nums[0]; 11 | } 12 | if (nums.length == 2) { 13 | return Math.max(nums[0], nums[1]); 14 | } 15 | int pre2 = nums[0]; 16 | int pre1 = Math.max(nums[0], nums[1]); 17 | for (int i = 2; i < nums.length - 1; i++) { 18 | int tmp = Math.max(pre1, nums[i] + pre2); 19 | pre2 = pre1; 20 | pre1 = tmp; 21 | } 22 | int ans1 = pre1; 23 | pre2 = nums[1]; 24 | pre1 = Math.max(nums[1], nums[2]); 25 | for (int i = 3; i < nums.length; i++) { 26 | int tmp = Math.max(pre1, nums[i] + pre2); 27 | pre2 = pre1; 28 | pre1 = tmp; 29 | } 30 | int ans2 = pre1; 31 | return Math.max(ans1, ans2); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0163_MissingRanges.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Problem_0163_MissingRanges { 7 | 8 | public static List findMissingRanges(int[] nums, int lower, int upper) { 9 | List ans = new ArrayList<>(); 10 | for (int num : nums) { 11 | if (num > lower) { 12 | ans.add(miss(lower, num - 1)); 13 | } 14 | if (num == upper) { 15 | return ans; 16 | } 17 | lower = num + 1; 18 | } 19 | if (lower <= upper) { 20 | ans.add(miss(lower, upper)); 21 | } 22 | return ans; 23 | } 24 | 25 | // 生成"lower->upper"的字符串,如果lower==upper,只用生成"lower" 26 | public static String miss(int lower, int upper) { 27 | String left = String.valueOf(lower); 28 | String right = ""; 29 | if (upper > lower) { 30 | right = "->" + String.valueOf(upper); 31 | } 32 | return left + right; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0200_NumberOfIslands.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0200_NumberOfIslands { 4 | 5 | public static int numIslands(char[][] m) { 6 | if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) { 7 | return 0; 8 | } 9 | int N = m.length; 10 | int M = m[0].length; 11 | int res = 0; 12 | for (int i = 0; i < N; i++) { 13 | for (int j = 0; j < M; j++) { 14 | if (m[i][j] == '1') { 15 | res++; 16 | infect(m, i, j, N, M); 17 | } 18 | } 19 | } 20 | return res; 21 | } 22 | 23 | // 目前来到m[i][j], 经历上下左右的感染过程 24 | public static void infect(char[][] m, int i, int j, int N, int M) { 25 | if (i < 0 || i >= N || j < 0 || j >= M || m[i][j] != '1') { 26 | return; 27 | } 28 | m[i][j] = '2'; 29 | infect(m, i + 1, j, N, M); 30 | infect(m, i - 1, j, N, M); 31 | infect(m, i, j + 1, N, M); 32 | infect(m, i, j - 1, N, M); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0202_HappyNumber.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.HashSet; 4 | 5 | public class Problem_0202_HappyNumber { 6 | 7 | public static boolean isHappy1(int n) { 8 | HashSet set = new HashSet<>(); 9 | while (n != 1) { 10 | int sum = 0; 11 | while (n != 0) { 12 | int r = n % 10; 13 | sum += r * r; 14 | n /= 10; 15 | } 16 | n = sum; 17 | if (set.contains(n)) { 18 | break; 19 | } 20 | set.add(n); 21 | } 22 | return n == 1; 23 | } 24 | 25 | public static boolean isHappy2(int n) { 26 | while (n != 1 && n != 4) { 27 | int sum = 0; 28 | while (n != 0) { 29 | sum += (n % 10) * (n % 10); 30 | n /= 10; 31 | } 32 | n = sum; 33 | } 34 | return n == 1; 35 | } 36 | 37 | public static void main(String[] args) { 38 | for (int i = 1; i < 1000; i++) { 39 | System.out.println(i + " : " + isHappy1(i)); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0013_RomanToInteger.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0013_RomanToInteger { 4 | 5 | public static int romanToInt(String s) { 6 | int nums[] = new int[s.length()]; 7 | for (int i = 0; i < s.length(); i++) { 8 | switch (s.charAt(i)) { 9 | case 'M': 10 | nums[i] = 1000; 11 | break; 12 | case 'D': 13 | nums[i] = 500; 14 | break; 15 | case 'C': 16 | nums[i] = 100; 17 | break; 18 | case 'L': 19 | nums[i] = 50; 20 | break; 21 | case 'X': 22 | nums[i] = 10; 23 | break; 24 | case 'V': 25 | nums[i] = 5; 26 | break; 27 | case 'I': 28 | nums[i] = 1; 29 | break; 30 | } 31 | } 32 | int sum = 0; 33 | for (int i = 0; i < nums.length - 1; i++) { 34 | if (nums[i] < nums[i + 1]) { 35 | sum -= nums[i]; 36 | } else { 37 | sum += nums[i]; 38 | } 39 | } 40 | return sum + nums[nums.length - 1]; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0198_HouseRobber.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0198_HouseRobber { 4 | 5 | public static int rob1(int[] nums) { 6 | if (nums == null || nums.length == 0) { 7 | return 0; 8 | } 9 | if (nums.length == 1) { 10 | return nums[0]; 11 | } 12 | int N = nums.length; 13 | int[] dp = new int[N]; 14 | dp[0] = nums[0]; 15 | dp[1] = Math.max(nums[0], nums[1]); 16 | for (int i = 2; i < N; i++) { 17 | dp[i] = Math.max(dp[i - 1], nums[i] + dp[i - 2]); 18 | } 19 | return dp[N - 1]; 20 | } 21 | 22 | public static int rob2(int[] nums) { 23 | if (nums == null || nums.length == 0) { 24 | return 0; 25 | } 26 | if (nums.length == 1) { 27 | return nums[0]; 28 | } 29 | int pre2 = nums[0]; 30 | int pre1 = Math.max(nums[0], nums[1]); 31 | for (int i = 2; i < nums.length; i++) { 32 | int cur = Math.max(pre1, nums[i] + pre2); 33 | pre2 = pre1; 34 | pre1 = cur; 35 | } 36 | return pre1; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0230_KthSmallestElementInBST.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0230_KthSmallestElementInBST { 4 | 5 | public static class TreeNode { 6 | public int val; 7 | public TreeNode left; 8 | public TreeNode right; 9 | } 10 | 11 | public static int kthSmallest(TreeNode head, int k) { 12 | if (head == null) { 13 | return -1; 14 | } 15 | TreeNode cur = head; 16 | TreeNode mostRight = null; 17 | int index = 1; 18 | while (cur != null) { 19 | mostRight = cur.left; 20 | if (mostRight != null) { 21 | while (mostRight.right != null && mostRight.right != cur) { 22 | mostRight = mostRight.right; 23 | } 24 | if (mostRight.right == null) { 25 | mostRight.right = cur; 26 | cur = cur.left; 27 | continue; 28 | } else { 29 | mostRight.right = null; 30 | } 31 | } 32 | if (index++ == k) { 33 | return cur.val; 34 | } 35 | cur = cur.right; 36 | } 37 | return -1; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0150_EvaluateReversePolishNotation.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.Stack; 4 | 5 | public class Problem_0150_EvaluateReversePolishNotation { 6 | 7 | public static int evalRPN(String[] tokens) { 8 | Stack stack = new Stack<>(); 9 | for (String str : tokens) { 10 | if (str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/")) { 11 | compute(stack, str); 12 | } else { 13 | stack.push(Integer.valueOf(str)); 14 | } 15 | } 16 | return stack.peek(); 17 | } 18 | 19 | public static void compute(Stack stack, String op) { 20 | int num2 = stack.pop(); 21 | int num1 = stack.pop(); 22 | int ans = 0; 23 | switch (op) { 24 | case "+": 25 | ans = num1 + num2; 26 | break; 27 | case "-": 28 | ans = num1 - num2; 29 | break; 30 | case "*": 31 | ans = num1 * num2; 32 | break; 33 | case "/": 34 | ans = num1 / num2; 35 | break; 36 | } 37 | stack.push(ans); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0084_LargestRectangleInHistogram.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.Stack; 4 | 5 | public class Problem_0084_LargestRectangleInHistogram { 6 | 7 | public static int largestRectangleArea(int[] height) { 8 | if (height == null || height.length == 0) { 9 | return 0; 10 | } 11 | int maxArea = 0; 12 | // 只放下标 13 | Stack stack = new Stack(); 14 | for (int i = 0; i < height.length; i++) { 15 | while (!stack.isEmpty() && height[i] <= height[stack.peek()]) { 16 | int j = stack.pop(); 17 | int k = stack.isEmpty() ? -1 : stack.peek(); 18 | int curArea = (i - k - 1) * height[j]; 19 | maxArea = Math.max(maxArea, curArea); 20 | } 21 | stack.push(i); 22 | } 23 | while (!stack.isEmpty()) { 24 | int j = stack.pop(); 25 | int k = stack.isEmpty() ? -1 : stack.peek(); 26 | int curArea = (height.length - k - 1) * height[j]; 27 | maxArea = Math.max(maxArea, curArea); 28 | } 29 | return maxArea; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0098_ValidateBinarySearchTree.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0098_ValidateBinarySearchTree { 4 | 5 | public static class TreeNode { 6 | int val; 7 | TreeNode left; 8 | TreeNode right; 9 | } 10 | 11 | public boolean isValidBST(TreeNode root) { 12 | if (root == null) { 13 | return true; 14 | } 15 | TreeNode cur = root; 16 | TreeNode mostRight = null; 17 | Integer pre = null; 18 | boolean ans = true; 19 | while (cur != null) { 20 | mostRight = cur.left; 21 | if (mostRight != null) { 22 | while (mostRight.right != null && mostRight.right != cur) { 23 | mostRight = mostRight.right; 24 | } 25 | if (mostRight.right == null) { 26 | mostRight.right = cur; 27 | cur = cur.left; 28 | continue; 29 | } else { 30 | mostRight.right = null; 31 | } 32 | } 33 | if (pre != null && pre >= cur.val) { 34 | ans = false; 35 | } 36 | pre = cur.val; 37 | cur = cur.right; 38 | } 39 | return ans; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0094_BinaryTreeInorderTraversal.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Problem_0094_BinaryTreeInorderTraversal { 7 | 8 | public static class TreeNode { 9 | int val; 10 | TreeNode left; 11 | TreeNode right; 12 | } 13 | 14 | public static List inorderTraversal(TreeNode root) { 15 | List ans = new ArrayList<>(); 16 | if (root == null) { 17 | return ans; 18 | } 19 | TreeNode cur = root; 20 | TreeNode mostRight = null; 21 | while (cur != null) { 22 | mostRight = cur.left; 23 | if (mostRight != null) { 24 | while (mostRight.right != null && mostRight.right != cur) { 25 | mostRight = mostRight.right; 26 | } 27 | if (mostRight.right == null) { 28 | mostRight.right = cur; 29 | cur = cur.left; 30 | continue; 31 | } else { 32 | mostRight.right = null; 33 | } 34 | } 35 | ans.add(cur.val); 36 | cur = cur.right; 37 | } 38 | return ans; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0160_IntersectionOfTwoLinkedLists.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0160_IntersectionOfTwoLinkedLists { 4 | 5 | public class ListNode { 6 | int val; 7 | ListNode next; 8 | } 9 | 10 | public static ListNode getIntersectionNode(ListNode head1, ListNode head2) { 11 | if (head1 == null || head2 == null) { 12 | return null; 13 | } 14 | ListNode cur1 = head1; 15 | ListNode cur2 = head2; 16 | int n = 0; 17 | while (cur1.next != null) { 18 | n++; 19 | cur1 = cur1.next; 20 | } 21 | // cur1 end1 22 | while (cur2.next != null) { 23 | n--; 24 | cur2 = cur2.next; 25 | } 26 | // cur2 end2 27 | if (cur1 != cur2) { 28 | return null; 29 | } 30 | cur1 = n > 0 ? head1 : head2; // 谁是长链表,谁把头节点,给cur1赋值 31 | cur2 = cur1 == head1 ? head2 : head1; 32 | n = Math.abs(n); 33 | while (n != 0) { 34 | n--; 35 | cur1 = cur1.next; 36 | } 37 | while (cur1 != cur2) { 38 | cur1 = cur1.next; 39 | cur2 = cur2.next; 40 | } 41 | return cur1; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0285_InorderSuccessorInBST.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0285_InorderSuccessorInBST { 4 | 5 | public static class TreeNode { 6 | public int val; 7 | public TreeNode left; 8 | public TreeNode right; 9 | } 10 | 11 | public static TreeNode inorderSuccessor(TreeNode head, TreeNode p) { 12 | if (head == null) { 13 | return null; 14 | } 15 | TreeNode cur = head; 16 | TreeNode mostRight = null; 17 | TreeNode pre = null; 18 | while (cur != null) { 19 | mostRight = cur.left; 20 | if (mostRight != null) { 21 | while (mostRight.right != null && mostRight.right != cur) { 22 | mostRight = mostRight.right; 23 | } 24 | if (mostRight.right == null) { 25 | mostRight.right = cur; 26 | cur = cur.left; 27 | continue; 28 | } else { 29 | mostRight.right = null; 30 | } 31 | } 32 | if (pre == p) { 33 | return cur; 34 | } else { 35 | pre = cur; 36 | } 37 | cur = cur.right; 38 | } 39 | return null; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0179_LargestNumber.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.Arrays; 4 | import java.util.Comparator; 5 | 6 | public class Problem_0179_LargestNumber { 7 | 8 | public static class MyComparator implements Comparator { 9 | 10 | @Override 11 | public int compare(String o1, String o2) { 12 | return (o2 + o1).compareTo(o1 + o2); 13 | } 14 | 15 | } 16 | 17 | public String largestNumber(int[] nums) { 18 | String[] strs = new String[nums.length]; 19 | for (int i = 0; i < nums.length; i++) { 20 | strs[i] = String.valueOf(nums[i]); 21 | } 22 | Arrays.sort(strs, new MyComparator()); 23 | StringBuilder builder = new StringBuilder(); 24 | for (String str : strs) { 25 | builder.append(str); 26 | } 27 | String ans = builder.toString(); 28 | char[] str = ans.toCharArray(); 29 | int index = -1; 30 | for (int i = 0; i < str.length; i++) { 31 | if (str[i] != '0') { 32 | index = i; 33 | break; 34 | } 35 | } 36 | return index == -1 ? "0" : ans.substring(index); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0328_OddEvenLinkedList.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0328_OddEvenLinkedList { 4 | 5 | // 提交时不要提交这个类 6 | public static class ListNode { 7 | int val; 8 | ListNode next; 9 | } 10 | 11 | public ListNode oddEvenList(ListNode head) { 12 | ListNode firstOdd = null; 13 | ListNode firstEven = null; 14 | ListNode odd = null; 15 | ListNode even = null; 16 | ListNode next = null; 17 | int count = 1; 18 | while (head != null) { 19 | next = head.next; 20 | head.next = null; 21 | if ((count & 1) == 1) { 22 | firstOdd = firstOdd == null ? head : firstOdd; 23 | if (odd != null) { 24 | odd.next = head; 25 | } 26 | odd = head; 27 | } else { 28 | firstEven = firstEven == null ? head : firstEven; 29 | if (even != null) { 30 | even.next = head; 31 | } 32 | even = head; 33 | } 34 | count++; 35 | head = next; 36 | } 37 | if (odd != null) { 38 | odd.next = firstEven; 39 | } 40 | return firstOdd != null ? firstOdd : firstEven; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0348_DesignTicTacToe.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0348_DesignTicTacToe { 4 | 5 | class TicTacToe { 6 | private int[][] rows; 7 | private int[][] cols; 8 | private int[] leftUp; 9 | private int[] rightUp; 10 | private boolean[][] matrix; 11 | private int N; 12 | 13 | public TicTacToe(int n) { 14 | rows = new int[n][3]; //0 1 2 15 | cols = new int[n][3]; 16 | leftUp = new int[3]; // 1 2 17 | rightUp = new int[3]; // 1 2 18 | matrix = new boolean[n][n]; 19 | N = n; 20 | } 21 | 22 | public int move(int row, int col, int player) { 23 | if (matrix[row][col]) { 24 | return 0; 25 | } 26 | matrix[row][col] = true; 27 | rows[row][player]++; 28 | cols[col][player]++; 29 | if (row == col) { 30 | leftUp[player]++; 31 | } 32 | if (row + col == N - 1) { 33 | rightUp[player]++; 34 | } 35 | if (rows[row][player] == N || cols[col][player] == N || leftUp[player] == N || rightUp[player] == N) { 36 | return player; 37 | } 38 | return 0; 39 | } 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0102_BinaryTreeLevelOrderTraversal.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | public class Problem_0102_BinaryTreeLevelOrderTraversal { 8 | 9 | public static class TreeNode { 10 | int val; 11 | TreeNode left; 12 | TreeNode right; 13 | } 14 | 15 | public static List> levelOrder(TreeNode root) { 16 | List> ans = new ArrayList<>(); 17 | if (root == null) { 18 | return ans; 19 | } 20 | LinkedList deque = new LinkedList<>(); 21 | deque.add(root); 22 | int size = 0; 23 | while(!deque.isEmpty()) { 24 | size = deque.size(); 25 | List curLevel = new ArrayList<>(); 26 | for(int i = 0 ; i< size;i++) { 27 | TreeNode cur = deque.pollLast(); 28 | curLevel.add(cur.val); 29 | if(cur.left != null) { 30 | deque.addFirst(cur.left); 31 | } 32 | if(cur.right != null) { 33 | deque.addFirst(cur.right); 34 | } 35 | } 36 | ans.add(curLevel); 37 | } 38 | return ans; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0076_MinimumWindowSubstring.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0076_MinimumWindowSubstring { 4 | 5 | public static String minWindow(String s, String t) { 6 | if (s.length() < t.length()) { 7 | return ""; 8 | } 9 | char[] str = s.toCharArray(); 10 | char[] target = t.toCharArray(); 11 | int[] map = new int[256]; 12 | for (char cha : target) { 13 | map[cha]++; 14 | } 15 | int all = target.length; 16 | int L = 0; 17 | int R = 0; 18 | // -1(从来没找到过合法的) 19 | int minLen = -1; 20 | int ansl = -1; 21 | int ansr = -1; 22 | // [L..R) [0,0) R 23 | while (R != str.length) { 24 | map[str[R]]--; 25 | if (map[str[R]] >= 0) { 26 | all--; 27 | } 28 | if (all == 0) { 29 | while (map[str[L]] < 0) { 30 | map[str[L++]]++; 31 | } 32 | if (minLen == -1 || minLen > R - L + 1) { 33 | minLen = R - L + 1; 34 | ansl = L; 35 | ansr = R; 36 | } 37 | all++; 38 | map[str[L++]]++; 39 | } 40 | R++; 41 | } 42 | return minLen == -1 ? "" : s.substring(ansl, ansr + 1); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0251_Flatten2DVector.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0251_Flatten2DVector { 4 | 5 | public static class Vector2D { 6 | private int[][] matrix; 7 | private int row; 8 | private int col; 9 | private boolean curUse; 10 | 11 | public Vector2D(int[][] v) { 12 | matrix = v; 13 | row = 0; 14 | col = -1; 15 | curUse = true; 16 | hasNext(); 17 | } 18 | 19 | public int next() { 20 | int ans = matrix[row][col]; 21 | curUse = true; 22 | hasNext(); 23 | return ans; 24 | } 25 | 26 | public boolean hasNext() { 27 | if (row == matrix.length) { 28 | return false; 29 | } 30 | if (!curUse) { 31 | return true; 32 | } 33 | // (row,col)用过了 34 | if (col < matrix[row].length - 1) { 35 | col++; 36 | } else { 37 | col = 0; 38 | do { 39 | row++; 40 | } while (row < matrix.length && matrix[row].length == 0); 41 | } 42 | // 新的(row,col) 43 | if (row != matrix.length) { 44 | curUse = false; 45 | return true; 46 | } else { 47 | return false; 48 | } 49 | } 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0079_WordSearch.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0079_WordSearch { 4 | 5 | public static boolean exist(char[][] board, String word) { 6 | char[] w = word.toCharArray(); 7 | for (int i = 0; i < board.length; i++) { 8 | for (int j = 0; j < board[0].length; j++) { 9 | if (process(board, i, j, w, 0)) { 10 | return true; 11 | } 12 | } 13 | } 14 | return false; 15 | } 16 | 17 | // 目前到达了b[i][j],word[k....] 18 | // 从b[i][j]出发,能不能搞定word[k....] true false 19 | public static boolean process(char[][] b, int i, int j, char[] w, int k) { 20 | if(k == w.length) { 21 | return true; 22 | } 23 | // k 有字符 24 | if (i < 0 || i == b.length || j < 0 || j == b[0].length) { 25 | return false; 26 | } 27 | if (b[i][j] != w[k]) { 28 | return false; 29 | } 30 | char tmp = b[i][j]; 31 | b[i][j] = 0; 32 | boolean ans = process(b, i - 1, j, w, k + 1) 33 | || process(b, i + 1, j, w, k + 1) 34 | || process(b, i, j - 1, w, k + 1) 35 | || process(b, i, j + 1, w, k + 1); 36 | b[i][j] = tmp; 37 | return ans; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0078_Subsets.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | public class Problem_0078_Subsets { 8 | 9 | public static List> subsets(int[] nums) { 10 | List> ans = new ArrayList<>(); 11 | LinkedList path = new LinkedList<>(); 12 | process(nums, 0, path, ans); 13 | return ans; 14 | } 15 | 16 | // 当前来到index位置,做决定,1)不要当前位置的数 2)要当前位置的数 17 | // 如果要当前位置的数,把该数字,放入到path中去 18 | // 如果不要当前位置的数,不把该数字,放入到path中去 19 | public static void process(int nums[], int index, LinkedList path, List> ans) { 20 | if (index == nums.length) { 21 | ans.add(copy(path)); 22 | } else { 23 | process(nums, index + 1, path, ans); 24 | path.addLast(nums[index]); 25 | process(nums, index + 1, path, ans); 26 | path.removeLast(); 27 | } 28 | } 29 | 30 | public static ArrayList copy(LinkedList path) { 31 | ArrayList ans = new ArrayList<>(); 32 | for (Integer num : path) { 33 | ans.add(num); 34 | } 35 | return ans; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0234_PalindromeLinkedList.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0234_PalindromeLinkedList { 4 | 5 | public static class ListNode { 6 | public int val; 7 | public ListNode next; 8 | } 9 | 10 | public static boolean isPalindrome(ListNode head) { 11 | if (head == null || head.next == null) { 12 | return true; 13 | } 14 | ListNode n1 = head; 15 | ListNode n2 = head; 16 | while (n2.next != null && n2.next.next != null) { 17 | n1 = n1.next; 18 | n2 = n2.next.next; 19 | } 20 | n2 = n1.next; 21 | n1.next = null; 22 | ListNode n3 = null; 23 | while (n2 != null) { 24 | n3 = n2.next; 25 | n2.next = n1; 26 | n1 = n2; 27 | n2 = n3; 28 | } 29 | n3 = n1; 30 | n2 = head; 31 | boolean res = true; 32 | while (n1 != null && n2 != null) { 33 | if (n1.val != n2.val) { 34 | res = false; 35 | break; 36 | } 37 | n1 = n1.next; 38 | n2 = n2.next; 39 | } 40 | n1 = n3.next; 41 | n3.next = null; 42 | while (n1 != null) { 43 | n2 = n1.next; 44 | n1.next = n3; 45 | n3 = n1; 46 | n1 = n2; 47 | } 48 | return res; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0350_IntersectionOfTwoArraysII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | 6 | public class Problem_0350_IntersectionOfTwoArraysII { 7 | 8 | public static int[] intersect(int[] nums1, int[] nums2) { 9 | HashMap map1 = new HashMap<>(); 10 | for (int num : nums1) { 11 | if (!map1.containsKey(num)) { 12 | map1.put(num, 1); 13 | } else { 14 | map1.put(num, map1.get(num) + 1); 15 | } 16 | } 17 | HashMap map2 = new HashMap<>(); 18 | for (int num : nums2) { 19 | if (!map2.containsKey(num)) { 20 | map2.put(num, 1); 21 | } else { 22 | map2.put(num, map2.get(num) + 1); 23 | } 24 | } 25 | ArrayList list = new ArrayList<>(); 26 | for (int key : map1.keySet()) { 27 | if (map2.containsKey(key)) { 28 | int n = Math.min(map1.get(key), map2.get(key)); 29 | for (int i = 0; i < n; i++) { 30 | list.add(key); 31 | } 32 | } 33 | } 34 | int[] ans = new int[list.size()]; 35 | for (int i = 0; i < ans.length; i++) { 36 | ans[i] = list.get(i); 37 | } 38 | return ans; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0166_FractionToRecurringDecimal.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Problem_0166_FractionToRecurringDecimal { 6 | 7 | public String fractionToDecimal(int numerator, int denominator) { 8 | if (numerator == 0) { 9 | return "0"; 10 | } 11 | StringBuilder res = new StringBuilder(); 12 | // "+" or "-" 13 | res.append(((numerator > 0) ^ (denominator > 0)) ? "-" : ""); 14 | long num = Math.abs((long) numerator); 15 | long den = Math.abs((long) denominator); 16 | // integral part 17 | res.append(num / den); 18 | num %= den; 19 | if (num == 0) { 20 | return res.toString(); 21 | } 22 | // fractional part 23 | res.append("."); 24 | HashMap map = new HashMap(); 25 | map.put(num, res.length()); 26 | while (num != 0) { 27 | num *= 10; 28 | res.append(num / den); 29 | num %= den; 30 | if (map.containsKey(num)) { 31 | int index = map.get(num); 32 | res.insert(index, "("); 33 | res.append(")"); 34 | break; 35 | } else { 36 | map.put(num, res.length()); 37 | } 38 | } 39 | return res.toString(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0238_ProductOfArrayExceptSelf.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0238_ProductOfArrayExceptSelf { 4 | 5 | public int[] productExceptSelf(int[] nums) { 6 | int zeros = 0; 7 | int all = 1; 8 | for (int num : nums) { 9 | if (num == 0) { 10 | zeros++; 11 | } else { 12 | all *= num; 13 | } 14 | } 15 | if (zeros > 1) { 16 | for (int i = 0; i < nums.length; i++) { 17 | nums[i] = 0; 18 | } 19 | } else { 20 | if (zeros == 0) { 21 | for (int i = 0; i < nums.length; i++) { 22 | nums[i] = all / nums[i]; 23 | } 24 | } else { 25 | for (int i = 0; i < nums.length; i++) { 26 | nums[i] = nums[i] == 0 ? all : 0; 27 | } 28 | } 29 | } 30 | return nums; 31 | } 32 | 33 | public int[] productExceptSelf2(int[] nums) { 34 | int n = nums.length; 35 | int[] ans = new int[n]; 36 | ans[0] = nums[0]; 37 | for (int i = 1; i < n; i++) { 38 | ans[i] = ans[i - 1] * nums[i]; 39 | } 40 | int right = 1; 41 | for (int i = n - 1; i > 0; i--) { 42 | ans[i] = ans[i - 1] * right; 43 | right *= nums[i]; 44 | } 45 | ans[0] = right; 46 | return ans; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0125_ValidPalindrome.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0125_ValidPalindrome { 4 | 5 | public static boolean isPalindrome(String s) { 6 | if (s == null || s.length() == 0) { 7 | return true; 8 | } 9 | char[] str = s.toCharArray(); 10 | int L = 0; 11 | int R = str.length - 1; 12 | while (L < R) { 13 | if (validChar(str[L]) && validChar(str[R])) { 14 | if (!equal(str[L], str[R])) { 15 | return false; 16 | } 17 | L++; 18 | R--; 19 | } else { 20 | L += validChar(str[L]) ? 0 : 1; 21 | R -= validChar(str[R]) ? 0 : 1; 22 | } 23 | } 24 | return true; 25 | } 26 | 27 | public static boolean validChar(char c) { 28 | return isLetter(c) || isNumber(c); 29 | } 30 | 31 | public static boolean equal(char c1, char c2) { 32 | if (isNumber(c1) || isNumber(c2)) { 33 | return c1 == c2; 34 | } 35 | return (c1 == c2) || (Math.max(c1, c2) - Math.min(c1, c2) == 32); 36 | } 37 | 38 | public static boolean isLetter(char c) { 39 | return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); 40 | } 41 | 42 | public static boolean isNumber(char c) { 43 | return (c >= '0' && c <= '9'); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0295_FindMedianFromDataStream.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.PriorityQueue; 4 | 5 | public class Problem_0295_FindMedianFromDataStream { 6 | 7 | class MedianFinder { 8 | 9 | private PriorityQueue maxh; 10 | private PriorityQueue minh; 11 | 12 | public MedianFinder() { 13 | maxh = new PriorityQueue<>((a, b) -> b - a); 14 | minh = new PriorityQueue<>((a, b) -> a - b); 15 | } 16 | 17 | public void addNum(int num) { 18 | if (maxh.isEmpty()) { 19 | maxh.add(num); 20 | } else { 21 | if (maxh.peek() >= num) { 22 | maxh.add(num); 23 | } else { 24 | minh.add(num); 25 | } 26 | } 27 | balance(); 28 | } 29 | 30 | public double findMedian() { 31 | if (maxh.size() == minh.size()) { 32 | return (double) (maxh.peek() + minh.peek()) / 2; 33 | } else { 34 | return maxh.size() > minh.size() ? maxh.peek() : minh.peek(); 35 | } 36 | } 37 | 38 | private void balance() { 39 | if (maxh.size() == minh.size() + 2) { 40 | minh.add(maxh.poll()); 41 | } 42 | if (maxh.size() == minh.size() - 2) { 43 | maxh.add(minh.poll()); 44 | } 45 | } 46 | 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /src/followup/PrintStar.java: -------------------------------------------------------------------------------- 1 | package followup; 2 | 3 | public class PrintStar { 4 | 5 | public static void printStar(int N) { 6 | int leftUp = 0; 7 | int rightDown = N - 1; 8 | char[][] m = new char[N][N]; 9 | for (int i = 0; i < N; i++) { 10 | for (int j = 0; j < N; j++) { 11 | m[i][j] = ' '; 12 | } 13 | } 14 | while (leftUp <= rightDown) { 15 | set(m, leftUp, rightDown); 16 | leftUp += 2; 17 | rightDown -= 2; 18 | } 19 | for (int i = 0; i < N; i++) { 20 | for (int j = 0; j < N; j++) { 21 | System.out.print(m[i][j] + " "); 22 | } 23 | System.out.println(); 24 | } 25 | } 26 | 27 | public static void set(char[][] m, int leftUp, int rightDown) { 28 | for (int col = leftUp; col <= rightDown; col++) { 29 | m[leftUp][col] = '*'; 30 | } 31 | for (int row = leftUp + 1; row <= rightDown; row++) { 32 | m[row][rightDown] = '*'; 33 | } 34 | for (int col = rightDown - 1; col > leftUp; col--) { 35 | m[rightDown][col] = '*'; 36 | } 37 | for (int row = rightDown - 1; row > leftUp + 1; row--) { 38 | m[row][leftUp + 1] = '*'; 39 | } 40 | } 41 | 42 | public static void main(String[] args) { 43 | System.out.println("begin:"); 44 | printStar(20); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0105_ConstructBinaryTreeFromPreorderAndInorderTraversal.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Problem_0105_ConstructBinaryTreeFromPreorderAndInorderTraversal { 6 | 7 | public static class TreeNode { 8 | int val; 9 | TreeNode left; 10 | TreeNode right; 11 | 12 | TreeNode(int val) { 13 | this.val = val; 14 | } 15 | } 16 | 17 | public static TreeNode buildTree(int[] preorder, int[] inorder) { 18 | HashMap map = new HashMap<>(); 19 | for (int i = 0; i < inorder.length; i++) { 20 | map.put(inorder[i], i); 21 | } 22 | return f(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1, map); 23 | } 24 | 25 | public static TreeNode f(int[] pre, int L1, int R1, int[] in, int L2, int R2, HashMap map) { 26 | if (L1 > R1) { 27 | return null; 28 | } 29 | TreeNode head = new TreeNode(pre[L1]); 30 | if (L1 == R1) { 31 | return head; 32 | } 33 | int findIndex = map.get(pre[L1]); 34 | head.left = f(pre, L1 + 1, L1 + findIndex - L2, in, L2, findIndex - 1, map); 35 | head.right = f(pre, L1 + findIndex - L2 + 1, R1, in, findIndex + 1, R2, map); 36 | return head; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0070_ClimbingStairs.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0070_ClimbingStairs { 4 | 5 | public static int climbStairs(int n) { 6 | if (n < 1) { 7 | return 0; 8 | } 9 | if (n == 1 || n == 2) { 10 | return n; 11 | } 12 | int[][] base = { { 1, 1 }, { 1, 0 } }; 13 | int[][] res = matrixPower(base, n - 2); 14 | return 2 * res[0][0] + res[1][0]; 15 | } 16 | 17 | public static int[][] matrixPower(int[][] m, int p) { 18 | int[][] res = new int[m.length][m[0].length]; 19 | for (int i = 0; i < res.length; i++) { 20 | res[i][i] = 1; 21 | } 22 | 23 | // res = 矩阵中的1 24 | int[][] tmp = m;// 矩阵1次方 25 | for (; p != 0; p >>= 1) { 26 | if ((p & 1) != 0) { 27 | res = muliMatrix(res, tmp); 28 | } 29 | tmp = muliMatrix(tmp, tmp); 30 | } 31 | return res; 32 | } 33 | 34 | // 两个矩阵乘完之后的结果返回 35 | public static int[][] muliMatrix(int[][] m1, int[][] m2) { 36 | int[][] res = new int[m1.length][m2[0].length]; 37 | for (int i = 0; i < m1.length; i++) { 38 | for (int j = 0; j < m2[0].length; j++) { 39 | for (int k = 0; k < m2.length; k++) { 40 | res[i][j] += m1[i][k] * m2[k][j]; 41 | } 42 | } 43 | } 44 | return res; 45 | } 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0023_MergeKSortedLists.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.Comparator; 4 | import java.util.PriorityQueue; 5 | 6 | public class Problem_0023_MergeKSortedLists { 7 | 8 | public static class ListNode { 9 | public int val; 10 | public ListNode next; 11 | } 12 | 13 | public static class ListNodeComparator implements Comparator { 14 | 15 | @Override 16 | public int compare(ListNode o1, ListNode o2) { 17 | return o1.val - o2.val; 18 | } 19 | 20 | } 21 | 22 | public static ListNode mergeKLists(ListNode[] lists) { 23 | if (lists == null) { 24 | return null; 25 | } 26 | PriorityQueue heap = new PriorityQueue<>(new ListNodeComparator()); 27 | for (int i = 0; i < lists.length; i++) { 28 | if (lists[i] != null) { 29 | heap.add(lists[i]); 30 | } 31 | } 32 | if (heap.isEmpty()) { 33 | return null; 34 | } 35 | ListNode head = heap.poll(); 36 | ListNode pre = head; 37 | if (pre.next != null) { 38 | heap.add(pre.next); 39 | } 40 | while (!heap.isEmpty()) { 41 | ListNode cur = heap.poll(); 42 | pre.next = cur; 43 | pre = cur; 44 | if (cur.next != null) { 45 | heap.add(cur.next); 46 | } 47 | } 48 | return head; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0034_FindFirstAndLastPositionOfElementInSortedArray.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0034_FindFirstAndLastPositionOfElementInSortedArray { 4 | 5 | public static int[] searchRange(int[] nums, int target) { 6 | int[] ans = { -1, -1 }; 7 | if (nums == null || nums.length == 0) { 8 | return ans; 9 | } 10 | ans[0] = findFirst(nums, target); 11 | ans[1] = findLast(nums, target); 12 | return ans; 13 | } 14 | 15 | public static int findFirst(int[] arr, int num) { 16 | int L = 0; 17 | int R = arr.length - 1; 18 | int ans = -1; 19 | int mid = 0; 20 | while (L <= R) { 21 | mid = L + ((R - L) >> 1); 22 | if (arr[mid] < num) { 23 | L = mid + 1; 24 | } else if (arr[mid] > num) { 25 | R = mid - 1; 26 | } else { 27 | ans = mid; 28 | R = mid - 1; 29 | } 30 | } 31 | return ans; 32 | } 33 | 34 | public static int findLast(int[] arr, int num) { 35 | int L = 0; 36 | int R = arr.length - 1; 37 | int ans = -1; 38 | int mid = 0; 39 | while (L <= R) { 40 | mid = L + ((R - L) >> 1); 41 | if (arr[mid] < num) { 42 | L = mid + 1; 43 | } else if (arr[mid] > num) { 44 | R = mid - 1; 45 | } else { 46 | ans = mid; 47 | L = mid + 1; 48 | } 49 | } 50 | return ans; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0002_AddTwoNumbers.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0002_AddTwoNumbers { 4 | 5 | // 不要提交这个类描述 6 | public static class ListNode { 7 | public int val; 8 | public ListNode next; 9 | 10 | public ListNode(int value) { 11 | this.val = value; 12 | } 13 | } 14 | 15 | public static ListNode addTwoNumbers(ListNode head1, ListNode head2) { 16 | int ca = 0; 17 | int n1 = 0; 18 | int n2 = 0; 19 | int n = 0; 20 | ListNode c1 = head1; 21 | ListNode c2 = head2; 22 | ListNode node = null; 23 | ListNode pre = null; 24 | while (c1 != null || c2 != null) { 25 | n1 = c1 != null ? c1.val : 0; 26 | n2 = c2 != null ? c2.val : 0; 27 | n = n1 + n2 + ca; 28 | pre = node; 29 | node = new ListNode(n % 10); 30 | node.next = pre; 31 | ca = n / 10; 32 | c1 = c1 != null ? c1.next : null; 33 | c2 = c2 != null ? c2.next : null; 34 | } 35 | if (ca == 1) { 36 | pre = node; 37 | node = new ListNode(1); 38 | node.next = pre; 39 | } 40 | return reverseList(node); 41 | } 42 | 43 | public static ListNode reverseList(ListNode head) { 44 | ListNode pre = null; 45 | ListNode next = null; 46 | while (head != null) { 47 | next = head.next; 48 | head.next = pre; 49 | pre = head; 50 | head = next; 51 | } 52 | return pre; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0138_CopyListWithRandomPointer.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0138_CopyListWithRandomPointer { 4 | 5 | public static class Node { 6 | int val; 7 | Node next; 8 | Node random; 9 | 10 | public Node(int val) { 11 | this.val = val; 12 | this.next = null; 13 | this.random = null; 14 | } 15 | } 16 | 17 | public static Node copyRandomList(Node head) { 18 | if (head == null) { 19 | return null; 20 | } 21 | Node cur = head; 22 | Node next = null; 23 | // 1 -> 2 -> 3 -> null 24 | // 1 -> 1' -> 2 -> 2' -> 3 -> 3' 25 | while (cur != null) { 26 | next = cur.next; 27 | cur.next = new Node(cur.val); 28 | cur.next.next = next; 29 | cur = next; 30 | } 31 | cur = head; 32 | Node copy = null; 33 | // 1 1' 2 2' 3 3' 34 | // 依次设置 1' 2' 3' random指针 35 | while (cur != null) { 36 | next = cur.next.next; 37 | copy = cur.next; 38 | copy.random = cur.random != null ? cur.random.next : null; 39 | cur = next; 40 | } 41 | Node res = head.next; 42 | cur = head; 43 | // 老 新 混在一起,next方向上,random正确 44 | // next方向上,把新老链表分离 45 | while (cur != null) { 46 | next = cur.next.next; 47 | copy = cur.next; 48 | cur.next = next; 49 | copy.next = next != null ? next.next : null; 50 | cur = next; 51 | } 52 | return res; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0054_SpiralMatrix.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Problem_0054_SpiralMatrix { 7 | 8 | public static List spiralOrder(int[][] matrix) { 9 | List ans = new ArrayList<>(); 10 | if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) { 11 | return ans; 12 | } 13 | int a = 0; 14 | int b = 0; 15 | int c = matrix.length - 1; 16 | int d = matrix[0].length - 1; 17 | while (a <= c && b <= d) { 18 | addEdge(matrix, a++, b++, c--, d--, ans); 19 | } 20 | return ans; 21 | } 22 | 23 | public static void addEdge(int[][] m, int a, int b, int c, int d, List ans) { 24 | if (a == c) { 25 | for (int i = b; i <= d; i++) { 26 | ans.add(m[a][i]); 27 | } 28 | } else if (b == d) { 29 | for (int i = a; i <= c; i++) { 30 | ans.add(m[i][b]); 31 | } 32 | } else { 33 | int curC = b; 34 | int curR = a; 35 | while (curC != d) { 36 | ans.add(m[a][curC]); 37 | curC++; 38 | } 39 | while (curR != c) { 40 | ans.add(m[curR][d]); 41 | curR++; 42 | } 43 | while (curC != b) { 44 | ans.add(m[c][curC]); 45 | curC--; 46 | } 47 | while (curR != a) { 48 | ans.add(m[curR][b]); 49 | curR--; 50 | } 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/followup/MaxSum.java: -------------------------------------------------------------------------------- 1 | package followup; 2 | 3 | public class MaxSum { 4 | 5 | // 给定一个数组arr,在不能取相邻数的情况下,返回所有组合中的最大累加和 6 | // 思路: 7 | // 定义dp[i] : 表示arr[0...i]范围上,在不能取相邻数的情况下,返回所有组合中的最大累加和 8 | // 在arr[0...i]范围上,在不能取相邻数的情况下,得到的最大累加和,可能性分类: 9 | // 可能性 1) 选出的组合,不包含arr[i]。那么dp[i] = dp[i-1] 10 | // 比如,arr[0...i] = {3,4,-4},最大累加和是不包含i位置数的时候 11 | // 12 | // 可能性 2) 选出的组合,只包含arr[i]。那么dp[i] = arr[i] 13 | // 比如,arr[0...i] = {-3,-4,4},最大累加和是只包含i位置数的时候 14 | // 15 | // 可能性 3) 选出的组合,包含arr[i], 且包含arr[0...i-2]范围上的累加和。那么dp[i] = arr[i] + dp[i-2] 16 | // 比如,arr[0...i] = {3,1,4},最大累加和是3和4组成的7,因为相邻不能选,所以i-1位置的数要跳过 17 | // 18 | // 综上所述:dp[i] = Max { dp[i-1], arr[i] , arr[i] + dp[i-2] } 19 | public static int maxSum(int[] arr) { 20 | if (arr == null || arr.length == 0) { 21 | return 0; 22 | } 23 | int N = arr.length; 24 | if (N == 1) { 25 | return arr[0]; 26 | } 27 | if (N == 2) { 28 | return Math.max(arr[0], arr[1]); 29 | } 30 | int[] dp = new int[N]; 31 | dp[0] = arr[0]; 32 | dp[1] = Math.max(arr[0], arr[1]); 33 | for (int i = 2; i < N; i++) { 34 | dp[i] = Math.max(Math.max(dp[i - 1], arr[i]), arr[i] + dp[i - 2]); 35 | } 36 | return dp[N - 1]; 37 | } 38 | 39 | public static void main(String[] args) { 40 | System.out.println("test begin"); 41 | int[] arr = { 10, 9, 25, 3, 6, 31, 19 }; 42 | System.out.println(maxSum(arr)); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0347_TopKFrequentElements.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.Comparator; 4 | import java.util.HashMap; 5 | import java.util.PriorityQueue; 6 | 7 | public class Problem_0347_TopKFrequentElements { 8 | 9 | public static class Node { 10 | public int num; 11 | public int count; 12 | 13 | public Node(int k) { 14 | num = k; 15 | count = 1; 16 | } 17 | } 18 | 19 | public static class CountComparator implements Comparator { 20 | 21 | @Override 22 | public int compare(Node o1, Node o2) { 23 | return o1.count - o2.count; 24 | } 25 | 26 | } 27 | 28 | public static int[] topKFrequent(int[] nums, int k) { 29 | HashMap map = new HashMap<>(); 30 | for (int num : nums) { 31 | if (!map.containsKey(num)) { 32 | map.put(num, new Node(num)); 33 | } else { 34 | map.get(num).count++; 35 | } 36 | } 37 | PriorityQueue heap = new PriorityQueue<>(new CountComparator()); 38 | for (Node node : map.values()) { 39 | if (heap.size() < k || (heap.size() == k && node.count > heap.peek().count)) { 40 | heap.add(node); 41 | } 42 | if (heap.size() > k) { 43 | heap.poll(); 44 | } 45 | } 46 | int[] ans = new int[k]; 47 | int index = 0; 48 | while (!heap.isEmpty()) { 49 | ans[index++] = heap.poll().num; 50 | } 51 | return ans; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0028_ImplementStrStr.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0028_ImplementStrStr { 4 | 5 | public static int getIndexOf(String s, String m) { 6 | if (s == null || m == null || s.length() < m.length()) { 7 | return -1; 8 | } 9 | if (m.length() == 0) { 10 | return 0; 11 | } 12 | char[] str1 = s.toCharArray(); 13 | char[] str2 = m.toCharArray(); 14 | int x = 0; 15 | int y = 0; 16 | int[] next = getNextArray(str2); 17 | while (x < str1.length && y < str2.length) { 18 | if (str1[x] == str2[y]) { 19 | x++; 20 | y++; 21 | } else if (next[y] == -1) { 22 | x++; 23 | } else { 24 | y = next[y]; 25 | } 26 | } 27 | return y == str2.length ? x - y : -1; 28 | } 29 | 30 | public static int[] getNextArray(char[] ms) { 31 | if (ms.length == 1) { 32 | return new int[] { -1 }; 33 | } 34 | int[] next = new int[ms.length]; 35 | next[0] = -1; 36 | next[1] = 0; 37 | int i = 2; 38 | // cn代表,cn位置的字符,是当前和i-1位置比较的字符 39 | int cn = 0; 40 | while (i < next.length) { 41 | if (ms[i - 1] == ms[cn]) { 42 | next[i++] = ++cn; 43 | } else if (cn > 0) { 44 | cn = next[cn]; 45 | } else { 46 | next[i++] = 0; 47 | } 48 | } 49 | return next; 50 | } 51 | 52 | public static int strStr(String haystack, String needle) { 53 | return getIndexOf(haystack, needle); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0017_LetterCombinationsOfAPhoneNumber.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Problem_0017_LetterCombinationsOfAPhoneNumber { 7 | 8 | public static char[][] phone = { 9 | { 'a', 'b', 'c' }, // 2 0 10 | { 'd', 'e', 'f' }, // 3 1 11 | { 'g', 'h', 'i' }, // 4 2 12 | { 'j', 'k', 'l' }, // 5 3 13 | { 'm', 'n', 'o' }, // 6 14 | { 'p', 'q', 'r', 's' }, // 7 15 | { 't', 'u', 'v' }, // 8 16 | { 'w', 'x', 'y', 'z' }, // 9 17 | }; 18 | 19 | // "23" 20 | public static List letterCombinations(String digits) { 21 | List ans = new ArrayList<>(); 22 | if (digits == null || digits.length() == 0) { 23 | return ans; 24 | } 25 | char[] str = digits.toCharArray(); 26 | char[] path = new char[str.length]; 27 | process(str, 0, path, ans); 28 | return ans; 29 | } 30 | 31 | // str = ['2','3'] 3 3 32 | // str[....index-1],按出的结果是什么都在path里 33 | // str[index...] 按完之后,有哪些组合,放入到ans里 34 | public static void process(char[] str, int index, char[] path, List ans) { 35 | if (index == str.length) { 36 | ans.add(String.valueOf(path)); 37 | } else { 38 | char[] cands = phone[str[index] - '2']; 39 | for (char cur : cands) { 40 | path[index] = cur; 41 | process(str, index + 1, path, ans); 42 | } 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0253_MeetingRoomsII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.Arrays; 4 | import java.util.Comparator; 5 | import java.util.PriorityQueue; 6 | 7 | public class Problem_0253_MeetingRoomsII { 8 | 9 | public static int minMeetingRooms(int[][] m) { 10 | Line[] lines = new Line[m.length]; 11 | for (int i = 0; i < m.length; i++) { 12 | lines[i] = new Line(m[i][0], m[i][1]); 13 | } 14 | Arrays.sort(lines, new StartComparator()); 15 | PriorityQueue heap = new PriorityQueue<>(new EndComparator()); 16 | int max = 0; 17 | for (int i = 0; i < lines.length; i++) { 18 | while (!heap.isEmpty() && heap.peek().end <= lines[i].start) { 19 | heap.poll(); 20 | } 21 | heap.add(lines[i]); 22 | max = Math.max(max, heap.size()); 23 | } 24 | return max; 25 | } 26 | 27 | public static class Line { 28 | public int start; 29 | public int end; 30 | 31 | public Line(int s, int e) { 32 | start = s; 33 | end = e; 34 | } 35 | } 36 | 37 | public static class StartComparator implements Comparator { 38 | 39 | @Override 40 | public int compare(Line o1, Line o2) { 41 | return o1.start - o2.start; 42 | } 43 | 44 | } 45 | 46 | public static class EndComparator implements Comparator { 47 | 48 | @Override 49 | public int compare(Line o1, Line o2) { 50 | return o1.end - o2.end; 51 | } 52 | 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0236_LowestCommonAncestorOfBinaryTree.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0236_LowestCommonAncestorOfBinaryTree { 4 | 5 | public static class TreeNode { 6 | public int val; 7 | public TreeNode left; 8 | public TreeNode right; 9 | } 10 | 11 | public static TreeNode lowestCommonAncestor(TreeNode head, TreeNode o1, TreeNode o2) { 12 | return process(head, o1, o2).ans; 13 | } 14 | 15 | public static class Info { 16 | public TreeNode ans; 17 | public boolean findO1; 18 | public boolean findO2; 19 | 20 | public Info(TreeNode a, boolean f1, boolean f2) { 21 | ans = a; 22 | findO1 = f1; 23 | findO2 = f2; 24 | } 25 | } 26 | 27 | public static Info process(TreeNode X, TreeNode o1, TreeNode o2) { 28 | if (X == null) { 29 | return new Info(null, false, false); 30 | } 31 | Info leftInfo = process(X.left, o1, o2); 32 | Info rightInfo = process(X.right, o1, o2); 33 | boolean findO1 = X == o1 || leftInfo.findO1 || rightInfo.findO1; 34 | boolean findO2 = X == o2 || leftInfo.findO2 || rightInfo.findO2; 35 | TreeNode ans = null; 36 | if (leftInfo.ans != null) { 37 | ans = leftInfo.ans; 38 | } 39 | if (rightInfo.ans != null) { 40 | ans = rightInfo.ans; 41 | } 42 | if (ans == null) { 43 | if (findO1 && findO2) { 44 | ans = X; 45 | } 46 | } 47 | return new Info(ans, findO1, findO2); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0380_InsertDeleteGetRandom.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Problem_0380_InsertDeleteGetRandom { 6 | 7 | public class RandomizedSet { 8 | 9 | private HashMap keyIndexMap; 10 | private HashMap indexKeyMap; 11 | private int size; 12 | 13 | public RandomizedSet() { 14 | keyIndexMap = new HashMap(); 15 | indexKeyMap = new HashMap(); 16 | size = 0; 17 | } 18 | 19 | public boolean insert(int val) { 20 | if (!keyIndexMap.containsKey(val)) { 21 | keyIndexMap.put(val, size); 22 | indexKeyMap.put(size++, val); 23 | return true; 24 | } 25 | return false; 26 | } 27 | 28 | public boolean remove(int val) { 29 | if (keyIndexMap.containsKey(val)) { 30 | int deleteIndex = keyIndexMap.get(val); 31 | int lastIndex = --size; 32 | int lastKey = indexKeyMap.get(lastIndex); 33 | keyIndexMap.put(lastKey, deleteIndex); 34 | indexKeyMap.put(deleteIndex, lastKey); 35 | keyIndexMap.remove(val); 36 | indexKeyMap.remove(lastIndex); 37 | return true; 38 | } 39 | return false; 40 | } 41 | 42 | public int getRandom() { 43 | if (size == 0) { 44 | return -1; 45 | } 46 | int randomIndex = (int) (Math.random() * size); 47 | return indexKeyMap.get(randomIndex); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0103_BinaryTreeZigzagLevelOrderTraversal.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | public class Problem_0103_BinaryTreeZigzagLevelOrderTraversal { 8 | 9 | public static class TreeNode { 10 | int val; 11 | TreeNode left; 12 | TreeNode right; 13 | } 14 | 15 | public static List> zigzagLevelOrder(TreeNode root) { 16 | List> ans = new ArrayList<>(); 17 | if (root == null) { 18 | return ans; 19 | } 20 | LinkedList deque = new LinkedList<>(); 21 | deque.add(root); 22 | int size = 0; 23 | boolean isHead = true; 24 | while (!deque.isEmpty()) { 25 | size = deque.size(); 26 | List curLevel = new ArrayList<>(); 27 | for (int i = 0; i < size; i++) { 28 | TreeNode cur = isHead ? deque.pollFirst() : deque.pollLast(); 29 | curLevel.add(cur.val); 30 | if(isHead) { 31 | if (cur.left != null) { 32 | deque.addLast(cur.left); 33 | } 34 | if (cur.right != null) { 35 | deque.addLast(cur.right); 36 | } 37 | }else { 38 | if (cur.right != null) { 39 | deque.addFirst(cur.right); 40 | } 41 | if (cur.left != null) { 42 | deque.addFirst(cur.left); 43 | } 44 | } 45 | } 46 | ans.add(curLevel); 47 | isHead = !isHead; 48 | } 49 | return ans; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0189_RotateArray.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0189_RotateArray { 4 | 5 | public void rotate1(int[] nums, int k) { 6 | int N = nums.length; 7 | k = k % N; 8 | reverse(nums, 0, N - k - 1); 9 | reverse(nums, N - k, N - 1); 10 | reverse(nums, 0, N - 1); 11 | } 12 | 13 | public static void reverse(int[] nums, int L, int R) { 14 | while (L < R) { 15 | int tmp = nums[L]; 16 | nums[L++] = nums[R]; 17 | nums[R--] = tmp; 18 | } 19 | } 20 | 21 | public static void rotate2(int[] nums, int k) { 22 | int N = nums.length; 23 | k = k % N; 24 | if (k == 0) { 25 | return; 26 | } 27 | int L = 0; 28 | int R = N - 1; 29 | int lpart = N - k; 30 | int rpart = k; 31 | int same = Math.min(lpart, rpart); 32 | int diff = lpart - rpart; 33 | exchange(nums, L, R, same); 34 | while (diff != 0) { 35 | if (diff > 0) { 36 | L += same; 37 | lpart = diff; 38 | } else { 39 | R -= same; 40 | rpart = -diff; 41 | } 42 | same = Math.min(lpart, rpart); 43 | diff = lpart - rpart; 44 | exchange(nums, L, R, same); 45 | } 46 | } 47 | 48 | public static void exchange(int[] nums, int start, int end, int size) { 49 | int i = end - size + 1; 50 | int tmp = 0; 51 | while (size-- != 0) { 52 | tmp = nums[start]; 53 | nums[start] = nums[i]; 54 | nums[i] = tmp; 55 | start++; 56 | i++; 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0033_SearchInRotatedSortedArray.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0033_SearchInRotatedSortedArray { 4 | 5 | public static int search(int[] arr, int num) { 6 | int L = 0; 7 | int R = arr.length - 1; 8 | int M = 0; 9 | while (L <= R) { 10 | M = (L + R) / 2; 11 | if (arr[M] == num) { 12 | return M; 13 | } 14 | // arr[M] != num 15 | if (arr[L] == arr[M] && arr[M] == arr[R]) { 16 | while (L != M && arr[L] == arr[M]) { 17 | L++; 18 | } 19 | // L和M没撞上,[L]!=[M] L,.....M 20 | if (L == M) { 21 | L = M + 1; 22 | continue; 23 | } 24 | } 25 | // arr[M] != num 26 | // [L] [M] [R] 不都一样的情况 27 | if (arr[L] != arr[M]) { 28 | if (arr[M] > arr[L]) { 29 | if (num >= arr[L] && num < arr[M]) { 30 | R = M - 1; 31 | } else { 32 | L = M + 1; 33 | } 34 | } else { // [L] > [M] 35 | if (num > arr[M] && num <= arr[R]) { 36 | L = M + 1; 37 | } else { 38 | R = M - 1; 39 | } 40 | } 41 | } else { // [L] === [M] -> [M]!=[R] 42 | if (arr[M] < arr[R]) { 43 | if (num > arr[M] && num <= arr[R]) { 44 | L = M + 1; 45 | } else { 46 | R = M - 1; 47 | } 48 | } else { 49 | if (num >= arr[L] && num < arr[M]) { 50 | R = M - 1; 51 | } else { 52 | L = M + 1; 53 | } 54 | } 55 | } 56 | } 57 | return -1; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0215_KthLargestElementInAnArray.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0215_KthLargestElementInAnArray { 4 | 5 | public int findKthLargest(int[] nums, int k) { 6 | return minKth(nums, nums.length + 1 - k); 7 | } 8 | 9 | public static int minKth(int[] arr, int k) { 10 | return process(arr, 0, arr.length - 1, k - 1); 11 | } 12 | 13 | public static int process(int[] arr, int L, int R, int index) { 14 | if (L == R) { 15 | return arr[L]; 16 | } 17 | int pivot = arr[L + (int) (Math.random() * (R - L + 1))]; 18 | int[] range = partition(arr, L, R, pivot); 19 | if (index >= range[0] && index <= range[1]) { 20 | return arr[index]; 21 | } else if (index < range[0]) { 22 | return process(arr, L, range[0] - 1, index); 23 | } else { 24 | return process(arr, range[1] + 1, R, index); 25 | } 26 | } 27 | 28 | public static int[] partition(int[] arr, int L, int R, int pivot) { 29 | int less = L - 1; 30 | int more = R + 1; 31 | int cur = L; 32 | while (cur < more) { 33 | if (arr[cur] < pivot) { 34 | swap(arr, ++less, cur++); 35 | } else if (arr[cur] > pivot) { 36 | swap(arr, cur, --more); 37 | } else { 38 | cur++; 39 | } 40 | } 41 | return new int[] { less + 1, more - 1 }; 42 | } 43 | 44 | public static void swap(int[] arr, int i1, int i2) { 45 | int tmp = arr[i1]; 46 | arr[i1] = arr[i2]; 47 | arr[i2] = tmp; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0005_LongestPalindromicSubstring.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0005_LongestPalindromicSubstring { 4 | 5 | public static String longestPalindrome(String str) { 6 | if (str == null || str.length() == 0) { 7 | return ""; 8 | } 9 | char[] charArr = manacherString(str); 10 | int[] pArr = new int[charArr.length]; 11 | int index = -1; 12 | int pR = -1; 13 | int max = Integer.MIN_VALUE; 14 | int mid = 0; 15 | for (int i = 0; i != charArr.length; i++) { 16 | pArr[i] = pR > i ? Math.min(pArr[2 * index - i], pR - i) : 1; 17 | while (i + pArr[i] < charArr.length && i - pArr[i] > -1) { 18 | if (charArr[i + pArr[i]] == charArr[i - pArr[i]]) 19 | pArr[i]++; 20 | else { 21 | break; 22 | } 23 | } 24 | if (i + pArr[i] > pR) { 25 | pR = i + pArr[i]; 26 | index = i; 27 | } 28 | if (max < pArr[i]) { 29 | max = pArr[i]; 30 | mid = i; 31 | } 32 | } 33 | mid = (mid - 1) / 2; 34 | max = max - 1; 35 | return str.substring((max & 1) == 0 ? mid - (max / 2) + 1 : mid - (max / 2), mid + (max / 2) + 1); 36 | } 37 | 38 | public static char[] manacherString(String str) { 39 | char[] charArr = str.toCharArray(); 40 | char[] res = new char[str.length() * 2 + 1]; 41 | int index = 0; 42 | for (int i = 0; i != res.length; i++) { 43 | res[i] = (i & 1) == 0 ? '#' : charArr[index++]; 44 | } 45 | return res; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0687_LongestUnivaluePath.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0687_LongestUnivaluePath { 4 | 5 | public static class TreeNode { 6 | public int val; 7 | public TreeNode left; 8 | public TreeNode right; 9 | 10 | public TreeNode(int v) { 11 | val = v; 12 | } 13 | } 14 | 15 | public static int longestUnivaluePath(TreeNode root) { 16 | if (root == null) { 17 | return 0; 18 | } 19 | return process(root).max - 1; 20 | } 21 | 22 | // 建设以x节点为头的树,返回两个信息 23 | public static class Info { 24 | // 在一条路径上:要求每个节点通过且只通过一遍 25 | public int len; // 路径必须从x出发且只能往下走的情况下,路径的最大距离 26 | public int max; // 路径不要求必须从x出发的情况下,整棵树的合法路径最大距离 27 | 28 | public Info(int l, int m) { 29 | len = l; 30 | max = m; 31 | } 32 | } 33 | 34 | private static Info process(TreeNode x) { 35 | if (x == null) { 36 | return new Info(0, 0); 37 | } 38 | TreeNode l = x.left; 39 | TreeNode r = x.right; 40 | Info linfo = process(l); 41 | Info rinfo = process(r); 42 | int len = 1; 43 | if (l != null && l.val == x.val) { 44 | len = linfo.len + 1; 45 | } 46 | if (r != null && r.val == x.val) { 47 | len = Math.max(len, rinfo.len + 1); 48 | } 49 | int max = Math.max(Math.max(linfo.max, rinfo.max), len); 50 | if (l != null && r != null && l.val == x.val && r.val == x.val) { 51 | max = Math.max(max, linfo.len + rinfo.len + 1); 52 | } 53 | return new Info(len, max); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0053_MaximumSubarray.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0053_MaximumSubarray { 4 | 5 | public static int maxSum(int[] nums) { 6 | int N = nums.length; 7 | // dp[i] 含义:子数组必须以i结尾的时候,所有可以得到的子数组中,最大累加和是多少? 8 | int[] dp = new int[N]; 9 | dp[0] = nums[0]; 10 | int max = Integer.MIN_VALUE; 11 | for (int i = 1; i < N; i++) { 12 | int p1 = nums[i]; 13 | int p2 = nums[i] + dp[i - 1]; 14 | dp[i] = Math.max(p1, p2); 15 | max = Math.max(max, dp[i]); 16 | } 17 | return max; 18 | } 19 | 20 | public static int maxSumFollowUp(int[] arr) { 21 | if (arr == null) { 22 | return 0; 23 | } 24 | int N = arr.length; 25 | if (N == 0) { 26 | return 0; 27 | } 28 | if (N == 1) { 29 | return arr[0]; 30 | } 31 | if (N == 2) { 32 | return Math.max(arr[0], arr[1]); 33 | } 34 | // N > 2 35 | int[] dp = new int[N]; 36 | dp[0] = arr[0]; 37 | dp[1] = Math.max(arr[0], arr[1]); 38 | for (int i = 2; i < N; i++) { 39 | int p1 = arr[i]; 40 | int p2 = dp[i - 1]; 41 | int p3 = arr[i] + dp[i - 2]; 42 | dp[i] = Math.max(Math.max(p1, p2), p3); 43 | } 44 | return dp[N-1]; 45 | } 46 | 47 | public static int maxSubArray(int[] nums) { 48 | int cur = 0; 49 | int max = Integer.MIN_VALUE; 50 | for (int i = 0; i < nums.length; i++) { 51 | cur += nums[i]; 52 | max = Math.max(max, cur); 53 | cur = cur < 0 ? 0 : cur; 54 | } 55 | return max; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0050_PowXN.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0050_PowXN { 4 | 5 | public static double myPow1(double x, int n) { 6 | if (n == 0) { 7 | return 1D; 8 | } 9 | if (n == Integer.MIN_VALUE) { 10 | return (x == 1D || x == -1D) ? 1D : 0; 11 | } 12 | int pow = Math.abs(n); 13 | double t = x; 14 | double ans = 1D; 15 | while (pow != 0) { 16 | if ((pow & 1) != 0) { 17 | ans *= t; 18 | } 19 | pow >>= 1; 20 | t = t * t; 21 | } 22 | return n < 0 ? (1D / ans) : ans; 23 | } 24 | 25 | public static double myPow2(double x, int n) { 26 | if (n == 0) { 27 | return 1D; 28 | } 29 | int pow = Math.abs(n == Integer.MIN_VALUE ? n + 1 : n); 30 | double t = x; 31 | double ans = 1D; 32 | while (pow != 0) { 33 | if ((pow & 1) != 0) { 34 | ans *= t; 35 | } 36 | pow >>= 1; 37 | t = t * t; 38 | } 39 | if (n == Integer.MIN_VALUE) { 40 | ans *= x; 41 | } 42 | return n < 0 ? (1D / ans) : ans; 43 | } 44 | 45 | public static void main(String[] args) { 46 | System.out.println("world shut up!"); 47 | int a = Integer.MIN_VALUE; 48 | int b = -a; 49 | System.out.println(b); 50 | 51 | System.out.println("=============="); 52 | 53 | double test = 1.00000001D; 54 | int N = Integer.MIN_VALUE; 55 | System.out.println(test == 1D); 56 | System.out.println(test + "的" + N + "次方,结果:"); 57 | System.out.println(Math.pow(test, (double) N)); 58 | System.out.println(myPow1(test, N)); 59 | System.out.println(myPow2(test, N)); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0188_BestTimeToBuyAndSellStockIV.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0188_BestTimeToBuyAndSellStockIV { 4 | 5 | public static int maxProfit1(int K, int[] arr) { 6 | if (arr == null || arr.length == 0) { 7 | return 0; 8 | } 9 | int N = arr.length; 10 | if (K >= N / 2) { 11 | return allTrans(arr); 12 | } 13 | int[][] dp = new int[N][K + 1]; 14 | for (int i = 1; i < N; i++) { 15 | for (int j = 1; j <= K; j++) { 16 | dp[i][j] = dp[i - 1][j]; 17 | for (int p = 0; p <= i; p++) { 18 | dp[i][j] = Math.max(dp[p][j - 1] + arr[i] - arr[p], dp[i][j]); 19 | } 20 | } 21 | } 22 | return dp[N - 1][K]; 23 | } 24 | 25 | public static int maxProfit2(int K, int[] prices) { 26 | if (prices == null || prices.length == 0) { 27 | return 0; 28 | } 29 | int N = prices.length; 30 | if (K >= N / 2) { 31 | return allTrans(prices); 32 | } 33 | int[][] dp = new int[K + 1][N]; 34 | int ans = 0; 35 | for (int j = 1; j <= K; j++) { 36 | int pre = dp[j][0]; 37 | int best = pre - prices[0]; 38 | for (int i = 1; i < N; i++) { 39 | pre = dp[j - 1][i]; 40 | dp[j][i] = Math.max(dp[j][i - 1], prices[i] + best); 41 | best = Math.max(best, pre - prices[i]); 42 | ans = Math.max(dp[j][i], ans); 43 | } 44 | } 45 | return ans; 46 | } 47 | 48 | public static int allTrans(int[] prices) { 49 | int ans = 0; 50 | for (int i = 1; i < prices.length; i++) { 51 | ans += Math.max(prices[i] - prices[i - 1], 0); 52 | } 53 | return ans; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0289_GameOfLife.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | // 有关这个游戏更有意思、更完整的内容: 4 | // https://www.bilibili.com/video/BV1rJ411n7ri 5 | // 也推荐这个up主 6 | public class Problem_0289_GameOfLife { 7 | 8 | public static void gameOfLife(int[][] board) { 9 | int N = board.length; 10 | int M = board[0].length; 11 | for (int i = 0; i < N; i++) { 12 | for (int j = 0; j < M; j++) { 13 | int neighbors = neighbors(board, i, j); 14 | if (neighbors == 3 || (board[i][j] == 1 && neighbors == 2)) { 15 | set(board, i, j); 16 | } 17 | } 18 | } 19 | for (int i = 0; i < N; i++) { 20 | for (int j = 0; j < M; j++) { 21 | board[i][j] = get(board, i, j); 22 | } 23 | } 24 | } 25 | 26 | public static int neighbors(int[][] board, int i, int j) { 27 | int count = 0; 28 | count += ok(board, i - 1, j - 1) ? 1 : 0; 29 | count += ok(board, i - 1, j) ? 1 : 0; 30 | count += ok(board, i - 1, j + 1) ? 1 : 0; 31 | count += ok(board, i, j - 1) ? 1 : 0; 32 | count += ok(board, i, j + 1) ? 1 : 0; 33 | count += ok(board, i + 1, j - 1) ? 1 : 0; 34 | count += ok(board, i + 1, j) ? 1 : 0; 35 | count += ok(board, i + 1, j + 1) ? 1 : 0; 36 | return count; 37 | } 38 | 39 | public static boolean ok(int[][] board, int i, int j) { 40 | return i >= 0 && i < board.length && j >= 0 && j < board[0].length && (board[i][j] & 1) == 1; 41 | } 42 | 43 | public static void set(int[][] board, int i, int j) { 44 | board[i][j] |= 2; 45 | } 46 | 47 | public static int get(int[][] board, int i, int j) { 48 | return board[i][j] >> 1; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0308_RangeSumQuery2DMutable.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | // 提交时把类名和构造函数名从Problem_0308_RangeSumQuery2DMutable改成NumMatrix 4 | public class Problem_0308_RangeSumQuery2DMutable { 5 | private int[][] tree; 6 | private int[][] nums; 7 | private int N; 8 | private int M; 9 | 10 | public Problem_0308_RangeSumQuery2DMutable(int[][] matrix) { 11 | if (matrix.length == 0 || matrix[0].length == 0) { 12 | return; 13 | } 14 | N = matrix.length; 15 | M = matrix[0].length; 16 | tree = new int[N + 1][M + 1]; 17 | nums = new int[N][M]; 18 | for (int i = 0; i < N; i++) { 19 | for (int j = 0; j < M; j++) { 20 | update(i, j, matrix[i][j]); 21 | } 22 | } 23 | } 24 | 25 | // 用户给我的row,col不能越界 26 | private int sum(int row, int col) { 27 | int sum = 0; 28 | for (int i = row + 1; i > 0; i -= i & (-i)) { 29 | for (int j = col + 1; j > 0; j -= j & (-j)) { 30 | sum += tree[i][j]; 31 | } 32 | } 33 | return sum; 34 | } 35 | 36 | // 用户给我的row,col不能越界 37 | public void update(int row, int col, int val) { 38 | if (N == 0 || M == 0) { 39 | return; 40 | } 41 | int add = val - nums[row][col]; 42 | nums[row][col] = val; 43 | for (int i = row + 1; i <= N; i += i & (-i)) { 44 | for (int j = col + 1; j <= M; j += j & (-j)) { 45 | tree[i][j] += add; 46 | } 47 | } 48 | } 49 | 50 | public int sumRegion(int row1, int col1, int row2, int col2) { 51 | if (N == 0 || M == 0) { 52 | return 0; 53 | } 54 | return sum(row2, col2) + sum(row1 - 1, col1 - 1) - sum(row1 - 1, col2) - sum(row2, col1 - 1); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0116_PopulatingNextRightPointersInEachNode.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0116_PopulatingNextRightPointersInEachNode { 4 | 5 | public static class Node { 6 | public int val; 7 | public Node left; 8 | public Node right; 9 | public Node next; 10 | } 11 | 12 | public static class MyQueue { 13 | public Node head; 14 | public Node tail; 15 | public int size; 16 | 17 | public MyQueue() { 18 | head = null; 19 | tail = null; 20 | size = 0; 21 | } 22 | 23 | public boolean isEmpty() { 24 | return size == 0; 25 | } 26 | 27 | public void offer(Node cur) { 28 | size++; 29 | if (head == null) { 30 | head = cur; 31 | tail = cur; 32 | } else { 33 | tail.next = cur; 34 | tail = cur; 35 | } 36 | } 37 | 38 | public Node poll() { 39 | size--; 40 | Node ans = head; 41 | head = head.next; 42 | ans.next = null; 43 | return ans; 44 | } 45 | 46 | } 47 | 48 | public static Node connect(Node root) { 49 | if (root == null) { 50 | return root; 51 | } 52 | MyQueue queue = new MyQueue(); 53 | queue.offer(root); 54 | while (!queue.isEmpty()) { 55 | // 第一个弹出的节点 56 | Node pre = null; 57 | int size = queue.size; 58 | for (int i = 0; i < size; i++) { 59 | Node cur = queue.poll(); 60 | if (cur.left != null) { 61 | queue.offer(cur.left); 62 | } 63 | if (cur.right != null) { 64 | queue.offer(cur.right); 65 | } 66 | if (pre != null) { 67 | pre.next = cur; 68 | } 69 | pre = cur; 70 | } 71 | } 72 | return root; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0049_GroupAnagrams.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | 8 | public class Problem_0049_GroupAnagrams { 9 | 10 | public static List> groupAnagrams1(String[] strs) { 11 | HashMap> map = new HashMap>(); 12 | for (String str : strs) { 13 | int[] record = new int[26]; 14 | for (char cha : str.toCharArray()) { 15 | record[cha - 'a']++; 16 | } 17 | StringBuilder builder = new StringBuilder(); 18 | for (int value : record) { 19 | builder.append(String.valueOf(value)).append("_"); 20 | } 21 | String key = builder.toString(); 22 | if (!map.containsKey(key)) { 23 | map.put(key, new ArrayList()); 24 | } 25 | map.get(key).add(str); 26 | } 27 | List> res = new ArrayList>(); 28 | for (List list : map.values()) { 29 | res.add(list); 30 | } 31 | return res; 32 | } 33 | 34 | public static List> groupAnagrams2(String[] strs) { 35 | HashMap> map = new HashMap>(); 36 | for (String str : strs) { 37 | char[] chs = str.toCharArray(); 38 | Arrays.sort(chs); 39 | String key = String.valueOf(chs); 40 | if (!map.containsKey(key)) { 41 | map.put(key, new ArrayList()); 42 | } 43 | map.get(key).add(str); 44 | } 45 | List> res = new ArrayList>(); 46 | for (List list : map.values()) { 47 | res.add(list); 48 | } 49 | return res; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0056_MergeIntervals.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Comparator; 6 | 7 | public class Problem_0056_MergeIntervals { 8 | 9 | public static class Range { 10 | public int start; 11 | public int end; 12 | 13 | public Range(int s, int e) { 14 | start = s; 15 | end = e; 16 | } 17 | } 18 | 19 | public static class RangeComparator implements Comparator { 20 | 21 | @Override 22 | public int compare(Range o1, Range o2) { 23 | return o1.start - o2.start; 24 | } 25 | 26 | } 27 | 28 | // intervals N * 2 29 | public static int[][] merge(int[][] intervals) { 30 | if (intervals.length == 0) { 31 | return new int[0][0]; 32 | } 33 | Range[] arr = new Range[intervals.length]; 34 | for (int i = 0; i < intervals.length; i++) { 35 | arr[i] = new Range(intervals[i][0], intervals[i][1]); 36 | } 37 | Arrays.sort(arr, new RangeComparator()); 38 | ArrayList ans = new ArrayList<>(); 39 | int s = arr[0].start; 40 | int e = arr[0].end; 41 | for (int i = 1; i < arr.length; i++) { 42 | if (arr[i].start > e) { 43 | ans.add(new Range(s, e)); 44 | s = arr[i].start; 45 | e = arr[i].end; 46 | } else { 47 | e = Math.max(e, arr[i].end); 48 | } 49 | } 50 | ans.add(new Range(s, e)); 51 | return generateMatrix(ans); 52 | } 53 | 54 | public static int[][] generateMatrix(ArrayList list) { 55 | int[][] matrix = new int[list.size()][2]; 56 | for (int i = 0; i < list.size(); i++) { 57 | matrix[i] = new int[] { list.get(i).start, list.get(i).end }; 58 | } 59 | return matrix; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0207_CourseSchedule.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.LinkedList; 6 | import java.util.Queue; 7 | 8 | public class Problem_0207_CourseSchedule { 9 | 10 | // 一个node,就是一个课程 11 | // name是课程的编号 12 | // in是课程的入度 13 | public static class Node { 14 | public int name; 15 | public int in; 16 | public ArrayList nexts; 17 | 18 | public Node(int n) { 19 | name = n; 20 | in = 0; 21 | nexts = new ArrayList<>(); 22 | } 23 | } 24 | 25 | public static boolean canFinish(int numCourses, int[][] prerequisites) { 26 | if (prerequisites == null || prerequisites.length == 0) { 27 | return true; 28 | } 29 | HashMap nodes = new HashMap<>(); 30 | for (int[] arr : prerequisites) { 31 | int to = arr[0]; 32 | int from = arr[1]; 33 | if (!nodes.containsKey(to)) { 34 | nodes.put(to, new Node(to)); 35 | } 36 | if (!nodes.containsKey(from)) { 37 | nodes.put(from, new Node(from)); 38 | } 39 | Node t = nodes.get(to); 40 | Node f = nodes.get(from); 41 | f.nexts.add(t); 42 | t.in++; 43 | } 44 | int needPrerequisiteNums = nodes.size(); 45 | Queue zeroInQueue = new LinkedList<>(); 46 | for (Node node : nodes.values()) { 47 | if (node.in == 0) { 48 | zeroInQueue.add(node); 49 | } 50 | } 51 | int count = 0; 52 | while (!zeroInQueue.isEmpty()) { 53 | Node cur = zeroInQueue.poll(); 54 | count++; 55 | for (Node next : cur.nexts) { 56 | if (--next.in == 0) { 57 | zeroInQueue.add(next); 58 | } 59 | } 60 | } 61 | return count == needPrerequisiteNums; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0124_BinaryTreeMaximumPathSum.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0124_BinaryTreeMaximumPathSum { 4 | 5 | public static class TreeNode { 6 | int val; 7 | TreeNode left; 8 | TreeNode right; 9 | } 10 | 11 | public static int maxPathSum(TreeNode root) { 12 | if (root == null) { 13 | return 0; 14 | } 15 | return process(root).maxPathSum; 16 | } 17 | 18 | public static class Info { 19 | public int maxPathSum; 20 | public int maxPathSumFromHead; 21 | 22 | public Info(int path, int head) { 23 | maxPathSum = path; 24 | maxPathSumFromHead = head; 25 | } 26 | } 27 | 28 | public static Info process(TreeNode x) { 29 | if (x == null) { 30 | return null; 31 | } 32 | Info leftInfo = process(x.left); 33 | Info rightInfo = process(x.right); 34 | int p1 = Integer.MIN_VALUE; 35 | if (leftInfo != null) { 36 | p1 = leftInfo.maxPathSum; 37 | } 38 | int p2 = Integer.MIN_VALUE; 39 | if (rightInfo != null) { 40 | p2 = rightInfo.maxPathSum; 41 | } 42 | int p3 = x.val; 43 | int p4 = Integer.MIN_VALUE; 44 | if (leftInfo != null) { 45 | p4 = x.val + leftInfo.maxPathSumFromHead; 46 | } 47 | int p5 = Integer.MIN_VALUE; 48 | if (rightInfo != null) { 49 | p5 = x.val + rightInfo.maxPathSumFromHead; 50 | } 51 | int p6 = Integer.MIN_VALUE; 52 | if (leftInfo != null && rightInfo != null) { 53 | p6 = x.val + leftInfo.maxPathSumFromHead + rightInfo.maxPathSumFromHead; 54 | } 55 | int maxSum = Math.max(Math.max(Math.max(p1, p2), Math.max(p3, p4)), Math.max(p5, p6)); 56 | int maxSumFromHead = Math.max(p3, Math.max(p4, p5)); 57 | return new Info(maxSum, maxSumFromHead); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0208_Trie.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | /* 4 | * 提交时把类名、构造函数名从Problem_0208_Trie改为Trie 5 | * 6 | * */ 7 | public class Problem_0208_Trie { 8 | 9 | public static class Node { 10 | public boolean end; 11 | public Node[] nexts; 12 | 13 | public Node() { 14 | end = false; 15 | nexts = new Node[26]; 16 | } 17 | } 18 | 19 | private Node root; 20 | 21 | public Problem_0208_Trie() { 22 | root = new Node(); 23 | } 24 | 25 | public void insert(String word) { 26 | if (word == null) { 27 | return; 28 | } 29 | char[] str = word.toCharArray(); 30 | Node node = root; 31 | int path = 0; 32 | for (int i = 0; i < str.length; i++) { 33 | path = str[i] - 'a'; 34 | if (node.nexts[path] == null) { 35 | node.nexts[path] = new Node(); 36 | } 37 | node = node.nexts[path]; 38 | } 39 | node.end = true; 40 | } 41 | 42 | public boolean search(String word) { 43 | if (word == null) { 44 | return false; 45 | } 46 | char[] chs = word.toCharArray(); 47 | Node node = root; 48 | int index = 0; 49 | for (int i = 0; i < chs.length; i++) { 50 | index = chs[i] - 'a'; 51 | if (node.nexts[index] == null) { 52 | return false; 53 | } 54 | node = node.nexts[index]; 55 | } 56 | return node.end; 57 | } 58 | 59 | public boolean startsWith(String pre) { 60 | if (pre == null) { 61 | return false; 62 | } 63 | char[] chs = pre.toCharArray(); 64 | Node node = root; 65 | int index = 0; 66 | for (int i = 0; i < chs.length; i++) { 67 | index = chs[i] - 'a'; 68 | if (node.nexts[index] == null) { 69 | return false; 70 | } 71 | node = node.nexts[index]; 72 | } 73 | return true; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0279_PerfectSquares.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0279_PerfectSquares { 4 | 5 | // 暴力解 6 | public static int numSquares1(int n) { 7 | int res = n, num = 2; 8 | while (num * num <= n) { 9 | int a = n / (num * num), b = n % (num * num); 10 | res = Math.min(res, a + numSquares1(b)); 11 | num++; 12 | } 13 | return res; 14 | } 15 | 16 | // 1 : 1, 4, 9, 16, 25, 36, ... 17 | // 4 : 7, 15, 23, 28, 31, 39, 47, 55, 60, 63, 71, ... 18 | // 规律解 19 | // 规律一:个数不超过4 20 | // 规律二:出现1个的时候,显而易见 21 | // 规律三:任何数 % 8 == 7,一定是4个 22 | // 规律四:任何数消去4的因子之后,剩下rest,rest % 8 == 7,一定是4个 23 | public static int numSquares2(int n) { 24 | int rest = n; 25 | while (rest % 4 == 0) { 26 | rest /= 4; 27 | } 28 | if (rest % 8 == 7) { 29 | return 4; 30 | } 31 | int f = (int) Math.sqrt(n); 32 | if (f * f == n) { 33 | return 1; 34 | } 35 | for (int first = 1; first * first <= n; first++) { 36 | int second = (int) Math.sqrt(n - first * first); 37 | if (first * first + second * second == n) { 38 | return 2; 39 | } 40 | } 41 | return 3; 42 | } 43 | 44 | // 数学解 45 | // 1)四平方和定理 46 | // 2)任何数消掉4的因子,结论不变 47 | public static int numSquares3(int n) { 48 | while (n % 4 == 0) { 49 | n /= 4; 50 | } 51 | if (n % 8 == 7) { 52 | return 4; 53 | } 54 | for (int a = 0; a * a <= n; ++a) { 55 | int b = (int) Math.sqrt(n - a * a); 56 | if (a * a + b * b == n) { 57 | return (a > 0 && b > 0) ? 2 : 1; 58 | } 59 | } 60 | return 3; 61 | } 62 | 63 | public static void main(String[] args) { 64 | for (int i = 1; i < 1000; i++) { 65 | System.out.println(i + " , " + numSquares1(i)); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/followup/IndexTreeTest.java: -------------------------------------------------------------------------------- 1 | package followup; 2 | 3 | public class IndexTreeTest { 4 | 5 | public static class IndexTree { 6 | 7 | private int[] tree; 8 | private int N; 9 | 10 | public IndexTree(int size) { 11 | N = size; 12 | tree = new int[N + 1]; 13 | } 14 | 15 | public int sum(int index) { 16 | int ret = 0; 17 | while (index > 0) { 18 | ret += tree[index]; 19 | index -= index & -index; 20 | } 21 | return ret; 22 | } 23 | 24 | public void add(int index, int d) { 25 | while (index <= N) { 26 | tree[index] += d; 27 | index += index & -index; 28 | } 29 | } 30 | } 31 | 32 | public static class Right { 33 | private int[] nums; 34 | private int N; 35 | 36 | public Right(int size) { 37 | N = size + 1; 38 | nums = new int[N + 1]; 39 | } 40 | 41 | public int sum(int index) { 42 | int ret = 0; 43 | for (int i = 1; i <= index; i++) { 44 | ret += nums[i]; 45 | } 46 | return ret; 47 | } 48 | 49 | public void add(int index, int d) { 50 | nums[index] += d; 51 | } 52 | 53 | } 54 | 55 | public static void main(String[] args) { 56 | int N = 100; 57 | int V = 100; 58 | int testTime = 2000000; 59 | IndexTree tree = new IndexTree(N); 60 | Right test = new Right(N); 61 | System.out.println("test begin"); 62 | for (int i = 0; i < testTime; i++) { 63 | int index = (int) (Math.random() * N) + 1; 64 | if (Math.random() <= 0.5) { 65 | int add = (int) (Math.random() * V); 66 | tree.add(index, add); 67 | test.add(index, add); 68 | } else { 69 | if (tree.sum(index) != test.sum(index)) { 70 | System.out.println("Oops!"); 71 | } 72 | } 73 | } 74 | System.out.println("test finish"); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0227_BasicCalculatorII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class Problem_0227_BasicCalculatorII { 6 | 7 | public static int calculate(String s) { 8 | char[] str = s.toCharArray(); 9 | LinkedList list = new LinkedList<>(); 10 | StringBuilder builder = new StringBuilder(); 11 | builder.setLength(0); 12 | for (int i = 0; i < str.length; i++) { 13 | if (str[i] != ' ') { 14 | if (str[i] >= '0' && str[i] <= '9') { 15 | builder.append(str[i]); 16 | } else { 17 | handleStack(list, builder.toString(), str[i]); 18 | builder.setLength(0); 19 | } 20 | } 21 | } 22 | handleStack(list, builder.toString(), ' '); 23 | return computeStack(list); 24 | } 25 | 26 | public static void handleStack(LinkedList list, String str, char op) { 27 | if (list.isEmpty() || (list.peekLast().equals("+") || list.peekLast().equals("-"))) { 28 | list.addLast(str); 29 | } else { 30 | int num = Integer.valueOf(str); 31 | String preOp = list.pollLast(); 32 | int preNum = Integer.valueOf(list.pollLast()); 33 | if (preOp.equals("*")) { 34 | list.addLast(String.valueOf(preNum * num)); 35 | } else { 36 | list.addLast(String.valueOf(preNum / num)); 37 | } 38 | } 39 | list.addLast(String.valueOf(op)); 40 | } 41 | 42 | public static int computeStack(LinkedList list) { 43 | int ans = Integer.valueOf(list.pollFirst()); 44 | while (list.size() != 1) { 45 | String op = list.pollFirst(); 46 | int cur = Integer.valueOf(list.pollFirst()); 47 | if (op.equals("+")) { 48 | ans += cur; 49 | } else { 50 | ans -= cur; 51 | } 52 | } 53 | return ans; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0037_SudokuSolver.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0037_SudokuSolver { 4 | 5 | public static void solveSudoku(char[][] board) { 6 | boolean[][] row = new boolean[9][10]; 7 | boolean[][] col = new boolean[9][10]; 8 | boolean[][] bucket = new boolean[9][10]; 9 | initMaps(board, row, col, bucket); 10 | process(board, 0, 0, row, col, bucket); 11 | } 12 | 13 | public static void initMaps(char[][] board, boolean[][] row, boolean[][] col, boolean[][] bucket) { 14 | for (int i = 0; i < 9; i++) { 15 | for (int j = 0; j < 9; j++) { 16 | int bid = 3 * (i / 3) + (j / 3); 17 | if (board[i][j] != '.') { 18 | int num = board[i][j] - '0'; 19 | row[i][num] = true; 20 | col[j][num] = true; 21 | bucket[bid][num] = true; 22 | } 23 | } 24 | } 25 | } 26 | 27 | public static boolean process(char[][] board, int i, int j, boolean[][] row, boolean[][] col, boolean[][] bucket) { 28 | if (i == 9) { 29 | return true; 30 | } 31 | int nexti = j != 8 ? i : i + 1; 32 | int nextj = j != 8 ? j + 1 : 0; 33 | if (board[i][j] != '.') { 34 | return process(board, nexti, nextj, row, col, bucket); 35 | } else { 36 | int bid = 3 * (i / 3) + (j / 3); 37 | for (int num = 1; num <= 9; num++) { 38 | if ((!row[i][num]) && (!col[j][num]) && (!bucket[bid][num])) { 39 | row[i][num] = true; 40 | col[j][num] = true; 41 | bucket[bid][num] = true; 42 | board[i][j] = (char) (num + '0'); 43 | if (process(board, nexti, nextj, row, col, bucket)) { 44 | return true; 45 | } 46 | row[i][num] = false; 47 | col[j][num] = false; 48 | bucket[bid][num] = false; 49 | board[i][j] = '.'; 50 | } 51 | } 52 | return false; 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/followup/FollowIndexTree.java: -------------------------------------------------------------------------------- 1 | package followup; 2 | 3 | public class FollowIndexTree { 4 | 5 | public static class IndexTree { 6 | 7 | private int[] tree; 8 | private int N; 9 | 10 | public IndexTree(int size) { 11 | N = size; 12 | tree = new int[N + 1]; 13 | } 14 | 15 | // 0 ~ index 范围上的累加和 16 | public int sum(int index) { 17 | int ret = 0; 18 | while (index > 0) { 19 | ret += tree[index]; 20 | index -= index & -index; 21 | } 22 | return ret; 23 | } 24 | 25 | // index位置的数,想加上d,还有哪些位置也要都加d 26 | public void add(int index, int d) { 27 | while (index <= N) { 28 | tree[index] += d; 29 | index += index & -index; 30 | } 31 | } 32 | } 33 | 34 | public static class Right { 35 | private int[] nums; 36 | private int N; 37 | 38 | public Right(int size) { 39 | N = size + 1; 40 | nums = new int[N + 1]; 41 | } 42 | 43 | public int sum(int index) { 44 | int ret = 0; 45 | for (int i = 1; i <= index; i++) { 46 | ret += nums[i]; 47 | } 48 | return ret; 49 | } 50 | 51 | public void add(int index, int d) { 52 | nums[index] += d; 53 | } 54 | 55 | } 56 | 57 | public static void main(String[] args) { 58 | int N = 100; 59 | int V = 100; 60 | int testTime = 2000000; 61 | IndexTree tree = new IndexTree(N); 62 | Right test = new Right(N); 63 | System.out.println("test begin"); 64 | for (int i = 0; i < testTime; i++) { 65 | int index = (int) (Math.random() * N) + 1; 66 | if (Math.random() <= 0.5) { 67 | int add = (int) (Math.random() * V); 68 | tree.add(index, add); 69 | test.add(index, add); 70 | } else { 71 | if (tree.sum(index) != test.sum(index)) { 72 | System.out.println("Oops!"); 73 | } 74 | } 75 | } 76 | System.out.println("test finish"); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0217_ContainsDuplicate.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.HashSet; 4 | 5 | public class Problem_0217_ContainsDuplicate { 6 | 7 | public boolean containsDuplicate1(int[] nums) { 8 | if (nums == null || nums.length < 2) { 9 | return false; 10 | } 11 | heapSort(nums); 12 | for (int i = 1; i < nums.length; i++) { 13 | if (nums[i] == nums[i - 1]) { 14 | return true; 15 | } 16 | } 17 | return false; 18 | } 19 | 20 | public static void heapSort(int[] arr) { 21 | if (arr == null || arr.length < 2) { 22 | return; 23 | } 24 | for (int i = arr.length - 1; i >= 0; i--) { 25 | heapify(arr, i, arr.length); 26 | } 27 | int heapSize = arr.length; 28 | swap(arr, 0, --heapSize); 29 | while (heapSize > 0) { 30 | heapify(arr, 0, heapSize); 31 | swap(arr, 0, --heapSize); 32 | } 33 | } 34 | 35 | public static void heapify(int[] arr, int index, int heapSize) { 36 | int left = index * 2 + 1; 37 | while (left < heapSize) { 38 | int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left; 39 | largest = arr[largest] > arr[index] ? largest : index; 40 | if (largest == index) { 41 | break; 42 | } 43 | swap(arr, largest, index); 44 | index = largest; 45 | left = index * 2 + 1; 46 | } 47 | } 48 | 49 | public static void swap(int[] arr, int i, int j) { 50 | int tmp = arr[i]; 51 | arr[i] = arr[j]; 52 | arr[j] = tmp; 53 | } 54 | 55 | public boolean containsDuplicate2(int[] nums) { 56 | if (nums == null || nums.length < 2) { 57 | return false; 58 | } 59 | HashSet set = new HashSet<>(); 60 | for (int num : nums) { 61 | if (set.contains(num)) { 62 | return true; 63 | } 64 | set.add(num); 65 | } 66 | return false; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0190_ReverseBits.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0190_ReverseBits { 4 | 5 | // 代码看着很魔幻吧? 6 | // 给个例子,假设n二进制为: 7 | // 1011 0111 0011 1001 0011 1111 0110 1010 8 | // 解释一下,第一行,是把n左边16位,和n右边16位交换 9 | // n = (n >>> 16) | (n << 16); 10 | // 因为 n >>> 16 就是左边16位被移动到了右侧 11 | // 同时 n << 16 就是右边16位被移动到了左侧 12 | // 又 | 在了一起,所以,n变成了 13 | // 0011 1111 0110 1010 1011 0111 0011 1001 14 | 15 | // 第二行, 16 | // n = ((n & 0xff00ff00) >>> 8) | ((n & 0x00ff00ff) << 8); 17 | // (n & 0xff00ff00) 18 | // 这一句意思是,左侧开始算0~7位,保留;8~15位,全变0;16~23位,保留;24~31位,全变0 19 | // 0011 1111 0000 0000 1011 0111 0000 0000 20 | // (n & 0xff00ff00) >>> 8 这句就是上面的值,统一向右移动8位,变成: 21 | // 0000 0000 0011 1111 0000 0000 1011 0111 22 | // 23 | // 24 | // (n & 0x00ff00ff) 25 | // 这一句意思是,左侧开始算0~7位,全变0;8~15位,保留;16~23位,全变0;24~31位,保留 26 | // 0000 0000 0110 1010 0000 0000 0011 1001 27 | // (n & 0x00ff00ff) << 8 这句就是上面的值,统一向左移动8位,变成: 28 | // 0110 1010 0000 0000 0011 1001 0000 0000 29 | // 那么 ((n & 0xff00ff00) >>> 8) | ((n & 0x00ff00ff) << 8) 30 | // 什么效果?就是n的0~7位和8~15位交换了,16~23位和24~31位交换了 31 | // 0110 1010 0011 1111 0011 1001 1011 0111 32 | 33 | // 也就是说,整个过程是n的左16位,和右16位交换 34 | // n的左16位的内部,左8位和右8位交换;n的右16位的内部,左8位和右8位交换 35 | // 接下来的一行,其实是,从左边开始算,0~7位内部,左4和右4交换;8~15位,左4和右4交换;... 36 | // 接下来的一行,其实是,从左边开始算,0~3位内部,左2和右2交换;4~7位,左2和右2交换;... 37 | // 最后的一行,其实是,从左边开始算,0~1位内部,左1和右1交换;2~3位,左1和右1交换;... 38 | 39 | 40 | public static int reverseBits(int n) { 41 | // n 42 | n = (n >>> 16) | (n << 16); 43 | n = ((n & 0xff00ff00) >>> 8) | ((n & 0x00ff00ff) << 8); 44 | n = ((n & 0xf0f0f0f0) >>> 4) | ((n & 0x0f0f0f0f) << 4); 45 | n = ((n & 0xcccccccc) >>> 2) | ((n & 0x33333333) << 2); 46 | n = ((n & 0xaaaaaaaa) >>> 1) | ((n & 0x55555555) << 1); 47 | return n; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0315_CountOfSmallerNumbersAfterSelf.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Problem_0315_CountOfSmallerNumbersAfterSelf { 7 | 8 | public static class Node { 9 | public int value; 10 | public int index; 11 | 12 | public Node(int v, int i) { 13 | value = v; 14 | index = i; 15 | } 16 | } 17 | 18 | public static List countSmaller(int[] nums) { 19 | List ans = new ArrayList<>(); 20 | if (nums == null) { 21 | return ans; 22 | } 23 | for (int i = 0; i < nums.length; i++) { 24 | ans.add(0); 25 | } 26 | if (nums.length < 2) { 27 | return ans; 28 | } 29 | Node[] arr = new Node[nums.length]; 30 | for (int i = 0; i < arr.length; i++) { 31 | arr[i] = new Node(nums[i], i); 32 | } 33 | process(arr, 0, arr.length - 1, ans); 34 | return ans; 35 | } 36 | 37 | public static void process(Node[] arr, int l, int r, List ans) { 38 | if (l == r) { 39 | return; 40 | } 41 | int mid = l + ((r - l) >> 1); 42 | process(arr, l, mid, ans); 43 | process(arr, mid + 1, r, ans); 44 | merge(arr, l, mid, r, ans); 45 | } 46 | 47 | public static void merge(Node[] arr, int l, int m, int r, List ans) { 48 | Node[] help = new Node[r - l + 1]; 49 | int i = help.length - 1; 50 | int p1 = m; 51 | int p2 = r; 52 | while (p1 >= l && p2 >= m + 1) { 53 | if (arr[p1].value > arr[p2].value) { 54 | ans.set(arr[p1].index, ans.get(arr[p1].index) + p2 - m); 55 | } 56 | help[i--] = arr[p1].value > arr[p2].value ? arr[p1--] : arr[p2--]; 57 | } 58 | while (p1 >= l) { 59 | help[i--] = arr[p1--]; 60 | } 61 | while (p2 >= m + 1) { 62 | help[i--] = arr[p2--]; 63 | } 64 | for (i = 0; i < help.length; i++) { 65 | arr[l + i] = help[i]; 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0149_MaxPointsOnALine.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class Problem_0149_MaxPointsOnALine { 7 | 8 | public static int maxPoints(int[][] points) { 9 | if (points == null) { 10 | return 0; 11 | } 12 | if (points.length <= 2) { 13 | return points.length; 14 | } 15 | // Map "3_5" 6 16 | // 3 / 5 4 17 | // 3 / 7 10 18 | // 3 / 17 11 19 | // 5 / 7 9 20 | // 5 / 9 3 21 | // 3 : ( 5 , 4 7, 10, 17 , 11 ) 22 | // 5 : ( 7 , 9 9, 3 ) 23 | Map> map = new HashMap>(); 24 | int result = 0; 25 | for (int i = 0; i < points.length; i++) { 26 | map.clear(); 27 | int samePosition = 1; 28 | int sameX = 0; 29 | int sameY = 0; 30 | int line = 0; // 哪个斜率压中的点最多,把最多的点的数量,赋值给line 31 | for (int j = i + 1; j < points.length; j++) { 32 | int x = points[j][0] - points[i][0]; 33 | int y = points[j][1] - points[i][1]; 34 | if (x == 0 && y == 0) { 35 | samePosition++; 36 | } else if (x == 0) { 37 | sameX++; 38 | } else if (y == 0) { 39 | sameY++; 40 | } else { // 有斜率 41 | int gcd = gcd(x, y); 42 | x /= gcd; 43 | y /= gcd; 44 | if (!map.containsKey(x)) { 45 | map.put(x, new HashMap()); 46 | } 47 | if (!map.get(x).containsKey(y)) { 48 | map.get(x).put(y, 0); 49 | } 50 | map.get(x).put(y, map.get(x).get(y) + 1); 51 | line = Math.max(line, map.get(x).get(y)); 52 | } 53 | } 54 | result = Math.max(result, Math.max(Math.max(sameX, sameY), line) + samePosition); 55 | } 56 | return result; 57 | } 58 | 59 | // 保证初始调用的时候,a和b不等于0 60 | // O(1) 61 | public static int gcd(int a, int b) { 62 | return b == 0 ? a : gcd(b, a % b); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0022_GenerateParentheses.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Problem_0022_GenerateParentheses { 7 | 8 | public static List generateParenthesis(int n) { 9 | char[] path = new char[n << 1]; 10 | List ans = new ArrayList<>(); 11 | process(path, 0, 0, n, ans); 12 | return ans; 13 | } 14 | 15 | // 依次在path上填写决定 16 | // ( ( ) ) ( ).... 17 | // 0 1 2 3 4 5 18 | // path[0...index-1]决定已经做完了 19 | // index位置上,( ) 20 | public static void process(char[] path, int index, int leftMinusRight, int leftRest, List ans) { 21 | if (index == path.length) { 22 | ans.add(String.valueOf(path)); 23 | } else { 24 | if (leftRest > 0) { 25 | path[index] = '('; 26 | process(path, index + 1, leftMinusRight + 1, leftRest - 1, ans); 27 | } 28 | if (leftMinusRight > 0) { 29 | path[index] = ')'; 30 | process(path, index + 1, leftMinusRight - 1, leftRest, ans); 31 | } 32 | } 33 | } 34 | 35 | // 不剪枝的做法 36 | public static List generateParenthesis2(int n) { 37 | char[] path = new char[n << 1]; 38 | List ans = new ArrayList<>(); 39 | process2(path, 0, ans); 40 | return ans; 41 | } 42 | 43 | public static void process2(char[] path, int index, List ans) { 44 | if (index == path.length) { 45 | if (isValid(path)) { 46 | ans.add(String.valueOf(path)); 47 | } 48 | } else { 49 | path[index] = '('; 50 | process2(path, index + 1, ans); 51 | path[index] = ')'; 52 | process2(path, index + 1, ans); 53 | } 54 | } 55 | 56 | public static boolean isValid(char[] path) { 57 | int count = 0; 58 | for (char cha : path) { 59 | if (cha == '(') { 60 | count++; 61 | } else { 62 | count--; 63 | } 64 | if (count < 0) { 65 | return false; 66 | } 67 | } 68 | return count == 0; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0322_CoinChange.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0322_CoinChange { 4 | 5 | public static int coinChange1(int[] coins, int amount) { 6 | if (coins == null || coins.length == 0 || amount < 0) { 7 | return -1; 8 | } 9 | int N = coins.length; 10 | int[][] dp = new int[N + 1][amount + 1]; 11 | for (int col = 1; col <= amount; col++) { 12 | dp[N][col] = -1; 13 | } 14 | for (int i = N - 1; i >= 0; i--) { 15 | for (int rest = 0; rest <= amount; rest++) { 16 | dp[i][rest] = -1; 17 | if (dp[i + 1][rest] != -1) { 18 | dp[i][rest] = dp[i + 1][rest]; 19 | } 20 | if (rest - coins[i] >= 0 && dp[i][rest - coins[i]] != -1) { 21 | if (dp[i][rest] == -1) { 22 | dp[i][rest] = dp[i][rest - coins[i]] + 1; 23 | } else { 24 | dp[i][rest] = Math.min(dp[i][rest], dp[i][rest - coins[i]] + 1); 25 | } 26 | } 27 | } 28 | } 29 | return dp[0][amount]; 30 | } 31 | 32 | public static int coinChange2(int[] coins, int aim) { 33 | if (coins == null || coins.length == 0 || aim < 0) { 34 | return -1; 35 | } 36 | int N = coins.length; 37 | int[][] dp = new int[N][aim + 1]; 38 | // dp[i][0] = 0 0列不需要填 39 | // dp[0][1...] = arr[0]的整数倍,有张数,倍数,其他的格子-1(表示无方案) 40 | for (int j = 1; j <= aim; j++) { 41 | if (j % coins[0] != 0) { 42 | dp[0][j] = -1; 43 | } else { 44 | dp[0][j] = j / coins[0]; 45 | } 46 | } 47 | 48 | for (int i = 1; i < N; i++) { 49 | for (int j = 1; j <= aim; j++) { 50 | dp[i][j] = Integer.MAX_VALUE; 51 | if (dp[i - 1][j] != -1) { 52 | dp[i][j] = dp[i - 1][j]; 53 | } 54 | if (j - coins[i] >= 0 && dp[i][j - coins[i]] != -1) { 55 | dp[i][j] = Math.min(dp[i][j], dp[i][j - coins[i]] + 1); 56 | } 57 | if (dp[i][j] == Integer.MAX_VALUE) { 58 | dp[i][j] = -1; 59 | } 60 | } 61 | } 62 | return dp[N - 1][aim]; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0210_CourseScheduleII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.LinkedList; 6 | import java.util.Queue; 7 | 8 | public class Problem_0210_CourseScheduleII { 9 | 10 | public static class Node { 11 | public int name; 12 | public int in; 13 | public ArrayList nexts; 14 | 15 | public Node(int n) { 16 | name = n; 17 | in = 0; 18 | nexts = new ArrayList<>(); 19 | } 20 | } 21 | 22 | public int[] findOrder(int numCourses, int[][] prerequisites) { 23 | int[] ans = new int[numCourses]; 24 | for (int i = 0; i < numCourses; i++) { 25 | ans[i] = i; 26 | } 27 | if (prerequisites == null || prerequisites.length == 0) { 28 | return ans; 29 | } 30 | HashMap nodes = new HashMap<>(); 31 | for (int[] arr : prerequisites) { 32 | int to = arr[0]; 33 | int from = arr[1]; 34 | if (!nodes.containsKey(to)) { 35 | nodes.put(to, new Node(to)); 36 | } 37 | if (!nodes.containsKey(from)) { 38 | nodes.put(from, new Node(from)); 39 | } 40 | Node t = nodes.get(to); 41 | Node f = nodes.get(from); 42 | f.nexts.add(t); 43 | t.in++; 44 | } 45 | int index = 0; 46 | Queue zeroInQueue = new LinkedList<>(); 47 | for (int i = 0; i < numCourses; i++) { 48 | if (!nodes.containsKey(i)) { 49 | ans[index++] = i; 50 | } else { 51 | if (nodes.get(i).in == 0) { 52 | zeroInQueue.add(nodes.get(i)); 53 | } 54 | } 55 | } 56 | int needPrerequisiteNums = nodes.size(); 57 | int count = 0; 58 | while (!zeroInQueue.isEmpty()) { 59 | Node cur = zeroInQueue.poll(); 60 | ans[index++] = cur.name; 61 | count++; 62 | for (Node next : cur.nexts) { 63 | if (--next.in == 0) { 64 | zeroInQueue.add(next); 65 | } 66 | } 67 | } 68 | return count == needPrerequisiteNums ? ans : new int[0]; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/followup/Code03_Array.java: -------------------------------------------------------------------------------- 1 | package followup; 2 | 3 | public class Code03_Array { 4 | 5 | public static int findError(String[] contents) { 6 | if (contents == null || contents.length == 0) { 7 | return 0; 8 | } 9 | String arrName = contents[0].substring(0, contents[0].indexOf("[")); 10 | int arrSize = Integer.valueOf(contents[0].substring(contents[0].indexOf("[") + 1, contents[0].indexOf("]"))); 11 | int[] arr = new int[arrSize]; 12 | for (int i = 1; i < contents.length; i++) { 13 | String[] parts = contents[i].replace(" ", "").split("="); 14 | String left = parts[0].replace(arrName, ""); 15 | left = left.substring(1, left.length() - 1); 16 | String right = parts[1].replace(arrName, ""); 17 | Integer leftIndex = value(left, arr); 18 | Integer rightValue = value(right, arr); 19 | if (leftIndex == null || rightValue == null) { 20 | return i; 21 | } 22 | if (leftIndex < 0 || leftIndex >= arrSize) { 23 | return i; 24 | } 25 | arr[leftIndex] = rightValue; 26 | } 27 | return 0; 28 | } 29 | 30 | // str -> " [[[7]]] " 返回什么 31 | public static Integer value(String str, int[] arr) { 32 | int value = Integer.valueOf(str.replace("[", "").replace("]", "")); 33 | int levels = str.lastIndexOf("[") + 1; 34 | for (int i = 0; i < levels; i++) { 35 | if (value < 0 || value >= arr.length) { 36 | return null; 37 | } 38 | value = arr[value]; 39 | } 40 | return value; 41 | } 42 | 43 | public static void main(String[] args) { 44 | String[] contents = { 45 | "arr[7]", 46 | "arr[0]=6", 47 | "arr[1]=3", 48 | "arr[2]=1", 49 | "arr[3]=2", 50 | "arr[4]=4", 51 | "arr[5]=0", 52 | "arr[6]=5", 53 | "arr[arr[1]]=3", 54 | "arr[arr[arr[arr[5]]]]=arr[arr[arr[3]]]", 55 | "arr[arr[4]]=arr[arr[arr[0]]]", 56 | "arr[arr[1]] = 7", 57 | "arr[0] = arr[arr[arr[1]]]" }; 58 | System.out.println(findError(contents)); 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0073_SetMatrixZeroes.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0073_SetMatrixZeroes { 4 | 5 | public static void setZeroes1(int[][] matrix) { 6 | boolean row0Zero = false; 7 | boolean col0Zero = false; 8 | int i = 0; 9 | int j = 0; 10 | for (i = 0; i < matrix[0].length; i++) { 11 | if (matrix[0][i] == 0) { 12 | row0Zero = true; 13 | break; 14 | } 15 | } 16 | for (i = 0; i < matrix.length; i++) { 17 | if (matrix[i][0] == 0) { 18 | col0Zero = true; 19 | break; 20 | } 21 | } 22 | for (i = 1; i < matrix.length; i++) { 23 | for (j = 1; j < matrix[0].length; j++) { 24 | if (matrix[i][j] == 0) { 25 | matrix[i][0] = 0; 26 | matrix[0][j] = 0; 27 | } 28 | } 29 | } 30 | for (i = 1; i < matrix.length; i++) { 31 | for (j = 1; j < matrix[0].length; j++) { 32 | if (matrix[i][0] == 0 || matrix[0][j] == 0) { 33 | matrix[i][j] = 0; 34 | } 35 | } 36 | } 37 | if (row0Zero) { 38 | for (i = 0; i < matrix[0].length; i++) { 39 | matrix[0][i] = 0; 40 | } 41 | } 42 | if (col0Zero) { 43 | for (i = 0; i < matrix.length; i++) { 44 | matrix[i][0] = 0; 45 | } 46 | } 47 | } 48 | 49 | public static void setZeroes2(int[][] matrix) { 50 | boolean col0 = false; 51 | int i = 0; 52 | int j = 0; 53 | for (i = 0; i < matrix.length; i++) { 54 | for (j = 0; j < matrix[0].length; j++) { 55 | if (matrix[i][j] == 0) { 56 | matrix[i][0] = 0; 57 | if (j == 0) { 58 | col0 = true; 59 | } else { 60 | matrix[0][j] = 0; 61 | } 62 | } 63 | } 64 | } 65 | for (i = matrix.length - 1; i >= 0; i--) { 66 | for (j = 1; j < matrix[0].length; j++) { 67 | if (matrix[i][0] == 0 || matrix[0][j] == 0) { 68 | matrix[i][j] = 0; 69 | } 70 | } 71 | } 72 | if (col0) { 73 | for (i = 0; i < matrix.length; i++) { 74 | matrix[i][0] = 0; 75 | } 76 | } 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0269_AlienDictionary.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.LinkedList; 6 | import java.util.Queue; 7 | 8 | public class Problem_0269_AlienDictionary { 9 | 10 | public static String alienOrder(String[] words) { 11 | if (words == null || words.length == 0) { 12 | return ""; 13 | } 14 | int N = words.length; 15 | HashMap indegree = new HashMap<>(); 16 | for (int i = 0; i < N; i++) { 17 | for (char c : words[i].toCharArray()) { 18 | indegree.put(c, 0); 19 | } 20 | } 21 | HashMap> graph = new HashMap<>(); 22 | for (int i = 0; i < N - 1; i++) { 23 | char[] cur = words[i].toCharArray(); 24 | char[] nex = words[i + 1].toCharArray(); 25 | int len = Math.min(cur.length, nex.length); 26 | int j = 0; 27 | for (; j < len; j++) { 28 | if (cur[j] != nex[j]) { 29 | if (!graph.containsKey(cur[j])) { 30 | graph.put(cur[j], new HashSet<>()); 31 | } 32 | if (!graph.get(cur[j]).contains(nex[j])) { 33 | graph.get(cur[j]).add(nex[j]); 34 | indegree.put(nex[j], indegree.get(nex[j]) + 1); 35 | } 36 | break; 37 | } 38 | } 39 | if (j < cur.length && j == nex.length) { 40 | return ""; 41 | } 42 | } 43 | StringBuilder ans = new StringBuilder(); 44 | Queue q = new LinkedList<>(); 45 | for (Character key : indegree.keySet()) { 46 | if (indegree.get(key) == 0) { 47 | q.offer(key); 48 | } 49 | } 50 | while (!q.isEmpty()) { 51 | char cur = q.poll(); 52 | ans.append(cur); 53 | if (graph.containsKey(cur)) { 54 | for (char next : graph.get(cur)) { 55 | indegree.put(next, indegree.get(next) - 1); 56 | if (indegree.get(next) == 0) { 57 | q.offer(next); 58 | } 59 | } 60 | } 61 | } 62 | return ans.length() == indegree.size() ? ans.toString() : ""; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0046_Permutations.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | 7 | public class Problem_0046_Permutations { 8 | 9 | public static List> onClass(int[] nums) { 10 | List> ans = new ArrayList<>(); 11 | HashSet rest = new HashSet<>(); 12 | for (int num : nums) { 13 | rest.add(num); 14 | } 15 | ArrayList path = new ArrayList<>(); 16 | f(rest, path, ans); 17 | return ans; 18 | } 19 | 20 | // rest中有剩余数字,已经选过的数字不在rest中,选过的数字在path里 21 | public static void f(HashSet rest, ArrayList path, List> ans) { 22 | if (rest.isEmpty()) { 23 | ans.add(path); 24 | } else { 25 | for (int num : rest) { 26 | ArrayList curPath = new ArrayList<>(path); 27 | curPath.add(num); 28 | HashSet clone = cloneExceptNum(rest, num); 29 | f(clone, curPath, ans); 30 | } 31 | } 32 | } 33 | 34 | public static HashSet cloneExceptNum(HashSet rest, int num) { 35 | HashSet clone = new HashSet<>(rest); 36 | clone.remove(num); 37 | return clone; 38 | } 39 | 40 | public static List> permute(int[] nums) { 41 | List> ans = new ArrayList<>(); 42 | process(nums, 0, ans); 43 | return ans; 44 | } 45 | 46 | public static void process(int[] nums, int index, List> ans) { 47 | if (index == nums.length) { 48 | ArrayList cur = new ArrayList<>(); 49 | for (int num : nums) { 50 | cur.add(num); 51 | } 52 | ans.add(cur); 53 | } else { 54 | for (int j = index; j < nums.length; j++) { 55 | swap(nums, index, j); 56 | process(nums, index + 1, ans); 57 | swap(nums, index, j); 58 | } 59 | } 60 | } 61 | 62 | public static void swap(int[] nums, int i, int j) { 63 | int tmp = nums[i]; 64 | nums[i] = nums[j]; 65 | nums[j] = tmp; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0131_PalindromePartitioning.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | public class Problem_0131_PalindromePartitioning { 8 | 9 | public static List> partition(String s) { 10 | // dp[L][R] -> 是不是回文 11 | boolean[][] dp = getdp(s.toCharArray()); 12 | LinkedList path = new LinkedList<>(); 13 | List> ans = new ArrayList<>(); 14 | process(s, 0, path, dp, ans); 15 | return ans; 16 | } 17 | 18 | public static boolean[][] getdp(char[] str) { 19 | int N = str.length; 20 | boolean[][] dp = new boolean[N][N]; 21 | for (int i = 0; i < N - 1; i++) { 22 | dp[i][i] = true; 23 | dp[i][i + 1] = str[i] == str[i + 1]; 24 | } 25 | dp[N - 1][N - 1] = true; 26 | for (int j = 2; j < N; j++) { 27 | int row = 0; 28 | int col = j; 29 | while (row < N && col < N) { 30 | dp[row][col] = str[row] == str[col] && dp[row + 1][col - 1]; 31 | row++; 32 | col++; 33 | } 34 | } 35 | return dp; 36 | } 37 | 38 | // s 字符串 39 | // s[0...index-1] 已经做过的决定,放入了path中 40 | // 在index开始做属于这个位置的决定, 41 | // index == s.len path之前做的决定(一种分割方法),放进总答案ans里 42 | public static void process(String s, int index, LinkedList path, 43 | boolean[][] dp, List> ans) { 44 | if (index == s.length()) { 45 | ans.add(copy(path)); 46 | } else { 47 | for (int end = index; end < s.length(); end++) { 48 | // index..index 49 | // index..index+1 50 | // index..index+2 51 | // index..end 52 | if (dp[index][end]) { 53 | path.addLast(s.substring(index, end + 1)); 54 | process(s, end + 1, path, dp, ans); 55 | path.pollLast(); 56 | } 57 | } 58 | } 59 | } 60 | 61 | public static List copy(List path) { 62 | List ans = new ArrayList<>(); 63 | for (String p : path) { 64 | ans.add(p); 65 | } 66 | return ans; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0772_BasicCalculatorIII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class Problem_0772_BasicCalculatorIII { 6 | 7 | public static int calculate(String str) { 8 | return f(str.toCharArray(), 0)[0]; 9 | } 10 | 11 | // 请从str[i...]往下算,遇到字符串终止位置或者右括号,就停止 12 | // 返回两个值,长度为2的数组 13 | // 0) 负责的这一段的结果是多少 14 | // 1) 负责的这一段计算到了哪个位置 15 | public static int[] f(char[] str, int i) { 16 | LinkedList que = new LinkedList(); 17 | int cur = 0; 18 | int[] bra = null; 19 | // 从i出发,开始撸str 20 | while (i < str.length && str[i] != ')') { 21 | if (str[i] == ' ') { 22 | i++; 23 | continue; 24 | } 25 | if (str[i] >= '0' && str[i] <= '9') { 26 | cur = cur * 10 + str[i++] - '0'; 27 | } else if (str[i] != '(') { // 你遇到了运算符 28 | // que 接受的是str的东西,cur是一个整型 29 | addNum(que, cur); 30 | que.addLast(String.valueOf(str[i++])); 31 | cur = 0; 32 | } else { // 遇到i左括号了 33 | bra = f(str, i + 1); 34 | cur = bra[0]; 35 | i = bra[1] + 1; 36 | } 37 | } 38 | addNum(que, cur); 39 | return new int[] { getNum(que), i }; 40 | } 41 | 42 | public static void addNum(LinkedList que, int num) { 43 | if (!que.isEmpty()) { 44 | int cur = 0; 45 | String top = que.pollLast(); 46 | if (top.equals("+") || top.equals("-")) { 47 | que.addLast(top); 48 | } else { 49 | cur = Integer.valueOf(que.pollLast()); 50 | num = top.equals("*") ? (cur * num) : (cur / num); 51 | } 52 | } 53 | que.addLast(String.valueOf(num)); 54 | } 55 | 56 | public static int getNum(LinkedList que) { 57 | int res = 0; 58 | boolean add = true; 59 | String cur = null; 60 | int num = 0; 61 | while (!que.isEmpty()) { 62 | cur = que.pollFirst(); 63 | if (cur.equals("+")) { 64 | add = true; 65 | } else if (cur.equals("-")) { 66 | add = false; 67 | } else { 68 | num = Integer.valueOf(cur); 69 | res += add ? num : (-num); 70 | } 71 | } 72 | return res; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0008_StringToInteger.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0008_StringToInteger { 4 | 5 | public static int myAtoi(String s) { 6 | if (s == null || s.equals("")) { 7 | return 0; 8 | } 9 | s = removeHeadZero(s.trim()); 10 | if (s == null || s.equals("")) { 11 | return 0; 12 | } 13 | char[] str = s.toCharArray(); 14 | if (!isValid(str)) { 15 | return 0; 16 | } 17 | // str 是符合日常书写的,正经整数形式 18 | boolean posi = str[0] == '-' ? false : true; 19 | int minq = Integer.MIN_VALUE / 10; 20 | int minr = Integer.MIN_VALUE % 10; 21 | int res = 0; 22 | int cur = 0; 23 | for (int i = (str[0] == '-' || str[0] == '+') ? 1 : 0; i < str.length; i++) { 24 | cur = '0' - str[i]; 25 | if ((res < minq) || (res == minq && cur < minr)) { 26 | return posi ? Integer.MAX_VALUE : Integer.MIN_VALUE; 27 | } 28 | res = res * 10 + cur; 29 | } 30 | // res 负 31 | if (posi && res == Integer.MIN_VALUE) { 32 | return Integer.MAX_VALUE; 33 | } 34 | return posi ? -res : res; 35 | } 36 | 37 | public static String removeHeadZero(String str) { 38 | boolean r = (str.startsWith("+") || str.startsWith("-")); 39 | int s = r ? 1 : 0; 40 | for (; s < str.length(); s++) { 41 | if (str.charAt(s) != '0') { 42 | break; 43 | } 44 | } 45 | // s 到了第一个不是'0'字符的位置 46 | int e = -1; 47 | // 左<-右 48 | for (int i = str.length() - 1; i >= (r ? 1 : 0); i--) { 49 | if (str.charAt(i) < '0' || str.charAt(i) > '9') { 50 | e = i; 51 | } 52 | } 53 | // e 到了最左的 不是数字字符的位置 54 | return (r ? String.valueOf(str.charAt(0)) : "") + str.substring(s, e == -1 ? str.length() : e); 55 | } 56 | 57 | public static boolean isValid(char[] chas) { 58 | if (chas[0] != '-' && chas[0] != '+' && (chas[0] < '0' || chas[0] > '9')) { 59 | return false; 60 | } 61 | if ((chas[0] == '-' || chas[0] == '+') && chas.length == 1) { 62 | return false; 63 | } 64 | // 0 +... -... num 65 | for (int i = 1; i < chas.length; i++) { 66 | if (chas[i] < '0' || chas[i] > '9') { 67 | return false; 68 | } 69 | } 70 | return true; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0029_DivideTwoIntegers.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0029_DivideTwoIntegers { 4 | 5 | public static int add(int a, int b) { 6 | int sum = a; 7 | while (b != 0) { 8 | sum = a ^ b; 9 | b = (a & b) << 1; 10 | a = sum; 11 | } 12 | return sum; 13 | } 14 | 15 | public static int negNum(int n) { 16 | return add(~n, 1); 17 | } 18 | 19 | public static int minus(int a, int b) { 20 | return add(a, negNum(b)); 21 | } 22 | 23 | public static int multi(int a, int b) { 24 | int res = 0; 25 | while (b != 0) { 26 | if ((b & 1) != 0) { 27 | res = add(res, a); 28 | } 29 | a <<= 1; 30 | b >>>= 1; 31 | } 32 | return res; 33 | } 34 | 35 | public static boolean isNeg(int n) { 36 | return n < 0; 37 | } 38 | 39 | public static int div(int a, int b) { 40 | int x = isNeg(a) ? negNum(a) : a; 41 | int y = isNeg(b) ? negNum(b) : b; 42 | int res = 0; 43 | for (int i = 31; i > negNum(1); i = minus(i, 1)) { 44 | if ((x >> i) >= y) { 45 | res |= (1 << i); 46 | x = minus(x, y << i); 47 | } 48 | } 49 | return isNeg(a) ^ isNeg(b) ? negNum(res) : res; 50 | } 51 | 52 | public static int divide(int dividend, int divisor) { 53 | if (divisor == Integer.MIN_VALUE) { 54 | return dividend == Integer.MIN_VALUE ? 1 : 0; 55 | } 56 | // 除数不是系统最小 57 | if (dividend == Integer.MIN_VALUE) { 58 | if (divisor == negNum(1)) { 59 | return Integer.MAX_VALUE; 60 | } 61 | int res = div(add(dividend, 1), divisor); 62 | return add(res, div(minus(dividend, multi(res, divisor)), divisor)); 63 | } 64 | // dividend不是系统最小,divisor也不是系统最小 65 | return div(dividend, divisor); 66 | } 67 | // div(a,b) a和b都不能是系统最小 68 | 69 | // 现场福利函数 70 | public static String printNumBinary(int num) { 71 | StringBuilder builder = new StringBuilder(); 72 | for (int i = 31; i >= 0; i--) { 73 | builder.append(((num >> i) & 1) == 0 ? '0' : '1'); 74 | } 75 | return builder.toString(); 76 | } 77 | 78 | public static void main(String[] args) { 79 | int num = -1; 80 | System.out.println(printNumBinary(num)); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/followup/Code04_Painting.java: -------------------------------------------------------------------------------- 1 | package followup; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Code04_Painting { 7 | // N * M的棋盘 8 | // 所有格子必须染色 9 | // 每种颜色的格子数必须相同的 10 | // 相邻格子染的颜色必须不同 11 | // 返回至少多少种颜色可以完成任务 12 | 13 | // 暴力解 14 | public static int minColors(int N, int M) { 15 | for (int i = 2; i <= N * M; i++) { 16 | int[][] matrix = new int[N][M]; 17 | // 下面这一句可知,需要的最少颜色数i,一定是N*M的某个因子 18 | if ((N * M) % i == 0 && can(matrix, N, M, i)) { 19 | return i; 20 | } 21 | } 22 | return N * M; 23 | } 24 | 25 | // 在matrix上染色,返回只用pNum种颜色是否可以做到要求 26 | public static boolean can(int[][] matrix, int N, int M, int pNum) { 27 | int all = N * M; 28 | int every = all / pNum; 29 | ArrayList rest = new ArrayList<>(); 30 | rest.add(0); 31 | for (int i = 1; i <= pNum; i++) { 32 | rest.add(every); 33 | } 34 | return process(matrix, N, M, pNum, 0, 0, rest); 35 | } 36 | 37 | public static boolean process(int[][] matrix, int N, int M, int pNum, int row, int col, List rest) { 38 | if (row == N) { 39 | return true; 40 | } 41 | if (col == M) { 42 | return process(matrix, N, M, pNum, row + 1, 0, rest); 43 | } 44 | int left = col == 0 ? 0 : matrix[row][col - 1]; 45 | int up = row == 0 ? 0 : matrix[row - 1][col]; 46 | for (int color = 1; color <= pNum; color++) { 47 | if (color != left && color != up && rest.get(color) > 0) { 48 | int count = rest.get(color); 49 | rest.set(color, count - 1); 50 | matrix[row][col] = color; 51 | if (process(matrix, N, M, pNum, row, col + 1, rest)) { 52 | return true; 53 | } 54 | rest.set(color, count); 55 | matrix[row][col] = 0; 56 | } 57 | } 58 | return false; 59 | } 60 | 61 | public static void main(String[] args) { 62 | // 根据代码16行的提示,打印出答案,看看是答案是哪个因子 63 | for (int N = 2; N < 11; N++) { 64 | for (int M = 2; M < 11; M++) { 65 | System.out.println("N = " + N); 66 | System.out.println("M = " + M); 67 | System.out.println("ans = " + minColors(N, M)); 68 | System.out.println("==========="); 69 | } 70 | } 71 | // 打印答案,分析可知,是N*M最小的质数因子,原因不明,也不重要 72 | // 反正打表法猜出来了 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/followup/Code02_Drive.java: -------------------------------------------------------------------------------- 1 | package followup; 2 | 3 | public class Code02_Drive { 4 | 5 | /* 6 | * 司机调度 时间限制: 3000MS 内存限制: 589824KB 题目描述: 7 | * 正值下班高峰时期,现有可载客司机数2N人,调度中心将调度相关司机服务A、B两个出行高峰区域。 第 i 个司机前往服务A区域可得收入为 8 | * income[i][0],前往服务B区域可得收入为 income[i][1]。 9 | * 返回将每位司机调度完成服务后,所有司机总可得的最高收入金额,要求每个区域都有 N 位司机服务。 输入描述 10 20 20 40 # 如上: 10 | * 第一个司机服务 A 区域,收入为 10元 第一个司机服务 B 区域,收入为 20元 第二个司机服务 A 区域,收入为 20元 第二个司机服务 B 11 | * 区域,收入为 40元 输入参数以 '#' 结束输入 输出描述 最高总收入为 10 + 40= 50,每个区域都有一半司机服务 12 | * 参数及相关数据异常请输出:error 样例输入 : 10 30 100 200 150 50 60 20 # 样例输出 440 13 | */ 14 | 15 | // 给定一个N*2的正数矩阵matix,N一定是偶数,可以保证。 16 | // 一定要让A区域分到N/2个司机,让B区域也分到N/2个司机 17 | // 返回最大的总收益 18 | public static int maxMoney(int[][] matrix) { 19 | // 0..... 20 | // N A N/2 B N/2 21 | return process2(matrix, 0, matrix.length / 2); 22 | } 23 | 24 | // int[][] matrix N * 2 大小的 25 | // i A : matrix[i][0] B : matrix[i][1] 26 | // 0..i-1司机,已经做完选择了,不用再操心了, 27 | // 从i开始到最后所有的司机,在A区域还有aRest个名额的情况下,返回最优分配的收益 28 | public static int process(int[][] matrix, int i, int aRest) { 29 | if (aRest < 0) { 30 | return -1; 31 | } 32 | // aRest >= 0 N A 耗尽 A B 33 | if (i == matrix.length) { 34 | return aRest == 0 ? 0 : -1; 35 | } 36 | // aRest >= 0 && 还有司机选 37 | int goToA = -1; 38 | // 当前司机 i 决定去A区域之后,后续过程最好的收益,nextA 39 | int nextA = process(matrix, i + 1, aRest - 1); 40 | if (nextA != -1) { 41 | goToA = matrix[i][0] + nextA; 42 | } 43 | int goToB = -1; 44 | int nextB = process(matrix, i + 1, aRest); 45 | if (nextB != -1) { 46 | goToB = matrix[i][1] + nextB; 47 | } 48 | return Math.max(goToA, goToB); 49 | } 50 | 51 | 52 | 53 | public static int process2(int[][] matrix, int i, int aRest) { 54 | if (i == matrix.length) { 55 | return aRest == 0 ? 0 : -1; 56 | } 57 | int goToA = -1; 58 | if(aRest > 0) { 59 | goToA = matrix[i][0] + process2(matrix, i+1, aRest - 1); 60 | } 61 | int goToB = -1; 62 | int goAs = (matrix.length / 2) - aRest; 63 | int goBs = i - goAs; 64 | if(goBs < (matrix.length / 2)) { 65 | goToB = matrix[i][1] + process2(matrix, i+1, aRest); 66 | } 67 | return Math.max(goToA, goToB); 68 | } 69 | 70 | public static void main(String[] args) { 71 | int[][] matrix = { { 10, 20 }, { 20, 40 } }; 72 | 73 | System.out.println(maxMoney(matrix)); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/followup/AddDevideNum.java: -------------------------------------------------------------------------------- 1 | package followup; 2 | 3 | import java.util.HashMap; 4 | 5 | /* 6 | * 100 = 3 + 69258 / 714 7 | * 100 = 82 + 3546 / 197 8 | * 9 | * 等号右边的部分,可以写成 p1 + p2 / p3的形式 10 | * 要求p1和p2和p3,所使用的数字,必须把1~9使用完全,并且不重复 11 | * 满足的话,我们就说,形如p1 + p2 / p3,一个有效的"带分数"形式 12 | * 要求,p2 / p3 必须整除 13 | * 14 | * 输入N,返回N有多少种带分数形式 15 | * 100,有11种带分数形式 16 | * 17 | * 输入的N,N < 10的8次方 18 | * 19 | * 20 | * */ 21 | public class AddDevideNum { 22 | 23 | public static HashMap map = new HashMap(); 24 | 25 | public static int[] arr = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; 26 | 27 | public static int ways(int n) { 28 | if (map.size() == 0) { 29 | process(123456789, 8); 30 | } 31 | return map.containsKey(n) ? map.get(n) : 0; 32 | } 33 | 34 | public static void process(int num, int index) { 35 | if (index == -1) { 36 | for (int add = 8; add >= 2; add--) { 37 | int p1 = num / arr[add]; 38 | int rest = num % arr[add]; 39 | for (int dev = (add >> 1); dev >= 1; dev--) { 40 | int p2 = rest / arr[dev]; 41 | int p3 = rest % arr[dev]; 42 | if (p2 % p3 == 0) { 43 | int ans = p1 + (p2 / p3); 44 | if (!map.containsKey(ans)) { 45 | map.put(ans, 1); 46 | } else { 47 | map.put(ans, map.get(ans) + 1); 48 | } 49 | } 50 | } 51 | } 52 | } else { 53 | for (int swap = index; swap >= 0; swap--) { 54 | process(swap(num, index, swap), index - 1); 55 | } 56 | } 57 | } 58 | 59 | public static int swap(int num, int L, int R) { 60 | int bitL = (num / arr[L]) % 10; 61 | int bitR = (num / arr[R]) % 10; 62 | return num + (bitR - bitL) * arr[L] - (bitR - bitL) * arr[R]; 63 | } 64 | 65 | public static void main(String[] args) { 66 | int N = 100; 67 | long start; 68 | long end; 69 | // 第一次跑要去生成map,需要100多毫秒, 70 | // 但是只需要在第一次生成,以后都是直接查询的 71 | start = System.currentTimeMillis(); 72 | System.out.println(N + "用带分数表示的方法数 : " + ways(N)); 73 | end = System.currentTimeMillis(); 74 | System.out.println("运行了(毫秒) : " + (end - start)); 75 | // 第二次跑map已经在上面生成好了,自然很快 76 | N = 10000; 77 | start = System.currentTimeMillis(); 78 | System.out.println(N + "用带分数表示的方法数 : " + ways(N)); 79 | end = System.currentTimeMillis(); 80 | System.out.println("运行了(毫秒) : " + (end - start)); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0015_3Sum.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class Problem_0015_3Sum { 8 | 9 | public static List> threeSum1(int[] nums) { 10 | Arrays.sort(nums); 11 | List> ans = new ArrayList<>(); 12 | // 第一个数选了i位置的数 13 | for (int i = 0; i < nums.length - 2; i++) { 14 | if (i == 0 || nums[i - 1] != nums[i]) { 15 | List> nexts = twoSum1(nums, i + 1, -nums[i]); 16 | for (List cur : nexts) { 17 | cur.add(0, nums[i]); 18 | ans.add(cur); 19 | } 20 | } 21 | } 22 | return ans; 23 | } 24 | 25 | // nums已经有序了 26 | // nums[begin......]范围上,找到累加和为target的所有二元组 27 | public static List> twoSum1(int[] nums, int begin, int target) { 28 | int L = begin; 29 | int R = nums.length - 1; 30 | List> ans = new ArrayList<>(); 31 | while (L < R) { 32 | if (nums[L] + nums[R] > target) { 33 | R--; 34 | } else if (nums[L] + nums[R] < target) { 35 | L++; 36 | } else { 37 | if (L == begin || nums[L - 1] != nums[L]) { 38 | List cur = new ArrayList<>(); 39 | cur.add(nums[L]); 40 | cur.add(nums[R]); 41 | ans.add(cur); 42 | } 43 | L++; 44 | } 45 | } 46 | return ans; 47 | } 48 | 49 | public static List> threeSum2(int[] nums) { 50 | Arrays.sort(nums); 51 | int N = nums.length; 52 | List> ans = new ArrayList<>(); 53 | for (int i = N - 1; i > 1; i--) { 54 | if (i == N - 1 || nums[i] != nums[i + 1]) { 55 | List> nexts = twoSum2(nums, i - 1, -nums[i]); 56 | for (List cur : nexts) { 57 | cur.add(nums[i]); 58 | ans.add(cur); 59 | } 60 | } 61 | } 62 | return ans; 63 | } 64 | 65 | public static List> twoSum2(int[] nums, int end, int target) { 66 | int L = 0; 67 | int R = end; 68 | List> ans = new ArrayList<>(); 69 | while (L < R) { 70 | if (nums[L] + nums[R] > target) { 71 | R--; 72 | } else if (nums[L] + nums[R] < target) { 73 | L++; 74 | } else { 75 | if (L == 0 || nums[L - 1] != nums[L]) { 76 | List cur = new ArrayList<>(); 77 | cur.add(nums[L]); 78 | cur.add(nums[R]); 79 | ans.add(cur); 80 | } 81 | L++; 82 | } 83 | } 84 | return ans; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0091_DecodeWays.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0091_DecodeWays { 4 | 5 | public static int numDecodings1(String s) { 6 | if (s == null || s.length() == 0) { 7 | return 0; 8 | } 9 | char[] str = s.toCharArray(); 10 | return process(str, 0); 11 | } 12 | 13 | // 潜台词:str[0...index-1]已经转化完了,不用操心了 14 | // str[index....] 能转出多少有效的,返回方法数 15 | public static int process(char[] str, int index) { 16 | if (index == str.length) { 17 | return 1; 18 | } 19 | if (str[index] == '0') { 20 | return 0; 21 | } 22 | // index还有字符, 又不是‘0’ 23 | // 1) (index 1 ~ 9) 24 | int ways = process(str, index + 1); 25 | // 2) (index index + 1) -> index + 2 .... 26 | if (index + 1 == str.length) { 27 | return ways; 28 | } 29 | // (index index + 1) "23" -> 23 "17" -> 17 30 | int num = (str[index] - '0') * 10 + str[index + 1] - '0'; 31 | // num > 26 32 | if (num <= 26) { 33 | ways += process(str, index + 2); 34 | } 35 | return ways; 36 | } 37 | 38 | public static int numDecodings2(String s) { 39 | if (s == null || s.length() == 0) { 40 | return 0; 41 | } 42 | char[] str = s.toCharArray(); 43 | int N = str.length; 44 | // dp[i] -> process(str, index)返回值 index 0 ~ N 45 | int[] dp = new int[N + 1]; 46 | dp[N] = 1; 47 | 48 | // dp依次填好 dp[i] dp[i+1] dp[i+2] 49 | for (int i = N - 1; i >= 0; i--) { 50 | if (str[i] != '0') { 51 | dp[i] = dp[i + 1]; 52 | if (i + 1 == str.length) { 53 | continue; 54 | } 55 | int num = (str[i] - '0') * 10 + str[i + 1] - '0'; 56 | if (num <= 26) { 57 | dp[i] += dp[i + 2]; 58 | } 59 | } 60 | } 61 | return dp[0]; 62 | } 63 | 64 | public static int numDecodings(String s) { 65 | if (s == null || s.length() == 0) { 66 | return 0; 67 | } 68 | char[] str = s.toCharArray(); 69 | int N = str.length; 70 | int[] dp = new int[N + 1]; 71 | dp[N] = 1; 72 | for (int i = N - 1; i >= 0; i--) { 73 | if (str[i] == '0') { 74 | dp[i] = 0; 75 | } else if (str[i] == '1') { 76 | dp[i] = dp[i + 1]; 77 | if (i + 1 < N) { 78 | dp[i] += dp[i + 2]; 79 | } 80 | } else if (str[i] == '2') { 81 | dp[i] = dp[i + 1]; 82 | if (i + 1 < str.length && (str[i + 1] >= '0' && str[i + 1] <= '6')) { 83 | dp[i] += dp[i + 2]; 84 | } 85 | } else { 86 | dp[i] = dp[i + 1]; 87 | } 88 | } 89 | return dp[0]; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0218_TheSkylineProblem.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Comparator; 6 | import java.util.List; 7 | import java.util.TreeMap; 8 | import java.util.Map.Entry; 9 | 10 | public class Problem_0218_TheSkylineProblem { 11 | 12 | public static class Node { 13 | public int x; 14 | public boolean isAdd; 15 | public int h; 16 | 17 | public Node(int x, boolean isAdd, int h) { 18 | this.x = x; 19 | this.isAdd = isAdd; 20 | this.h = h; 21 | } 22 | } 23 | 24 | public static class NodeComparator implements Comparator { 25 | @Override 26 | public int compare(Node o1, Node o2) { 27 | if (o1.x != o2.x) { 28 | return o1.x - o2.x; 29 | } 30 | if (o1.isAdd != o2.isAdd) { 31 | return o1.isAdd ? -1 : 1; 32 | } 33 | return 0; 34 | } 35 | } 36 | 37 | public static List> getSkyline(int[][] matrix) { 38 | Node[] nodes = new Node[matrix.length * 2]; 39 | for (int i = 0; i < matrix.length; i++) { 40 | nodes[i * 2] = new Node(matrix[i][0], true, matrix[i][2]); 41 | nodes[i * 2 + 1] = new Node(matrix[i][1], false, matrix[i][2]); 42 | } 43 | Arrays.sort(nodes, new NodeComparator()); 44 | // 有序表,key 代表某个高度 value 这个高度出现的次数 45 | TreeMap mapHeightTimes = new TreeMap<>(); 46 | // 有序表 key x的值 value 处在x位置时的高度 47 | TreeMap xMaxHeight = new TreeMap<>(); 48 | for (int i = 0; i < nodes.length; i++) { 49 | if (nodes[i].isAdd) { 50 | if (!mapHeightTimes.containsKey(nodes[i].h)) { 51 | mapHeightTimes.put(nodes[i].h, 1); 52 | } else { 53 | mapHeightTimes.put(nodes[i].h, mapHeightTimes.get(nodes[i].h) + 1); 54 | } 55 | } else { 56 | if (mapHeightTimes.get(nodes[i].h) == 1) { 57 | mapHeightTimes.remove(nodes[i].h); 58 | } else { 59 | mapHeightTimes.put(nodes[i].h, mapHeightTimes.get(nodes[i].h) - 1); 60 | } 61 | } 62 | if (mapHeightTimes.isEmpty()) { 63 | xMaxHeight.put(nodes[i].x, 0); 64 | } else { 65 | xMaxHeight.put(nodes[i].x, mapHeightTimes.lastKey()); 66 | } 67 | } 68 | List> ans = new ArrayList<>(); 69 | for (Entry entry : xMaxHeight.entrySet()) { 70 | int curX = entry.getKey(); 71 | int curMaxHeight = entry.getValue(); 72 | if (ans.isEmpty() || ans.get(ans.size() - 1).get(1) != curMaxHeight) { 73 | ans.add(new ArrayList<>(Arrays.asList(curX, curMaxHeight))); 74 | } 75 | } 76 | return ans; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0297_SerializeAndDeserializeBinaryTree.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | 6 | public class Problem_0297_SerializeAndDeserializeBinaryTree { 7 | 8 | // 提交代码时不要提交TreeNode类 9 | public static class TreeNode { 10 | public int val; 11 | public TreeNode left; 12 | public TreeNode right; 13 | 14 | public TreeNode(int value) { 15 | val = value; 16 | } 17 | } 18 | 19 | public String serialize(TreeNode root) { 20 | LinkedList ans = new LinkedList<>(); 21 | if (root == null) { 22 | ans.add(null); 23 | } else { 24 | ans.add(String.valueOf(root.val)); 25 | Queue queue = new LinkedList(); 26 | queue.add(root); 27 | while (!queue.isEmpty()) { 28 | root = queue.poll(); 29 | if (root.left != null) { 30 | ans.add(String.valueOf(root.left.val)); 31 | queue.add(root.left); 32 | } else { 33 | ans.add(null); 34 | } 35 | if (root.right != null) { 36 | ans.add(String.valueOf(root.right.val)); 37 | queue.add(root.right); 38 | } else { 39 | ans.add(null); 40 | } 41 | } 42 | } 43 | while (!ans.isEmpty() && ans.peekLast() == null) { 44 | ans.pollLast(); 45 | } 46 | StringBuilder builder = new StringBuilder(); 47 | builder.append("["); 48 | String str = ans.pollFirst(); 49 | builder.append(str == null ? "null" : str); 50 | while (!ans.isEmpty()) { 51 | str = ans.pollFirst(); 52 | builder.append("," + (str == null ? "null" : str)); 53 | } 54 | builder.append("]"); 55 | return builder.toString(); 56 | } 57 | 58 | public TreeNode deserialize(String data) { 59 | String[] strs = data.substring(1, data.length() - 1).split(","); 60 | int index = 0; 61 | TreeNode root = generateNode(strs[index++]); 62 | Queue queue = new LinkedList(); 63 | if (root != null) { 64 | queue.add(root); 65 | } 66 | while (!queue.isEmpty()) { 67 | TreeNode node = queue.poll(); 68 | node.left = generateNode(index == strs.length ? "null" : strs[index++]); 69 | node.right = generateNode(index == strs.length ? "null" : strs[index++]); 70 | if (node.left != null) { 71 | queue.add(node.left); 72 | } 73 | if (node.right != null) { 74 | queue.add(node.right); 75 | } 76 | } 77 | return root; 78 | } 79 | 80 | private TreeNode generateNode(String val) { 81 | if (val.equals("null")) { 82 | return null; 83 | } 84 | return new TreeNode(Integer.valueOf(val)); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0140_WordBreakII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Problem_0140_WordBreakII { 7 | 8 | public static class Node { 9 | public String path; 10 | public boolean end; 11 | public Node[] nexts; 12 | 13 | public Node() { 14 | path = null; 15 | end = false; 16 | nexts = new Node[26]; 17 | } 18 | } 19 | 20 | public static List wordBreak(String s, List wordDict) { 21 | char[] str = s.toCharArray(); 22 | Node root = gettrie(wordDict); 23 | boolean[] dp = getdp(s, root); 24 | ArrayList path = new ArrayList<>(); 25 | List ans = new ArrayList<>(); 26 | process(str, 0, root, dp, path, ans); 27 | return ans; 28 | } 29 | 30 | public static void process(char[] str, int index, Node root, boolean[] dp, ArrayList path, 31 | List ans) { 32 | if (index == str.length) { 33 | StringBuilder builder = new StringBuilder(); 34 | for (int i = 0; i < path.size() - 1; i++) { 35 | builder.append(path.get(i) + " "); 36 | } 37 | builder.append(path.get(path.size() - 1)); 38 | ans.add(builder.toString()); 39 | } else { 40 | Node cur = root; 41 | for (int end = index; end < str.length; end++) { 42 | int road = str[end] - 'a'; 43 | if (cur.nexts[road] == null) { 44 | break; 45 | } 46 | cur = cur.nexts[road]; 47 | if (cur.end && dp[end + 1]) { 48 | path.add(cur.path); 49 | process(str, end + 1, root, dp, path, ans); 50 | path.remove(path.size() - 1); 51 | } 52 | } 53 | } 54 | } 55 | 56 | public static Node gettrie(List wordDict) { 57 | Node root = new Node(); 58 | for (String str : wordDict) { 59 | char[] chs = str.toCharArray(); 60 | Node node = root; 61 | int index = 0; 62 | for (int i = 0; i < chs.length; i++) { 63 | index = chs[i] - 'a'; 64 | if (node.nexts[index] == null) { 65 | node.nexts[index] = new Node(); 66 | } 67 | node = node.nexts[index]; 68 | } 69 | node.path = str; 70 | node.end = true; 71 | } 72 | return root; 73 | } 74 | 75 | public static boolean[] getdp(String s, Node root) { 76 | char[] str = s.toCharArray(); 77 | int N = str.length; 78 | boolean[] dp = new boolean[N + 1]; 79 | dp[N] = true; 80 | for (int i = N - 1; i >= 0; i--) { 81 | Node cur = root; 82 | for (int end = i; end < N; end++) { 83 | int path = str[end] - 'a'; 84 | if (cur.nexts[path] == null) { 85 | break; 86 | } 87 | cur = cur.nexts[path]; 88 | if (cur.end && dp[end + 1]) { 89 | dp[i] = true; 90 | break; 91 | } 92 | } 93 | } 94 | return dp; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0004_MedianOfTwoSortedArrays.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0004_MedianOfTwoSortedArrays { 4 | 5 | public static double findMedianSortedArrays(int[] nums1, int[] nums2) { 6 | int size = nums1.length + nums2.length; 7 | boolean even = (size & 1) == 0; 8 | if (nums1.length != 0 && nums2.length != 0) { 9 | if (even) { 10 | return (double) (findKthNum(nums1, nums2, size / 2) + findKthNum(nums1, nums2, size / 2 + 1)) / 2D; 11 | } else { 12 | return findKthNum(nums1, nums2, size / 2 + 1); 13 | } 14 | } else if (nums1.length != 0) { 15 | if (even) { 16 | return (double) (nums1[(size - 1) / 2] + nums1[size / 2]) / 2; 17 | } else { 18 | return nums1[size / 2]; 19 | } 20 | } else if (nums2.length != 0) { 21 | if (even) { 22 | return (double) (nums2[(size - 1) / 2] + nums2[size / 2]) / 2; 23 | } else { 24 | return nums2[size / 2]; 25 | } 26 | } else { 27 | return 0; 28 | } 29 | } 30 | 31 | public static int findKthNum(int[] arr1, int[] arr2, int kth) { 32 | int[] longs = arr1.length >= arr2.length ? arr1 : arr2; 33 | int[] shorts = arr1.length < arr2.length ? arr1 : arr2; 34 | int l = longs.length; 35 | int s = shorts.length; 36 | if (kth <= s) { 37 | return getUpMedian(shorts, 0, kth - 1, longs, 0, kth - 1); 38 | } 39 | if (kth > l) { 40 | if (shorts[kth - l - 1] >= longs[l - 1]) { 41 | return shorts[kth - l - 1]; 42 | } 43 | if (longs[kth - s - 1] >= shorts[s - 1]) { 44 | return longs[kth - s - 1]; 45 | } 46 | return getUpMedian(shorts, kth - l, s - 1, longs, kth - s, l - 1); 47 | } 48 | // 第2段 49 | if (longs[kth - s - 1] >= shorts[s - 1]) { 50 | return longs[kth - s - 1]; 51 | } 52 | return getUpMedian(shorts, 0, s - 1, longs, kth - s, kth - 1); 53 | } 54 | 55 | public static int getUpMedian(int[] A, int s1, int e1, int[] B, int s2, int e2) { 56 | int mid1 = 0; 57 | int mid2 = 0; 58 | while (s1 < e1) { 59 | mid1 = (s1 + e1) / 2; 60 | mid2 = (s2 + e2) / 2; 61 | if (A[mid1] == B[mid2]) { 62 | return A[mid1]; 63 | } 64 | if (((e1 - s1 + 1) & 1) == 1) { // 奇数长度 65 | if (A[mid1] > B[mid2]) { 66 | if (B[mid2] >= A[mid1 - 1]) { 67 | return B[mid2]; 68 | } 69 | e1 = mid1 - 1; 70 | s2 = mid2 + 1; 71 | } else { // A[mid1] < B[mid2] 72 | if (A[mid1] >= B[mid2 - 1]) { 73 | return A[mid1]; 74 | } 75 | e2 = mid2 - 1; 76 | s1 = mid1 + 1; 77 | } 78 | } else { // 偶数长度 79 | if (A[mid1] > B[mid2]) { 80 | e1 = mid1; 81 | s2 = mid2 + 1; 82 | } else { 83 | e2 = mid2; 84 | s1 = mid1 + 1; 85 | } 86 | } 87 | } 88 | return Math.min(A[s1], B[s2]); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0329_LongestIncreasingPathInAMatrix.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0329_LongestIncreasingPathInAMatrix { 4 | 5 | public static int longest(int[][] matrix) { 6 | int longest = 0; 7 | int[][] dp = new int[matrix.length][matrix[0].length]; 8 | // dp[i][j] == 0 process(i,j) 9 | for (int i = 0; i < matrix.length; i++) { 10 | for (int j = 0; j < matrix[0].length; j++) { 11 | longest = Math.max(longest, process(matrix, i, j, dp)); 12 | } 13 | } 14 | return longest; 15 | } 16 | 17 | // 从matrix[i][j]出发,可以走上下左右四个方向,走出的最长递增链是多长,返回 18 | public static int process(int[][] matrix, int i, int j, int[][] dp) { 19 | if (dp[i][j] != 0) { 20 | return dp[i][j]; 21 | } 22 | // 不越界 23 | int next = 0; // 往左右上下四个方向,能走出最长的后续是多少? 24 | // i, j i-1,j 25 | if (i > 0 && matrix[i - 1][j] > matrix[i][j]) { 26 | next = process(matrix, i - 1, j, dp); 27 | } 28 | // i + 1 29 | if (i + 1 < matrix.length && matrix[i + 1][j] > matrix[i][j]) { 30 | next = Math.max(next, process(matrix, i + 1, j, dp)); 31 | } 32 | if (j > 0 && matrix[i][j - 1] > matrix[i][j]) { 33 | next = Math.max(next, process(matrix, i, j - 1, dp)); 34 | } 35 | if (j + 1 < matrix[0].length && matrix[i][j + 1] > matrix[i][j]) { 36 | next = Math.max(next, process(matrix, i, j + 1, dp)); 37 | } 38 | dp[i][j] = 1 + next; 39 | return 1 + next; 40 | } 41 | 42 | public static int longestIncreasingPath(int[][] matrix) { 43 | if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) { 44 | return 0; 45 | } 46 | int ans = 0; 47 | int N = matrix.length; 48 | int M = matrix[0].length; 49 | int[][] dp = new int[N][M]; 50 | for (int i = 0; i < N; i++) { 51 | for (int j = 0; j < M; j++) { 52 | ans = Math.max(ans, lip(matrix, i, j, dp)); 53 | } 54 | } 55 | return ans; 56 | } 57 | 58 | public static int lip(int[][] matrix, int i, int j, int[][] dp) { 59 | if (dp[i][j] != 0) { 60 | return dp[i][j]; 61 | } 62 | int next = 0; 63 | if (canWalk(matrix, i, j, i - 1, j)) { 64 | next = Math.max(next, lip(matrix, i - 1, j, dp)); 65 | } 66 | if (canWalk(matrix, i, j, i + 1, j)) { 67 | next = Math.max(next, lip(matrix, i + 1, j, dp)); 68 | } 69 | if (canWalk(matrix, i, j, i, j - 1)) { 70 | next = Math.max(next, lip(matrix, i, j - 1, dp)); 71 | } 72 | if (canWalk(matrix, i, j, i, j + 1)) { 73 | next = Math.max(next, lip(matrix, i, j + 1, dp)); 74 | } 75 | dp[i][j] = 1 + next; 76 | return dp[i][j]; 77 | } 78 | 79 | public static boolean canWalk(int[][] matrix, int i1, int j1, int i2, int j2) { 80 | return i2 >= 0 && i2 < matrix.length && j2 >= 0 && j2 < matrix[0].length && matrix[i1][j1] < matrix[i2][j2]; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0044_WildcardMatching.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0044_WildcardMatching { 4 | 5 | public static boolean isMatch1(String str, String pattern) { 6 | char[] s = str.toCharArray(); 7 | char[] p = pattern.toCharArray(); 8 | return process1(s, p, 0, 0); 9 | } 10 | 11 | // s[si....] 能否被 p[pi....] 匹配出来 12 | public static boolean process1(char[] s, char[] p, int si, int pi) { 13 | if (si == s.length) { // s -> "" 14 | if (pi == p.length) { // p -> "" 15 | return true; 16 | } else { 17 | // p -> "..." 18 | // p[pi] == '*' && p[pi+1...] -> " 19 | return p[pi] == '*' && process1(s, p, si, pi + 1); 20 | } 21 | } 22 | if (pi == p.length) { // p -> "" s 23 | return si == s.length; 24 | } 25 | // s从si出发.... p从pi出发... 26 | // s[si] -> 小写字母 27 | // p[pi] -> 小写、?、* 28 | if (p[pi] != '?' && p[pi] != '*') { 29 | return s[si] == p[pi] && process1(s, p, si + 1, pi + 1); 30 | } 31 | // si.. pi.. pi ? * 32 | if (p[pi] == '?') { 33 | return process1(s, p, si + 1, pi + 1); 34 | } 35 | for (int len = 0; len <= s.length - si; len++) { 36 | if (process1(s, p, si + len, pi + 1)) { 37 | return true; 38 | } 39 | } 40 | return false; 41 | } 42 | 43 | public static boolean isMatch2(String str, String pattern) { 44 | char[] s = str.toCharArray(); 45 | char[] p = pattern.toCharArray(); 46 | int N = s.length; 47 | int M = p.length; 48 | boolean[][] dp = new boolean[N + 1][M + 1]; 49 | dp[N][M] = true; 50 | for (int pi = M - 1; pi >= 0; pi--) { 51 | dp[N][pi] = p[pi] == '*' && dp[N][pi + 1]; 52 | } 53 | for (int si = N - 1; si >= 0; si--) { 54 | for (int pi = M - 1; pi >= 0; pi--) { 55 | if (p[pi] != '?' && p[pi] != '*') { 56 | dp[si][pi] = s[si] == p[pi] && dp[si + 1][pi + 1]; 57 | continue; 58 | } 59 | if (p[pi] == '?') { 60 | dp[si][pi] = dp[si + 1][pi + 1]; 61 | continue; 62 | } 63 | // p[pi] == '*' 64 | dp[si][pi] = dp[si][pi + 1] || dp[si + 1][pi]; 65 | } 66 | } 67 | return dp[0][0]; 68 | } 69 | 70 | // 最终做的化简 71 | public static boolean isMatch3(String str, String pattern) { 72 | char[] s = str.toCharArray(); 73 | char[] p = pattern.toCharArray(); 74 | int N = s.length; 75 | int M = p.length; 76 | boolean[][] dp = new boolean[N + 1][M + 1]; 77 | dp[N][M] = true; 78 | for (int pi = M - 1; pi >= 0; pi--) { 79 | dp[N][pi] = p[pi] == '*' && dp[N][pi + 1]; 80 | } 81 | for (int si = N - 1; si >= 0; si--) { 82 | for (int pi = M - 1; pi >= 0; pi--) { 83 | if (p[pi] != '*') { 84 | dp[si][pi] = (p[pi] == '?' || s[si] == p[pi]) && dp[si + 1][pi + 1]; 85 | } else { 86 | dp[si][pi] = dp[si][pi + 1] || dp[si + 1][pi]; 87 | } 88 | } 89 | } 90 | return dp[0][0]; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0378_KthSmallestElementInSortedMatrix.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.Comparator; 4 | import java.util.PriorityQueue; 5 | 6 | public class Problem_0378_KthSmallestElementInSortedMatrix { 7 | 8 | public static class Node { 9 | public int value; 10 | public int row; 11 | public int col; 12 | 13 | public Node(int v, int r, int c) { 14 | value = v; 15 | row = r; 16 | col = c; 17 | } 18 | 19 | } 20 | 21 | public static class NodeComparator implements Comparator { 22 | 23 | @Override 24 | public int compare(Node o1, Node o2) { 25 | return o1.value - o2.value; 26 | } 27 | 28 | } 29 | 30 | public static int kthSmallest1(int[][] matrix, int k) { 31 | int N = matrix.length; 32 | int M = matrix[0].length; 33 | PriorityQueue heap = new PriorityQueue<>(new NodeComparator()); 34 | boolean[][] set = new boolean[N][M]; 35 | heap.add(new Node(matrix[0][0], 0, 0)); 36 | set[0][0] = true; 37 | int count = 0; 38 | Node ans = null; 39 | while (!heap.isEmpty()) { 40 | ans = heap.poll(); 41 | if (++count == k) { 42 | break; 43 | } 44 | int row = ans.row; 45 | int col = ans.col; 46 | if (row + 1 < N && !set[row + 1][col]) { 47 | heap.add(new Node(matrix[row + 1][col], row + 1, col)); 48 | set[row + 1][col] = true; 49 | } 50 | if (col + 1 < M && !set[row][col + 1]) { 51 | heap.add(new Node(matrix[row][col + 1], row, col + 1)); 52 | set[row][col + 1] = true; 53 | } 54 | } 55 | return ans.value; 56 | } 57 | 58 | public static int kthSmallest2(int[][] matrix, int k) { 59 | int N = matrix.length; 60 | int M = matrix[0].length; 61 | int left = matrix[0][0]; 62 | int right = matrix[N - 1][M - 1]; 63 | int ans = 0; 64 | while (left <= right) { 65 | int mid = left + ((right - left) >> 1); 66 | Info info = noMoreNum(matrix, mid); 67 | if (info.num < k) { 68 | left = mid + 1; 69 | } else { 70 | ans = info.near; 71 | right = mid - 1; 72 | } 73 | } 74 | return ans; 75 | } 76 | 77 | public static class Info { 78 | public int near; 79 | public int num; 80 | 81 | public Info(int n1, int n2) { 82 | near = n1; 83 | num = n2; 84 | } 85 | } 86 | 87 | public static Info noMoreNum(int[][] matrix, int value) { 88 | int near = Integer.MIN_VALUE; 89 | int num = 0; 90 | int N = matrix.length; 91 | int M = matrix[0].length; 92 | int row = 0; 93 | int col = M - 1; 94 | while (row < N && col >= 0) { 95 | if (matrix[row][col] <= value) { 96 | near = Math.max(near, matrix[row][col]); 97 | num += col + 1; 98 | row++; 99 | } else { 100 | col--; 101 | } 102 | } 103 | return new Info(near, num); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0148_SortList.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0148_SortList { 4 | 5 | public static class ListNode { 6 | int val; 7 | ListNode next; 8 | 9 | public ListNode(int v) { 10 | val = v; 11 | } 12 | } 13 | 14 | public static ListNode sortList(ListNode head) { 15 | int N = 0; 16 | ListNode cur = head; 17 | while (cur != null) { 18 | N++; 19 | cur = cur.next; 20 | } 21 | ListNode h = head; 22 | ListNode teamFirst = head; 23 | ListNode pre = null; 24 | for (int len = 1; len < N; len <<= 1) { 25 | while (teamFirst != null) { 26 | ListNode[] hthtn = hthtn(teamFirst, len); 27 | ListNode[] mhmt = merge(hthtn[0], hthtn[1], hthtn[2], hthtn[3]); 28 | if (h == teamFirst) { 29 | h = mhmt[0]; 30 | pre = mhmt[1]; 31 | } else { 32 | pre.next = mhmt[0]; 33 | pre = mhmt[1]; 34 | } 35 | teamFirst = hthtn[4]; 36 | } 37 | teamFirst = h; 38 | pre = null; 39 | } 40 | return h; 41 | } 42 | 43 | public static ListNode[] hthtn(ListNode teamFirst, int len) { 44 | ListNode ls = teamFirst; 45 | ListNode le = teamFirst; 46 | ListNode rs = null; 47 | ListNode re = null; 48 | ListNode next = null; 49 | int pass = 0; 50 | while (teamFirst != null) { 51 | pass++; 52 | if (pass <= len) { 53 | le = teamFirst; 54 | } 55 | if (pass == len + 1) { 56 | rs = teamFirst; 57 | } 58 | if (pass > len) { 59 | re = teamFirst; 60 | } 61 | if (pass == (len << 1)) { 62 | break; 63 | } 64 | teamFirst = teamFirst.next; 65 | } 66 | le.next = null; 67 | if (re != null) { 68 | next = re.next; 69 | re.next = null; 70 | } 71 | return new ListNode[] { ls, le, rs, re, next }; 72 | } 73 | 74 | public static ListNode[] merge(ListNode ls, ListNode le, ListNode rs, ListNode re) { 75 | if (rs == null) { 76 | return new ListNode[] { ls, le }; 77 | } 78 | ListNode head = null; 79 | ListNode pre = null; 80 | ListNode cur = null; 81 | ListNode tail = null; 82 | while (ls != le.next && rs != re.next) { 83 | if (ls.val <= rs.val) { 84 | cur = ls; 85 | ls = ls.next; 86 | } else { 87 | cur = rs; 88 | rs = rs.next; 89 | } 90 | if (pre == null) { 91 | head = cur; 92 | pre = cur; 93 | } else { 94 | pre.next = cur; 95 | pre = cur; 96 | } 97 | } 98 | if (ls != le.next) { 99 | while (ls != le.next) { 100 | pre.next = ls; 101 | pre = ls; 102 | tail = ls; 103 | ls = ls.next; 104 | } 105 | } else { 106 | while (rs != re.next) { 107 | pre.next = rs; 108 | pre = rs; 109 | tail = rs; 110 | rs = rs.next; 111 | } 112 | } 113 | return new ListNode[] { head, tail }; 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0130_SurroundedRegions.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0130_SurroundedRegions { 4 | 5 | public static void solve1(char[][] board) { 6 | boolean[] ans = new boolean[1]; 7 | for (int i = 0; i < board.length; i++) { 8 | for (int j = 0; j < board[0].length; j++) { 9 | if (board[i][j] == 'O') { 10 | ans[0] = true; 11 | can(board, i, j, ans); 12 | board[i][j] = ans[0] ? 'T' : 'F'; 13 | } 14 | } 15 | } 16 | for (int i = 0; i < board.length; i++) { 17 | for (int j = 0; j < board[0].length; j++) { 18 | char can = board[i][j]; 19 | if (can == 'T' || can == 'F') { 20 | board[i][j] = '.'; 21 | change(board, i, j, can); 22 | } 23 | } 24 | } 25 | 26 | } 27 | 28 | public static void can(char[][] board, int i, int j, boolean[] ans) { 29 | if (i < 0 || i == board.length || j < 0 || j == board[0].length) { 30 | ans[0] = false; 31 | return; 32 | } 33 | if (board[i][j] == 'O') { 34 | board[i][j] = '.'; 35 | can(board, i - 1, j, ans); 36 | can(board, i + 1, j, ans); 37 | can(board, i, j - 1, ans); 38 | can(board, i, j + 1, ans); 39 | } 40 | } 41 | 42 | public static void change(char[][] board, int i, int j, char can) { 43 | if (i < 0 || i == board.length || j < 0 || j == board[0].length) { 44 | return; 45 | } 46 | if (board[i][j] == '.') { 47 | board[i][j] = can == 'T' ? 'X' : 'O'; 48 | change(board, i - 1, j, can); 49 | change(board, i + 1, j, can); 50 | change(board, i, j - 1, can); 51 | change(board, i, j + 1, can); 52 | } 53 | } 54 | 55 | // 从边界开始感染的方法,比第一种方法更好 56 | public static void solve2(char[][] board) { 57 | if (board == null || board.length == 0 || board[0] == null || board[0].length == 0) { 58 | return; 59 | } 60 | int N = board.length; 61 | int M = board[0].length; 62 | for (int j = 0; j < M; j++) { 63 | if (board[0][j] == 'O') { 64 | free(board, 0, j); 65 | } 66 | if (board[N - 1][j] == 'O') { 67 | free(board, N - 1, j); 68 | } 69 | } 70 | for (int i = 1; i < N - 1; i++) { 71 | if (board[i][0] == 'O') { 72 | free(board, i, 0); 73 | } 74 | if (board[i][M - 1] == 'O') { 75 | free(board, i, M - 1); 76 | } 77 | } 78 | for (int i = 0; i < N; i++) { 79 | for (int j = 0; j < M; j++) { 80 | if (board[i][j] == 'O') { 81 | board[i][j] = 'X'; 82 | } 83 | if (board[i][j] == 'F') { 84 | board[i][j] = 'O'; 85 | } 86 | } 87 | } 88 | } 89 | 90 | public static void free(char[][] board, int i, int j) { 91 | if (i < 0 || i == board.length || j < 0 || j == board[0].length || board[i][j] != 'O') { 92 | return; 93 | } 94 | board[i][j] = 'F'; 95 | free(board, i + 1, j); 96 | free(board, i - 1, j); 97 | free(board, i, j + 1); 98 | free(board, i, j - 1); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0324_WiggleSortII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0324_WiggleSortII { 4 | 5 | // 时间复杂度O(N),额外空间复杂度O(1) 6 | public void wiggleSort(int[] nums) { 7 | if (nums == null || nums.length < 2) { 8 | return; 9 | } 10 | int N = nums.length; 11 | findIndexNum(nums, 0, nums.length - 1, N / 2); 12 | if ((N & 1) == 0) { 13 | shuffle(nums, 0, nums.length - 1); 14 | reverse(nums, 0, nums.length - 1); 15 | } else { 16 | shuffle(nums, 1, nums.length - 1); 17 | } 18 | } 19 | 20 | public static int findIndexNum(int[] arr, int L, int R, int index) { 21 | int pivot = 0; 22 | int[] range = null; 23 | while (L < R) { 24 | pivot = arr[L + (int) (Math.random() * (R - L + 1))]; 25 | range = partition(arr, L, R, pivot); 26 | if (index >= range[0] && index <= range[1]) { 27 | return arr[index]; 28 | } else if (index < range[0]) { 29 | R = range[0] - 1; 30 | } else { 31 | L = range[1] + 1; 32 | } 33 | } 34 | return arr[L]; 35 | } 36 | 37 | public static int[] partition(int[] arr, int L, int R, int pivot) { 38 | int less = L - 1; 39 | int more = R + 1; 40 | int cur = L; 41 | while (cur < more) { 42 | if (arr[cur] < pivot) { 43 | swap(arr, ++less, cur++); 44 | } else if (arr[cur] > pivot) { 45 | swap(arr, cur, --more); 46 | } else { 47 | cur++; 48 | } 49 | } 50 | return new int[] { less + 1, more - 1 }; 51 | } 52 | 53 | public static void shuffle(int[] nums, int l, int r) { 54 | while (r - l + 1 > 0) { 55 | int lenAndOne = r - l + 2; 56 | int bloom = 3; 57 | int k = 1; 58 | while (bloom <= lenAndOne / 3) { 59 | bloom *= 3; 60 | k++; 61 | } 62 | int m = (bloom - 1) / 2; 63 | int mid = (l + r) / 2; 64 | rotate(nums, l + m, mid, mid + m); 65 | cycles(nums, l - 1, bloom, k); 66 | l = l + bloom - 1; 67 | } 68 | } 69 | 70 | public static void cycles(int[] nums, int base, int bloom, int k) { 71 | for (int i = 0, trigger = 1; i < k; i++, trigger *= 3) { 72 | int next = (2 * trigger) % bloom; 73 | int cur = next; 74 | int record = nums[next + base]; 75 | int tmp = 0; 76 | nums[next + base] = nums[trigger + base]; 77 | while (cur != trigger) { 78 | next = (2 * cur) % bloom; 79 | tmp = nums[next + base]; 80 | nums[next + base] = record; 81 | cur = next; 82 | record = tmp; 83 | } 84 | } 85 | } 86 | 87 | public static void rotate(int[] arr, int l, int m, int r) { 88 | reverse(arr, l, m); 89 | reverse(arr, m + 1, r); 90 | reverse(arr, l, r); 91 | } 92 | 93 | public static void reverse(int[] arr, int l, int r) { 94 | while (l < r) { 95 | swap(arr, l++, r--); 96 | } 97 | } 98 | 99 | public static void swap(int[] nums, int i, int j) { 100 | int tmp = nums[i]; 101 | nums[i] = nums[j]; 102 | nums[j] = tmp; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0395_LongestSubstringWithAtLeastKRepeatingCharacters.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | public class Problem_0395_LongestSubstringWithAtLeastKRepeatingCharacters { 4 | 5 | public static int longestSubstring1(String s, int k) { 6 | char[] str = s.toCharArray(); 7 | int N = str.length; 8 | int max = 0; 9 | for (int i = 0; i < N; i++) { 10 | int[] count = new int[256]; 11 | int collect = 0; 12 | int satisfy = 0; 13 | for (int j = i; j < N; j++) { 14 | if (count[str[j]] == 0) { 15 | collect++; 16 | } 17 | if (count[str[j]] == k - 1) { 18 | satisfy++; 19 | } 20 | count[str[j]]++; 21 | if (collect == satisfy) { 22 | max = Math.max(max, j - i + 1); 23 | } 24 | } 25 | } 26 | return max; 27 | } 28 | 29 | public static int longestSubstring2(String s, int k) { 30 | char[] str = s.toCharArray(); 31 | int N = str.length; 32 | int max = 0; 33 | for (int require = 1; require <= 26; require++) { 34 | // a~z a~z 出现次数 35 | // count[0 1 2] a b c 36 | int[] count = new int[26]; 37 | // 目前窗口内收集了几种字符了 38 | int collect = 0; 39 | // 目前窗口内出现次数>=k次的字符,满足了几种 40 | int satisfy = 0; 41 | // 窗口右边界 42 | int R = -1; 43 | for (int L = 0; L < N; L++) { // L要尝试每一个窗口的最左位置 44 | // [L..R] R+1 45 | while (R + 1 < N && !(collect == require && count[str[R + 1] - 'a'] == 0)) { 46 | R++; 47 | if (count[str[R] - 'a'] == 0) { 48 | collect++; 49 | } 50 | if (count[str[R] - 'a'] == k - 1) { 51 | satisfy++; 52 | } 53 | count[str[R] - 'a']++; 54 | } 55 | // [L...R] 56 | if (satisfy == require) { 57 | max = Math.max(max, R - L + 1); 58 | } 59 | // L++ 60 | if (count[str[L] - 'a'] == 1) { 61 | collect--; 62 | } 63 | if (count[str[L] - 'a'] == k) { 64 | satisfy--; 65 | } 66 | count[str[L] - 'a']--; 67 | } 68 | } 69 | return max; 70 | } 71 | 72 | // 会超时,但是思路的确是正确的 73 | public static int longestSubstring3(String s, int k) { 74 | return process(s.toCharArray(), 0, s.length() - 1, k); 75 | } 76 | 77 | public static int process(char[] str, int L, int R, int k) { 78 | if (L > R) { 79 | return 0; 80 | } 81 | int[] counts = new int[26]; 82 | for (int i = L; i <= R; i++) { 83 | counts[str[i] - 'a']++; 84 | } 85 | char few = 0; 86 | int min = Integer.MAX_VALUE; 87 | for (int i = 0; i < 26; i++) { 88 | if (counts[i] != 0 && min > counts[i]) { 89 | few = (char) (i + 'a'); 90 | min = counts[i]; 91 | } 92 | } 93 | if (min >= k) { 94 | return R - L + 1; 95 | } 96 | int pre = 0; 97 | int max = Integer.MIN_VALUE; 98 | for (int i = L; i <= R; i++) { 99 | if (str[i] == few) { 100 | max = Math.max(max, process(str, pre, i - 1, k)); 101 | pre = i + 1; 102 | } 103 | } 104 | if (pre != R + 1) { 105 | max = Math.max(max, process(str, pre, R, k)); 106 | } 107 | return max; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0341_FlattenNestedListIterator.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | import java.util.Stack; 6 | 7 | public class Problem_0341_FlattenNestedListIterator { 8 | 9 | // 不要提交这个接头类 10 | public interface NestedInteger { 11 | 12 | // @return true if this NestedInteger holds a single integer, rather than a 13 | // nested list. 14 | public boolean isInteger(); 15 | 16 | // @return the single integer that this NestedInteger holds, if it holds a 17 | // single integer 18 | // Return null if this NestedInteger holds a nested list 19 | public Integer getInteger(); 20 | 21 | // @return the nested list that this NestedInteger holds, if it holds a nested 22 | // list 23 | // Return null if this NestedInteger holds a single integer 24 | public List getList(); 25 | } 26 | 27 | public class NestedIterator implements Iterator { 28 | 29 | private List list; 30 | private Stack stack; 31 | private boolean used; 32 | 33 | public NestedIterator(List nestedList) { 34 | list = nestedList; 35 | stack = new Stack<>(); 36 | stack.push(-1); 37 | used = true; 38 | hasNext(); 39 | } 40 | 41 | @Override 42 | public Integer next() { 43 | Integer ans = null; 44 | if (!used) { 45 | ans = get(list, stack); 46 | used = true; 47 | hasNext(); 48 | } 49 | return ans; 50 | } 51 | 52 | @Override 53 | public boolean hasNext() { 54 | if (stack.isEmpty()) { 55 | return false; 56 | } 57 | if (!used) { 58 | return true; 59 | } 60 | if (findNext(list, stack)) { 61 | used = false; 62 | } 63 | return !used; 64 | } 65 | 66 | private Integer get(List nestedList, Stack stack) { 67 | int index = stack.pop(); 68 | Integer ans = null; 69 | if (!stack.isEmpty()) { 70 | ans = get(nestedList.get(index).getList(), stack); 71 | } else { 72 | ans = nestedList.get(index).getInteger(); 73 | } 74 | stack.push(index); 75 | return ans; 76 | } 77 | 78 | private boolean findNext(List nestedList, Stack stack) { 79 | int index = stack.pop(); 80 | if (!stack.isEmpty() && findNext(nestedList.get(index).getList(), stack)) { 81 | stack.push(index); 82 | return true; 83 | } 84 | for (int i = index + 1; i < nestedList.size(); i++) { 85 | if (pickFirst(nestedList.get(i), i, stack)) { 86 | return true; 87 | } 88 | } 89 | return false; 90 | } 91 | 92 | private boolean pickFirst(NestedInteger nested, int position, Stack stack) { 93 | if (nested.isInteger()) { 94 | stack.add(position); 95 | return true; 96 | } else { 97 | List actualList = nested.getList(); 98 | for (int i = 0; i < actualList.size(); i++) { 99 | if (pickFirst(actualList.get(i), i, stack)) { 100 | stack.add(position); 101 | return true; 102 | } 103 | } 104 | } 105 | return false; 106 | } 107 | 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/followup/AddDevideNum2.java: -------------------------------------------------------------------------------- 1 | package followup; 2 | 3 | import java.util.HashMap; 4 | 5 | /* 6 | * 100 = 3 + 69258 / 714 7 | * 100 = 82 + 3546 / 197 8 | * 9 | * 等号右边的部分,可以写成 p1 + p2 / p3的形式 10 | * 要求p1和p2和p3,所使用的数字,必须把1~9使用完全,并且不重复 11 | * 满足的话,我们就说,形如p1 + p2 / p3,一个有效的"带分数"形式 12 | * 要求,p2 / p3 必须整除 13 | * 14 | * 输入N,返回N有多少种带分数形式 15 | * 100,有11种带分数形式 16 | * 17 | * 输入的N,N < 10的8次方 18 | * 19 | * 20 | * */ 21 | public class AddDevideNum2 { 22 | 23 | // 1-9 所有带分数,形成的结果,都算一遍,map里去 24 | // key 100 value 11 25 | public static HashMap map = new HashMap(); 26 | 27 | public final static int[] arr = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; 28 | 29 | public static int ways(int n) { 30 | if (map.size() == 0) { 31 | process(123456789, 8); 32 | } 33 | return map.containsKey(n) ? map.get(n) : 0; 34 | } 35 | 36 | // process, 当的数形成样子,num 123456789 37 | // index 该哪个位置的数字去指定了 38 | public static void process(int num, int index) { 39 | if (index == -1) { 40 | // num 固定了 8 ~ 0 41 | // num + / 8 ~ 0 42 | for (int addSplit = 8; addSplit >= 2; addSplit--) { 43 | // p1 44 | int p1 = num / arr[addSplit]; 45 | int rest = num % arr[addSplit]; 46 | for (int devSplit = (addSplit >> 1); devSplit >= 1; devSplit--) { 47 | int p2 = rest / arr[devSplit]; 48 | int p3 = rest % arr[devSplit]; 49 | if (p2 % p3 == 0) { 50 | int ans = p1 + p2 / p3; 51 | if (!map.containsKey(ans)) { 52 | map.put(ans, 1); 53 | } else { 54 | map.put(ans, map.get(ans) + 1); 55 | } 56 | } 57 | } 58 | } 59 | } else { 60 | // 需要去指定index位置的数 61 | for (int swap = index; swap >= 0; swap--) { 62 | int next = swap(num, index, swap); 63 | process(next, index - 1); 64 | } 65 | } 66 | } 67 | 68 | // 123456789 L == 8 R == 2 69 | 70 | // 723456189 71 | public static int swap(int num, int L, int R) { 72 | // num L位的数字是什么? 73 | int bitL = (num / arr[L]) % 10; 74 | int bitR = (num / arr[R]) % 10; 75 | return num - (bitL - bitR) * arr[L] + (bitL - bitR) * arr[R]; 76 | } 77 | 78 | public static void main(String[] args) { 79 | // 876543210 80 | // int test = 672381945; 81 | // int ans = swap(test, 8, 0); 82 | // System.out.println(ans); 83 | // process(123456789, 8); 84 | 85 | long start; 86 | long end; 87 | start = System.currentTimeMillis(); 88 | System.out.println(ways(100)); 89 | end = System.currentTimeMillis(); 90 | System.out.println(end - start); 91 | 92 | // int N = 100; 93 | // long start; 94 | // long end; 95 | // // 第一次跑要去生成map,需要100多毫秒, 96 | // // 但是只需要在第一次生成,以后都是直接查询的 97 | // start = System.currentTimeMillis(); 98 | // System.out.println(N + "用带分数表示的方法数 : " + ways(N)); 99 | // end = System.currentTimeMillis(); 100 | // System.out.println("运行了(毫秒) : " + (end - start)); 101 | // // 第二次跑map已经在上面生成好了,自然很快 102 | // N = 10000; 103 | // start = System.currentTimeMillis(); 104 | // System.out.println(N + "用带分数表示的方法数 : " + ways(N)); 105 | // end = System.currentTimeMillis(); 106 | // System.out.println("运行了(毫秒) : " + (end - start)); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0673_NumberOfLongestIncreasingSubsequence.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.TreeMap; 5 | 6 | public class Problem_0673_NumberOfLongestIncreasingSubsequence { 7 | 8 | public static int findNumberOfLIS(int[] nums) { 9 | if (nums == null || nums.length == 0) { 10 | return 0; 11 | } 12 | 13 | ArrayList> dp = new ArrayList<>(); 14 | 15 | for (int i = 0; i < nums.length; i++) { 16 | int L = 0; 17 | int R = dp.size() - 1; 18 | int find = -1; 19 | while (L <= R) { 20 | int mid = (L + R) / 2; 21 | if (dp.get(mid).firstKey() >= nums[i]) { 22 | find = mid; 23 | R = mid - 1; 24 | } else { 25 | L = mid + 1; 26 | } 27 | } 28 | int num = 1; 29 | int index = find == -1 ? dp.size() : find; 30 | if (index > 0) { 31 | TreeMap lastMap = dp.get(index - 1); 32 | num = lastMap.get(lastMap.firstKey()); 33 | if (lastMap.ceilingKey(nums[i]) != null) { 34 | num -= lastMap.get(lastMap.ceilingKey(nums[i])); 35 | } 36 | } 37 | if (index == dp.size()) { 38 | TreeMap newMap = new TreeMap(); 39 | newMap.put(nums[i], num); 40 | dp.add(newMap); 41 | } else { 42 | TreeMap curMap = dp.get(index); 43 | curMap.put(nums[i], curMap.get(curMap.firstKey()) + num); 44 | } 45 | } 46 | return dp.get(dp.size() - 1).firstEntry().getValue(); 47 | } 48 | 49 | public static int findNumberOfLIS2(int[] nums) { 50 | if (nums == null || nums.length == 0) { 51 | return 0; 52 | } 53 | ArrayList> dp = new ArrayList<>(); 54 | for (int i = 0; i < nums.length; i++) { 55 | int L = 0; 56 | int R = dp.size() - 1; 57 | int find = -1; 58 | while (L <= R) { 59 | int mid = (L + R) / 2; 60 | if (dp.get(mid).firstKey() >= nums[i]) { 61 | find = mid; 62 | R = mid - 1; 63 | } else { 64 | L = mid + 1; 65 | } 66 | } 67 | if (find == -1) { 68 | dp.add(new TreeMap<>()); 69 | int index = dp.size() - 1; 70 | TreeMap cur = dp.get(index); 71 | int size = 1; 72 | if (index > 0) { 73 | TreeMap pre = dp.get(index - 1); 74 | size = pre.get(pre.firstKey()); 75 | if (pre.ceilingKey(nums[i]) != null) { 76 | size -= pre.get(pre.ceilingKey(nums[i])); 77 | } 78 | } 79 | cur.put(nums[i], size); 80 | } else { 81 | int newAdd = 1; 82 | if (find > 0) { 83 | TreeMap pre = dp.get(find - 1); 84 | newAdd = pre.get(pre.firstKey()); 85 | if (pre.ceilingKey(nums[i]) != null) { 86 | newAdd -= pre.get(pre.ceilingKey(nums[i])); 87 | } 88 | } 89 | // >=nums[i] ? 90 | TreeMap cur = dp.get(find); 91 | if (cur.firstKey() == nums[i]) { 92 | cur.put(nums[i], cur.get(nums[i]) + newAdd); 93 | } else { 94 | int preNum = cur.get(cur.firstKey()); 95 | cur.put(nums[i], newAdd + preNum); 96 | } 97 | } 98 | 99 | } 100 | return dp.get(dp.size() - 1).firstEntry().getValue(); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0212_WordSearchII.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashSet; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | 8 | public class Problem_0212_WordSearchII { 9 | 10 | public static class TrieNode { 11 | public TrieNode[] nexts; 12 | public int pass; 13 | public int end; 14 | 15 | public TrieNode() { 16 | nexts = new TrieNode[26]; 17 | pass = 0; 18 | end = 0; 19 | } 20 | } 21 | 22 | public static List findWords(char[][] board, String[] words) { 23 | TrieNode head = new TrieNode(); // 前缀树最顶端的头 24 | HashSet set = new HashSet<>(); 25 | for (String word : words) { 26 | if (!set.contains(word)) { 27 | fillWord(head, word); 28 | set.add(word); 29 | } 30 | } 31 | // 答案 32 | List res = new ArrayList<>(); 33 | // 沿途走过的字符,收集起来,存在path里 34 | LinkedList path = new LinkedList<>(); 35 | for (int row = 0; row < board.length; row++) { 36 | for (int col = 0; col < board[0].length; col++) { 37 | // 枚举在board中的所有位置 38 | // 每一个位置出发的情况下,答案都收集 39 | process(board, row, col, path, head, res); 40 | } 41 | } 42 | return res; 43 | } 44 | 45 | public static void fillWord(TrieNode node, String word) { 46 | node.pass++; 47 | char[] chs = word.toCharArray(); 48 | int index = 0; 49 | for (int i = 0; i < chs.length; i++) { 50 | index = chs[i] - 'a'; 51 | if (node.nexts[index] == null) { 52 | node.nexts[index] = new TrieNode(); 53 | } 54 | node = node.nexts[index]; 55 | node.pass++; 56 | } 57 | node.end++; 58 | } 59 | 60 | // 从board[row][col]位置的字符出发, 61 | // 之前的路径上,走过的字符,记录在path里 62 | // cur还没有登上,有待检查能不能登上去的前缀树的节点 63 | // 如果找到words中的某个str,就记录在 res里 64 | // 返回值,从row,col 出发,一共找到了多少个str 65 | public static int process(char[][] board, int row, int col, LinkedList path, TrieNode cur, 66 | List res) { 67 | char cha = board[row][col]; 68 | if (cha == 0) { // 这个row col位置是之前走过的位置 69 | return 0; 70 | } 71 | // (row,col) 不是回头路 72 | 73 | int index = cha - 'a'; 74 | // 如果没路,或者这条路上最终的字符串之前加入过结果里 75 | if (cur.nexts[index] == null || cur.nexts[index].pass == 0) { 76 | return 0; 77 | } 78 | // 没有走回头路且能登上去 79 | cur = cur.nexts[index]; 80 | path.addLast(cha);// 当前位置的字符加到路径里去 81 | int fix = 0; // 从row和col位置出发,后续一共搞定了多少答案 82 | // 当我来到row col位置,如果决定不往后走了。是不是已经搞定了某个字符串了 83 | if (cur.end > 0) { 84 | res.add(generatePath(path)); 85 | cur.end--; 86 | fix++; 87 | } 88 | // 往上、下、左、右,四个方向尝试 89 | board[row][col] = 0; 90 | if (row > 0) { 91 | fix += process(board, row - 1, col, path, cur, res); 92 | } 93 | if (row < board.length - 1) { 94 | fix += process(board, row + 1, col, path, cur, res); 95 | } 96 | if (col > 0) { 97 | fix += process(board, row, col - 1, path, cur, res); 98 | } 99 | if (col < board[0].length - 1) { 100 | fix += process(board, row, col + 1, path, cur, res); 101 | } 102 | board[row][col] = cha; 103 | path.pollLast(); 104 | cur.pass -= fix; 105 | return fix; 106 | } 107 | 108 | public static String generatePath(LinkedList path) { 109 | char[] str = new char[path.size()]; 110 | int index = 0; 111 | for (Character cha : path) { 112 | str[index++] = cha; 113 | } 114 | return String.valueOf(str); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/topinterviewquestions/Problem_0127_WordLadder.java: -------------------------------------------------------------------------------- 1 | package topinterviewquestions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Queue; 9 | 10 | public class Problem_0127_WordLadder { 11 | 12 | public static int ladderLength1(String start, String to, List list) { 13 | list.add(start); 14 | HashMap> nexts = getNexts(list); 15 | HashMap distanceMap = new HashMap<>(); 16 | distanceMap.put(start, 1); 17 | HashSet set = new HashSet<>(); 18 | set.add(start); 19 | Queue queue = new LinkedList<>(); 20 | queue.add(start); 21 | while (!queue.isEmpty()) { 22 | String cur = queue.poll(); 23 | Integer distance = distanceMap.get(cur); 24 | for (String next : nexts.get(cur)) { 25 | if (next.equals(to)) { 26 | return distance + 1; 27 | } 28 | if (!set.contains(next)) { 29 | set.add(next); 30 | queue.add(next); 31 | distanceMap.put(next, distance + 1); 32 | } 33 | } 34 | 35 | } 36 | return 0; 37 | } 38 | 39 | public static HashMap> getNexts(List words) { 40 | HashSet dict = new HashSet<>(words); 41 | HashMap> nexts = new HashMap<>(); 42 | for (int i = 0; i < words.size(); i++) { 43 | nexts.put(words.get(i), getNext(words.get(i), dict)); 44 | } 45 | return nexts; 46 | } 47 | 48 | // 应该根据具体数据状况决定用什么来找邻居 49 | // 1)如果字符串长度比较短,字符串数量比较多,以下方法适合 50 | // 2)如果字符串长度比较长,字符串数量比较少,以下方法不适合 51 | public static ArrayList getNext(String word, HashSet dict) { 52 | ArrayList res = new ArrayList(); 53 | char[] chs = word.toCharArray(); 54 | for (char cur = 'a'; cur <= 'z'; cur++) { 55 | for (int i = 0; i < chs.length; i++) { 56 | if (chs[i] != cur) { 57 | char tmp = chs[i]; 58 | chs[i] = cur; 59 | if (dict.contains(String.valueOf(chs))) { 60 | res.add(String.valueOf(chs)); 61 | } 62 | chs[i] = tmp; 63 | } 64 | } 65 | } 66 | return res; 67 | } 68 | 69 | public static int ladderLength2(String beginWord, String endWord, List wordList) { 70 | HashSet dict = new HashSet<>(wordList); 71 | if (!dict.contains(endWord)) { 72 | return 0; 73 | } 74 | HashSet startSet = new HashSet<>(); 75 | HashSet endSet = new HashSet<>(); 76 | HashSet visit = new HashSet<>(); 77 | startSet.add(beginWord); 78 | endSet.add(endWord); 79 | for (int len = 2; !startSet.isEmpty(); len++) { 80 | HashSet nextSet = new HashSet<>(); 81 | for (String w : startSet) { 82 | for (int j = 0; j < w.length(); j++) { 83 | char[] ch = w.toCharArray(); 84 | for (char c = 'a'; c <= 'z'; c++) { 85 | if (c != w.charAt(j)) { 86 | ch[j] = c; 87 | String next = String.valueOf(ch); 88 | if (endSet.contains(next)) { 89 | return len; 90 | } 91 | if (dict.contains(next) && !visit.contains(next)) { 92 | nextSet.add(next); 93 | visit.add(next); 94 | } 95 | } 96 | } 97 | } 98 | } 99 | startSet = (nextSet.size() < endSet.size()) ? nextSet : endSet; 100 | endSet = (startSet == nextSet) ? endSet : nextSet; 101 | } 102 | return 0; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/followup/KN.java: -------------------------------------------------------------------------------- 1 | package followup; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | /* 7 | * 8 | * 已知数组中其他数都出现了N次,只有一种数出现了K次 9 | * 怎么找到出现了K次的数?做到时间复杂度O(N),额外空间复杂度O(1) 10 | * 规定:N > 1,K > 0,K < N 11 | * 12 | * */ 13 | 14 | public class KN { 15 | 16 | public static int get1(int[] arr, int k, int n) { 17 | HashMap map = new HashMap<>(); 18 | for (int num : arr) { 19 | if (!map.containsKey(num)) { 20 | map.put(num, 1); 21 | } else { 22 | map.put(num, map.get(num) + 1); 23 | } 24 | } 25 | for (Integer key : map.keySet()) { 26 | if (map.get(key) == k) { 27 | return key; 28 | } 29 | } 30 | return -1; 31 | } 32 | 33 | public static int get2(int[] arr, int k, int n) { 34 | int[] count = new int[32]; 35 | for (int num : arr) { 36 | for (int i = 0; i < 32; i++) { 37 | if ((num & (1 << i)) != 0) { 38 | count[i]++; 39 | } 40 | } 41 | } 42 | for (int i = 0; i < count.length; i++) { 43 | count[i] = (count[i] % n) / k; 44 | } 45 | int ans = 0; 46 | for (int i = 0; i < count.length; i++) { 47 | ans |= (count[i] << i); 48 | } 49 | return ans; 50 | } 51 | 52 | public static int[] randomArray(int k, int n, int type) { 53 | HashSet set = new HashSet<>(); 54 | while (set.size() != type - 1) { 55 | set.add((int) (Math.random() * 10000) - (int) (Math.random() * 10000)); 56 | } 57 | int knum = 0; 58 | do { 59 | knum = (int) (Math.random() * 10000) - (int) (Math.random() * 10000); 60 | } while (set.contains(knum)); 61 | int[] arr = new int[(type - 1) * n + k]; 62 | int index = 0; 63 | for (int num : set) { 64 | for (int i = 0; i < n; i++) { 65 | arr[index++] = num; 66 | } 67 | } 68 | for (int i = 0; i < k; i++) { 69 | arr[index++] = knum; 70 | } 71 | for (int i = arr.length - 1; i >= 0; i--) { 72 | int j = (int) (Math.random() * (i + 1)); 73 | int tmp = arr[i]; 74 | arr[i] = arr[j]; 75 | arr[j] = tmp; 76 | } 77 | return arr; 78 | } 79 | 80 | public static boolean check(int[] arr, int k, int n, int type) { 81 | HashMap map = new HashMap<>(); 82 | for (int num : arr) { 83 | if (!map.containsKey(num)) { 84 | map.put(num, 1); 85 | } else { 86 | map.put(num, map.get(num) + 1); 87 | } 88 | } 89 | int kcount = 0; 90 | int ncount = 0; 91 | for (Integer key : map.keySet()) { 92 | if (map.get(key) == n) { 93 | ncount++; 94 | } else if (map.get(key) == k) { 95 | kcount++; 96 | } else { 97 | return false; 98 | } 99 | } 100 | return map.size() == type && kcount == 1 && ncount == type - 1; 101 | } 102 | 103 | public static void main(String[] args) { 104 | int knMax = 20; 105 | int typeMax = 50; 106 | int testTimes = 100000; 107 | System.out.println("test begin"); 108 | for (int i = 0; i < testTimes; i++) { 109 | int k = 0; 110 | int n = 0; 111 | do { 112 | k = (int) (Math.random() * knMax) + 1; 113 | n = (int) (Math.random() * knMax) + 2; 114 | } while (k >= n); 115 | int type = (int) (Math.random() * typeMax) + 5; 116 | int[] arr = randomArray(k, n, type); 117 | if (!check(arr, k, n, type)) { 118 | System.out.println("random arr error!"); 119 | } 120 | int ans1 = get1(arr, k, n); 121 | int ans2 = get2(arr, k, n); 122 | if (ans1 != ans2) { 123 | System.out.println("Oops!"); 124 | } 125 | } 126 | System.out.println("test end"); 127 | } 128 | 129 | } 130 | --------------------------------------------------------------------------------