├── .github └── workflows │ └── scala.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.sbt ├── docs ├── BestTimetoBuyandSellStock.md ├── ContainsDuplicate.md ├── CourseSchedule.md ├── MyCalendar.md ├── NextGreaterElement.md └── ValidPalindrome.md ├── project ├── build.properties └── plugins.sbt └── src ├── main └── scala │ ├── array │ ├── BestTimetoBuyandSellStock.scala │ ├── MergeSortedArray.scala │ ├── MinimumIncrementtoMakeArrayUnique.scala │ ├── MoveZeroes.scala │ ├── RemoveDuplicatesfromSortedArray.scala │ ├── ReverseWordsinaString.scala │ ├── RotateArray.scala │ ├── Subsets.scala │ └── array.md │ ├── backtracking │ ├── CombinationSum2.scala │ ├── Combinations.scala │ ├── GenerateParentheses.scala │ ├── LetterCombinationsofaPhoneNumber.scala │ ├── NQueens.scala │ ├── NQueens2.scala │ ├── Permutations.scala │ ├── Permutations2.scala │ ├── RestoreIPAddresses.scala │ ├── WordSearch.scala │ └── backtracking.md │ ├── bfs │ ├── BinaryTreeRightSideView.scala │ ├── CloneGraph.scala │ ├── SurroundedRegions.scala │ └── bfs.md │ ├── binarysearch │ ├── FindFirstAndLastPositionInSortedArray.scala │ ├── FindMinimuminRotatedSortedArray.scala │ ├── FindMinimuminRotatedSortedArray2.scala │ ├── FindPeakElement.scala │ ├── FirstBadVersion.scala │ ├── HIndex2.scala │ ├── MedianofTwoSortedArrays.scala │ ├── SearchInsertPosition.scala │ ├── SearchinRotatedSortedArray.scala │ ├── SearchinRotatedSortedArray2.scala │ ├── Sqrt.scala │ └── binarysearch.md │ ├── bit │ ├── ConvertaNumbertoHexadecimal.scala │ ├── DivideTwoIntegers.scala │ ├── GrayCode.scala │ ├── Numberof1Bits.scala │ ├── RepeatedDNASequences.scala │ ├── ReverseBits.scala │ ├── SingleNumber.scala │ ├── SingleNumber2.scala │ ├── Subsets.scala │ └── bit.md │ ├── bst │ ├── BinarySearchTreeIterator.scala │ ├── BinaryTreePaths.scala │ ├── ConvertSortedArraytoBST.scala │ ├── DeleteNodeinaBST.scala │ ├── InsertIntoaBST.scala │ ├── LowestCommonAncestorofBST.scala │ ├── RecoverBinarySearchTree.scala │ ├── SameTree.scala │ ├── ValidateBinarySearchTree.scala │ └── bst.md │ ├── bucketsort │ ├── ContainsDuplicate3.scala │ ├── MaximumGap.scala │ ├── SortCharactersByFrequency.scala │ ├── TopKFrequentElements.scala │ ├── TopKFrequentWords.scala │ └── bucketsort.md │ ├── counting │ ├── ContainsDuplicate.scala │ ├── MajorityElement.scala │ ├── MajorityElement2.scala │ ├── RansomNote.scala │ ├── RearrangeStringkDistanceApart.scala │ └── counting.md │ ├── dfs │ ├── BinaryTreeUpsideDown.scala │ ├── PathSum.scala │ ├── PathSum2.scala │ ├── PopulatingNextRightPointersinEachNode.scala │ ├── SumRoottoLeafNumbers.scala │ ├── WordLadder.scala │ └── dfs.md │ ├── dp │ ├── BestTimetoBuyandSellStock3.scala │ ├── BestTimetoBuyandSellStock4.scala │ ├── ClimbingStairs.scala │ ├── CoinChange.scala │ ├── CoinChange2.scala │ ├── DecodeWays.scala │ ├── DistinctSubsequences.scala │ ├── DungeonGame.scala │ ├── InterleavingString.scala │ ├── JumpGame.scala │ ├── LongestPalindromicSubsequence.scala │ ├── LongestPalindromicSubstring.scala │ ├── MaximumSubarray.scala │ ├── MinimumPathSum.scala │ ├── TargetSum.scala │ ├── Triangle.scala │ ├── UniquePaths2.scala │ ├── ValidPalindrome3.scala │ └── dp.md │ ├── fastslowpointers │ ├── LinkedListCycle.scala │ ├── LinkedListCycle2.scala │ ├── MiddleoftheLinkedList.scala │ └── pointers.md │ ├── graph │ ├── CourseSchedule.scala │ ├── CourseSchedule2.scala │ ├── MinimumHeightTrees.scala │ ├── Node.scala │ └── graph.md │ ├── greedy │ ├── BestTimetoBuyandSellStock2.scala │ ├── Candy.scala │ ├── CourseSchedule3.scala │ ├── GasStation.scala │ ├── LargestNumber.scala │ ├── WildcardMatching.scala │ └── greedy.md │ ├── hashmap │ ├── BrickWall.scala │ ├── BullsandCows.scala │ ├── FirstUniqChar.scala │ ├── HappyNumber.scala │ ├── InsertDeleteGetRandomO1.scala │ ├── IsomorphicStrings.scala │ ├── TwoSum.scala │ └── hashmap.md │ ├── heap │ ├── KthLargestElementinanArray.scala │ ├── PriorityQueue.scala │ ├── RelativeRanks.scala │ ├── TheSkylineProblem.scala │ ├── UglyNumber2.scala │ └── heap.md │ ├── linkedlist │ ├── AddTwoNumbers.scala │ ├── AddTwoNumbers2.scala │ ├── CopyListwithRandomPointer.scala │ ├── IntersectionofTwoLinkedLists.scala │ ├── LinkedList.scala │ ├── PartitionList.scala │ ├── RemoveDuplicatesfromSortedList.scala │ ├── RemoveDuplicatesfromSortedListII.scala │ ├── RemoveNthFromEnd.scala │ ├── ReorderList.scala │ ├── ReverseList.scala │ ├── RotateList.scala │ └── linkedlist.md │ ├── math │ ├── ExcelSheetColumnNumber.scala │ ├── ExcelSheetColumnTitle.scala │ ├── FactorialTrailingZeroes.scala │ ├── Fraction2RecurringDecimal.scala │ ├── Integer2Roman.scala │ ├── MaxPointsonaLine.scala │ ├── PlusOne.scala │ ├── PowXn.scala │ ├── Roman2Integer.scala │ ├── UniqueBinarySearchTrees.scala │ └── math.md │ ├── matrix │ ├── RotateImage.scala │ ├── Searcha2DMatrix.scala │ ├── SetMatrixZeroes.scala │ ├── SpiralMatrix.scala │ ├── SpiralMatrix2.scala │ ├── SudokuSolver.scala │ ├── ValidSudoku.scala │ └── matrix.md │ ├── monotonicstack │ ├── LargestRectangleinHistogram.scala │ ├── NextGreaterElement.scala │ ├── NextGreaterElement2.scala │ ├── NextGreaterElement3.scala │ └── monotonicstack.md │ ├── number │ ├── MultiplyStrings.scala │ ├── PalindromeNumber.scala │ ├── ReverseInteger.scala │ └── number.md │ ├── orderedset │ ├── ExamRoom.scala │ ├── MinimumAbsoluteSumDifference.scala │ ├── MyCalendar.scala │ ├── MyCalendar2.scala │ ├── MyCalendar3.scala │ └── orderedset.md │ ├── prefixsum │ ├── ContiguousArray.scala │ ├── ContinuousSubarraySum.scala │ ├── FindPivotIndex.scala │ ├── ProductofArrayExceptSelf.scala │ ├── RangeSumQueryImmutable.scala │ └── prefixsum.md │ ├── queue │ ├── Dota2Senate.scala │ ├── MyQueue.scala │ ├── MyStack.scala │ ├── RevealCardsInIncreasingOrder.scala │ ├── SlidingWindowMaximum.scala │ ├── ZigzagIterator.scala │ └── queue.md │ ├── recursion │ ├── MergeKSortedLists.scala │ ├── MergeTwoSortedLists.scala │ ├── PermutationSequence.scala │ ├── RegularExpressionMatching.scala │ ├── ReverseNodesinkGroup.scala │ ├── ScrambleString.scala │ ├── StrobogrammaticNumber2.scala │ ├── SwapNodesinPairs.scala │ └── recursion.md │ ├── sort │ ├── GroupAnagrams.scala │ ├── MergeIntervals.scala │ ├── SortList.scala │ └── sort.md │ ├── stack │ ├── DecodeString.scala │ ├── EvaluateReversePolishNotation.scala │ ├── LongestValidParentheses.scala │ ├── MinStack.scala │ ├── OnlineStockSpan.scala │ ├── ShortestUnsortedContinuousSubarray.scala │ ├── SimplifyPath.scala │ ├── ValidParentheses.scala │ └── stack.md │ ├── string │ ├── AddBinary.scala │ ├── AddStrings.scala │ ├── CompareVersionNumbers.scala │ ├── CountandSay.scala │ ├── LongestCommonPrefix.scala │ ├── MinimumWindowSubstring.scala │ ├── OneEditDistance.scala │ ├── PartitionLabels.scala │ ├── ZigZagConversion.scala │ └── string.md │ ├── tree │ ├── BalancedBinaryTree.scala │ ├── BinaryTreeTraversal.scala │ ├── ConstructBinaryTreefromInorderandPostorder.scala │ ├── ConstructBinaryTreefromPreorderandInorder.scala │ ├── FlattenBinaryTreetoLinkedList.scala │ ├── InvertBinaryTree.scala │ ├── LowestCommonAncestorofaBinaryTree.scala │ ├── MaximumDepthofBinaryTree.scala │ ├── MinimumDepthofBinaryTree.scala │ ├── SymmetricTree.scala │ ├── TreeNode.scala │ └── tree.md │ ├── tries │ ├── IndexPairsofaString.scala │ ├── Trie.scala │ ├── WordBreak.scala │ ├── WordBreak2.scala │ ├── WordSearch2.scala │ └── tries.md │ ├── twopointers │ ├── ContainerWithMostWater.scala │ ├── ContainsDuplicate2.scala │ ├── ImplementstrStr.scala │ ├── LengthOfLongestSubString.scala │ ├── LongestSubstringwithAtMostTwoDistinctCharacters.scala │ ├── MinimumSizeSubarraySum.scala │ ├── RemoveDuplicatesfromSortedArrayII.scala │ ├── SortColors.scala │ ├── StringCompression.scala │ ├── SubstringwithConcatenationofAllWords.scala │ ├── SummaryRanges.scala │ ├── ThreeSum.scala │ ├── ThreeSumClosest.scala │ ├── TrappingRainWater.scala │ ├── TwoSumII.scala │ ├── ValidPalindrome.scala │ ├── ValidPalindrome2.scala │ ├── ValidPalindrome4.scala │ └── twopointers.md │ └── unionfind │ ├── NumberofIslands.scala │ ├── NumberofIslands2.scala │ ├── NumberofProvinces.scala │ ├── UF.scala │ └── unionfind.md └── test └── scala ├── array ├── BestTimetoBuyandSellStockTest.scala ├── MergeSortedArrayTest.scala ├── MinimumIncrementtoMakeArrayUniqueTest.scala ├── MoveZeroesTest.scala ├── RemoveDuplicatesfromSortedArrayTest.scala ├── ReverseWordsinaStringTest.scala ├── RotateArrayTest.scala └── SubsetsTest.scala ├── backtracking ├── CombinationSum2Test.scala ├── CombinationsTest.scala ├── GenerateParenthesesTest.scala ├── LetterCombinationsofaPhoneNumberTest.scala ├── NQueens2Test.scala ├── NQueensTest.scala ├── Permutations2Test.scala ├── PermutationsTest.scala ├── RestoreIPAddressesTest.scala └── WordSearchTest.scala ├── bfs ├── BinaryTreeRightSideViewTest.scala ├── CloneGraphTest.scala └── SurroundedRegionsTest.scala ├── binarysearch ├── FindFirstAndLastPositionInSortedArrayTest.scala ├── FindMinimuminRotatedSortedArray2Test.scala ├── FindMinimuminRotatedSortedArrayTest.scala ├── FindPeakElementTest.scala ├── FirstBadVersionTest.scala ├── HIndex2Test.scala ├── MedianofTwoSortedArraysTest.scala ├── SearchInsertPositionTest.scala ├── SearchinRotatedSortedArray2Test.scala ├── SearchinRotatedSortedArrayTest.scala └── SqrtTest.scala ├── bit ├── ConvertaNumbertoHexadecimalTest.scala ├── DivideTwoIntegersTest.scala ├── GrayCodeTest.scala ├── Numberof1BitsTest.scala ├── RepeatedDNASequencesTest.scala ├── ReverseBitsTest.scala ├── SingleNumber2Test.scala ├── SingleNumberTest.scala └── SubsetsTest.scala ├── bst ├── BinarySearchTreeIteratorTest.scala ├── BinaryTreePathsTest.scala ├── ConvertSortedArraytoBSTTest.scala ├── DeleteNodeinaBSTTest.scala ├── InsertIntoaBSTTest.scala ├── LowestCommonAncestorofBSTTest.scala ├── RecoverBinarySearchTreeTest.scala ├── SameTreeTest.scala └── ValidateBinarySearchTreeTest.scala ├── bucketsort ├── ContainsDuplicate3Test.scala ├── MaximumGapTest.scala ├── SortCharactersByFrequencyTest.scala ├── TopKFrequentElementsTest.scala └── TopKFrequentWordsTest.scala ├── counting ├── ContainsDuplicateTest.scala ├── MajorityElement2Test.scala ├── MajorityElementTest.scala ├── RansomNoteTest.scala └── RearrangeStringkDistanceApartTest.scala ├── dfs ├── BinaryTreeUpsideDownTest.scala ├── PathSum2Test.scala ├── PathSumTest.scala ├── PopulatingNextRightPointersinEachNodeTest.scala ├── SumRoottoLeafNumbersTest.scala └── WordLadderTest.scala ├── dp ├── BestTimetoBuyandSellStock3Test.scala ├── BestTimetoBuyandSellStock4Test.scala ├── ClimbingStairsTest.scala ├── CoinChange2Test.scala ├── CoinChangeTest.scala ├── DecodeWaysTest.scala ├── DistinctSubsequencesTest.scala ├── DungeonGameTest.scala ├── InterleavingStringTest.scala ├── JumpGameTest.scala ├── LongestPalindromicSubsequenceTest.scala ├── LongestPalindromicSubstringTest.scala ├── MaximumSubarrayTest.scala ├── MinimumPathSumTest.scala ├── TargetSumTest.scala ├── TriangleTest.scala ├── UniquePaths2Test.scala └── ValidPalindrome3Test.scala ├── fastslowpointers ├── LinkedListCycle2Test.scala ├── LinkedListCycleTest.scala └── MiddleoftheLinkedListTest.scala ├── graph ├── CourseSchedule2Test.scala ├── CourseScheduleTest.scala ├── MinimumHeightTreesTest.scala └── NodeTest.scala ├── greedy ├── BestTimetoBuyandSellStock2Test.scala ├── CandyTest.scala ├── CourseSchedule3Test.scala ├── GasStationTest.scala ├── LargestNumberTest.scala └── WildcardMatchingTest.scala ├── hashmap ├── BrickWallTest.scala ├── BullsandCowsTest.scala ├── FirstUniqCharTest.scala ├── HappyNumberTest.scala ├── InsertDeleteGetRandomO1Test.scala ├── IsomorphicStringsTest.scala └── TwoSumTest.scala ├── heap ├── KthLargestElementinanArrayTest.scala ├── PriorityQueueTest.scala ├── RelativeRanksTest.scala ├── TheSkylineProblemTest.scala └── UglyNumber2Test.scala ├── linkedlist ├── AddTwoNumbers2Test.scala ├── AddTwoNumbersTest.scala ├── CopyListwithRandomPointerTest.scala ├── IntersectionofTwoLinkedListsTest.scala ├── LinkedListTest.scala ├── PartitionListTest.scala ├── RemoveDuplicatesfromSortedListIITest.scala ├── RemoveDuplicatesfromSortedListTest.scala ├── RemoveNthFromEndTest.scala ├── ReorderListTest.scala ├── ReverseListTest.scala └── RotateListTest.scala ├── math ├── ExcelSheetColumnNumberTest.scala ├── ExcelSheetColumnTitleTest.scala ├── FactorialTrailingZeroesTest.scala ├── Fraction2RecurringDecimalTest.scala ├── Integer2RomanTest.scala ├── MaxPointsonaLineTest.scala ├── PlusOneTest.scala ├── PowXnTest.scala ├── Roman2IntegerTest.scala └── UniqueBinarySearchTreesTest.scala ├── matrix ├── RotateImageTest.scala ├── Searcha2DMatrixTest.scala ├── SetMatrixZeroesTest.scala ├── SpiralMatrix2Test.scala ├── SpiralMatrixTest.scala ├── SudokuSolverTest.scala └── ValidSudokuTest.scala ├── monotonicstack ├── LargestRectangleinHistogramTest.scala ├── NextGreaterElement2Test.scala ├── NextGreaterElement3Test.scala └── NextGreaterElementTest.scala ├── number ├── MultiplyStringsTest.scala ├── PalindromeNumberTest.scala └── ReverseIntegerTest.scala ├── orderedset ├── ExamRoomTest.scala ├── MinimumAbsoluteSumDifferenceTest.scala ├── MyCalendar2Test.scala ├── MyCalendar3Test.scala └── MyCalendarTest.scala ├── prefixsum ├── ContiguousArrayTest.scala ├── ContinuousSubarraySumTest.scala ├── FindPivotIndexTest.scala ├── ProductofArrayExceptSelfTest.scala └── RangeSumQueryImmutableTest.scala ├── queue ├── Dota2SenateTest.scala ├── MyQueueTest.scala ├── MyStackTest.scala ├── RevealCardsInIncreasingOrderTest.scala ├── SlidingWindowMaximumTest.scala └── ZigzagIteratorTest.scala ├── recursion ├── MergeKSortedListsTest.scala ├── MergeTwoSortedListsTest.scala ├── PermutationSequenceTest.scala ├── RegularExpressionMatchingTest.scala ├── ReverseNodesinkGroupTest.scala ├── ScrambleStringTest.scala ├── StrobogrammaticNumber2Test.scala └── SwapNodesinPairsTest.scala ├── sort ├── GroupAnagramsTest.scala ├── MergeIntervalsTest.scala └── SortListTest.scala ├── stack ├── DecodeStringTest.scala ├── EvaluateReversePolishNotationTest.scala ├── LongestValidParenthesesTest.scala ├── MinStackTest.scala ├── OnlineStockSpanTest.scala ├── ShortestUnsortedContinuousSubarrayTest.scala ├── SimplifyPathTest.scala └── ValidParenthesesTest.scala ├── string ├── AddBinaryTest.scala ├── AddStringsTest.scala ├── CompareVersionNumbersTest.scala ├── CountandSayTest.scala ├── LongestCommonPrefixTest.scala ├── MinimumWindowSubstringTest.scala ├── OneEditDistanceTest.scala ├── PartitionLabelsTest.scala └── ZigZagConversionTest.scala ├── tree ├── BalancedBinaryTreeTest.scala ├── BinaryTreeTraversalTest.scala ├── ConstructBinaryTreefromInorderandPostorderTest.scala ├── ConstructBinaryTreefromPreorderandInorderTest.scala ├── FlattenBinaryTreetoLinkedListTest.scala ├── InvertBinaryTreeTest.scala ├── LowestCommonAncestorofaBinaryTreeTest.scala ├── MaximumDepthofBinaryTreeTest.scala ├── MinimumDepthofBinaryTreeTest.scala ├── SymmetricTreeTest.scala └── TreeNodeTest.scala ├── tries ├── IndexPairsofaStringTest.scala ├── TrieTest.scala ├── WordBreak2Test.scala ├── WordBreakTest.scala └── WordSearch2Test.scala ├── twopointers ├── ContainerWithMostWaterTest.scala ├── ContainsDuplicate2Test.scala ├── ImplementstrStrTest.scala ├── LengthOfLongestSubStringTest.scala ├── LongestSubstringwithAtMostTwoDistinctCharactersTest.scala ├── MinimumSizeSubarraySumTest.scala ├── RemoveDuplicatesfromSortedArrayIITest.scala ├── SortColorsTest.scala ├── StringCompressionTest.scala ├── SubstringwithConcatenationofAllWordsTest.scala ├── SummaryRangesTest.scala ├── ThreeSumClosestTest.scala ├── ThreeSumTest.scala ├── TrappingRainWaterTest.scala ├── TwoSumIITest.scala ├── ValidPalindrome2Test.scala ├── ValidPalindrome4Test.scala └── ValidPalindromeTest.scala └── unionfind ├── NumberofIslands2Test.scala ├── NumberofIslandsTest.scala └── NumberofProvincesTest.scala /.github/workflows/scala.yml: -------------------------------------------------------------------------------- 1 | name: Scala CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Set up JDK 11 15 | uses: actions/setup-java@v2 16 | with: 17 | java-version: '11' 18 | distribution: 'adopt' 19 | - name: Run tests 20 | run: sbt jacoco 21 | - name: Upload to codecov 22 | run: bash <(curl -s https://codecov.io/bash) 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bsp/ 2 | .idea/ 3 | target/ 4 | **/target/ 5 | *.class 6 | *.log 7 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | val scala3Version = "3.0.1" 2 | 3 | lazy val root = project 4 | .in(file(".")) 5 | .settings( 6 | name := "scala3-simple", 7 | version := "0.1.0", 8 | 9 | scalaVersion := scala3Version, 10 | 11 | libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test", 12 | libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.9" % "test" 13 | ) 14 | 15 | jacocoReportSettings := JacocoReportSettings() 16 | .withFileEncoding("UTF-8") 17 | .withFormats(JacocoReportFormats.XML) 18 | 19 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.5.5 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") 2 | -------------------------------------------------------------------------------- /src/main/scala/array/BestTimetoBuyandSellStock.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | object BestTimetoBuyandSellStock { 4 | def maxProfit(prices: Array[Int]): Int = prices match 5 | case Array() => 0 6 | case Array(head, tail) => if head < tail then tail - head else 0 7 | case _ => var (maxprofit, minprice) = (0, prices(0)) 8 | prices.drop(1).foreach(price => { 9 | maxprofit = maxprofit.max(price - minprice) 10 | minprice = minprice.min(price) 11 | }) 12 | maxprofit 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/array/MergeSortedArray.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | object MergeSortedArray { 4 | def merge(nums1: Array[Int], m: Int, nums2: Array[Int], n: Int): Unit = 5 | var (p1, p2) = (0, 0) 6 | while p1 < m do 7 | if n > 0 && nums1(p1) > nums2(p2) then { 8 | val tmp = nums2(p2) 9 | nums2(p2) = nums1(p1) 10 | nums1(p1) = tmp 11 | } 12 | p1 = p1 + 1 13 | for (i <- 0 until n) nums1(m + i) = nums2(i) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/array/MinimumIncrementtoMakeArrayUnique.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | object MinimumIncrementtoMakeArrayUnique { 4 | def minIncrementForUnique(nums: Array[Int]): Int = nums match 5 | case Array(_) => 0 6 | case _ => val sorted = nums.sorted 7 | var (result, currentexpect) = (0, sorted(0) + 1) 8 | sorted.drop(1).foreach(num => { 9 | if num < currentexpect then 10 | result = result + (currentexpect - num) 11 | currentexpect = currentexpect + 1 12 | else 13 | currentexpect = num + 1 14 | end if 15 | }) 16 | result 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/array/MoveZeroes.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | object MoveZeroes { 4 | def moveZeroes(nums: Array[Int]): Unit = 5 | var (index, nonezeroPos) = (0, 0) 6 | while nonezeroPos < nums.length do 7 | while nums(nonezeroPos) == 0 do nonezeroPos = nonezeroPos + 1 8 | if nonezeroPos < nums.length then { 9 | nums(index) = nums(nonezeroPos) 10 | nonezeroPos = nonezeroPos + 1 11 | index = index + 1 12 | } 13 | (index until nums.length).foreach(nums(_) = 0) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/array/RemoveDuplicatesfromSortedArray.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | object RemoveDuplicatesfromSortedArray { 4 | def removeDuplicates(nums: Array[Int]): Int = 5 | nums.foldLeft(1) { case (index, num) => 6 | if num <= nums(index - 1) then index else { 7 | nums(index) = num 8 | index + 1 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/array/RotateArray.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | object RotateArray { 4 | def rotate(nums: Array[Int], k: Int): Unit = 5 | reverse(nums, 0, nums.length - 1) 6 | reverse(nums, 0, k) 7 | reverse(nums, k + 1, nums.length - 1) 8 | 9 | private def reverse(nums: Array[Int], sp: Int, ep: Int): Unit = 10 | var (s, e) = (sp, ep) 11 | while s < e do 12 | val tmp = nums(e) 13 | nums(e) = nums(s) 14 | nums(s) = tmp 15 | s = s + 1 16 | e = e - 1 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/array/Subsets.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | import scala.collection.mutable 4 | 5 | object Subsets { 6 | def subsets(nums: Array[Int]): List[List[Int]] = 7 | val cache = mutable.ListBuffer[List[Int]]() 8 | cache.addOne(List[Int]()) 9 | nums.foreach(num => { 10 | val temp = mutable.ListBuffer[List[Int]]() 11 | cache.foreach(list => temp.addOne(mutable.ListBuffer[Int]().addAll(list).addOne(num).toList)) 12 | cache.addAll(temp) 13 | }) 14 | cache.toList 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/backtracking/Combinations.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import scala.collection.mutable 4 | 5 | object Combinations { 6 | def combine(n: Int, k: Int): List[List[Int]] = 7 | val result = mutable.ListBuffer[List[Int]]() 8 | for (i <- 1 to n) _combine(i, n, k, mutable.ListBuffer[Int](), result) 9 | result.toList 10 | 11 | private def _combine(i: Int, n: Int, k: Int, buffer: mutable.ListBuffer[Int], result: mutable.ListBuffer[List[Int]]): Unit = 12 | buffer.addOne(i) 13 | if buffer.length == k then result.addOne(buffer.clone.toList) 14 | else if buffer.length < k then for (j <- i + 1 to n) _combine(j, n, k, buffer, result) 15 | buffer.remove(buffer.length - 1) 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/backtracking/GenerateParentheses.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import scala.collection.mutable 4 | 5 | object GenerateParentheses { 6 | def generateParenthesis(n: Int): List[String] = 7 | val cache = mutable.ListBuffer[String]() 8 | generateParenthesisInternal(cache, "", 0, 0, n) 9 | cache.toList 10 | 11 | private def generateParenthesisInternal(cache: mutable.ListBuffer[String], tmp: String, open: Int, close: Int, max: Int): Unit = 12 | if open == max && close == max then cache.append(tmp) 13 | else 14 | if open < max then generateParenthesisInternal(cache, tmp + "(", open + 1, close, max) 15 | if close < open then generateParenthesisInternal(cache, tmp + ")", open, close + 1, max) 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/backtracking/Permutations2.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import scala.collection.mutable 4 | 5 | object Permutations2 { 6 | def permuteUnique(nums: Array[Int]): List[List[Int]] = _permuteUnique(nums, mutable.HashSet[List[Int]]()) 7 | 8 | private def _permuteUnique(nums: Array[Int], buffer: mutable.HashSet[List[Int]]): List[List[Int]] = nums match 9 | case Array() => buffer.toList 10 | case _ => nums.zipWithIndex.flatMap { case (_, i) => 11 | _permuteUnique(nums.take(i) ++ nums.drop(i + 1) 12 | , if buffer.isEmpty then mutable.HashSet(List(nums(i))) else buffer.map(l => nums(i) :: l)) 13 | }.toList 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/bfs/BinaryTreeRightSideView.scala: -------------------------------------------------------------------------------- 1 | package bfs 2 | 3 | import tree.TreeNode 4 | 5 | import scala.collection.mutable 6 | 7 | object BinaryTreeRightSideView { 8 | def rightSideView(root: TreeNode[Int]): List[Int] = 9 | val result = mutable.ListBuffer[Int]() 10 | var queue = mutable.ListBuffer[TreeNode[Int]]().addOne(root) 11 | while queue.nonEmpty do { 12 | result.addOne(queue.last.value) 13 | val tmpqueue = mutable.ListBuffer[TreeNode[Int]]() 14 | while queue.nonEmpty do { 15 | val node = queue.remove(0) 16 | if node.left.isDefined then tmpqueue.addOne(node.left.get) 17 | if node.right.isDefined then tmpqueue.addOne(node.right.get) 18 | } 19 | queue = tmpqueue 20 | } 21 | result.toList 22 | } 23 | -------------------------------------------------------------------------------- /src/main/scala/binarysearch/FindFirstAndLastPositionInSortedArray.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | object FindFirstAndLastPositionInSortedArray { 4 | def searchRange(nums: Array[Int], target: Int): Array[Int] = 5 | Array(find(nums, target, (a: Int, b: Int) => a >= b), find(nums, target, (a: Int, b: Int) => a > b)) 6 | 7 | private def find(nums: Array[Int], target: Int, compare: (Int, Int) => Boolean): Int = 8 | var (index, left, mid, right) = (-1, 0, nums.length / 2, nums.length - 1) 9 | while left <= right do { 10 | mid = (left + right) / 2 11 | if compare(nums(mid), target) then right = mid - 1 else left = mid + 1 12 | if nums(mid) == target then index = mid 13 | } 14 | index 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/binarysearch/FindMinimuminRotatedSortedArray.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | object FindMinimuminRotatedSortedArray { 4 | def findMin(nums: Array[Int]): Int = 5 | var (low, high) = (0, nums.length - 1) 6 | while low < high do { 7 | val mid = low + (high - low) / 2 8 | if nums(mid) > nums(high) then low = mid + 1 9 | else high = mid 10 | } 11 | nums(high) 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/binarysearch/FindMinimuminRotatedSortedArray2.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | object FindMinimuminRotatedSortedArray2 { 4 | def findMin(nums: Array[Int]): Int = 5 | var (low, high) = (0, nums.length - 1) 6 | while low < high do { 7 | val mid = low + (high - low) / 2 8 | if nums(mid) > nums(high) then low = mid + 1 9 | else if nums(mid) < nums(low) then { 10 | high = mid 11 | low = low + 1 12 | } else high = high - 1 13 | } 14 | nums(low) 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/main/scala/binarysearch/FindPeakElement.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | object FindPeakElement { 4 | def findPeakElement(nums: Array[Int]): Int = 5 | var (low, high) = (0, nums.length - 1) 6 | while low < high do { 7 | val mid = low + (high - low) / 2 8 | val (midb, mida) = (mid - 1, mid + 1) 9 | if (midb < 0 && nums(mid) > nums(mida)) || (nums(mid) > nums(mida) && nums(mid) > nums(midb)) || (mida >= nums.length && nums(mid) > nums(midb)) then return mid 10 | else if nums(mid) < nums(midb) then high = mid 11 | else low = mid 12 | } 13 | low 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/binarysearch/FirstBadVersion.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | class VersionControl(badversion: Int) { 4 | def isBadVersion(version: Int): Boolean = version >= badversion 5 | } 6 | 7 | class FirstBadVersion(badversion: Int) extends VersionControl(badversion) { 8 | def firstBadVersion(n: Int): Int = 9 | var (low, high) = (1, n) 10 | while low < high do { 11 | val mid = low + (high - low) / 2 12 | if !isBadVersion(mid) then low = mid + 1 13 | else high = mid 14 | } 15 | low 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/binarysearch/HIndex2.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | object HIndex2 { 4 | def hIndex(citations: Array[Int]): Int = 5 | var (low, high) = (0, citations.length - 1) 6 | while low <= high do 7 | val mid = low + (high - low) / 2 8 | if (citations.length - mid) > citations(mid) then low = mid + 1 9 | else high = mid - 1 10 | citations.length - low 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/binarysearch/SearchInsertPosition.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | object SearchInsertPosition { 4 | def searchInsert(nums: Array[Int], target: Int): Int = 5 | var (low, high) = (0, nums.length - 1) 6 | while low <= high do { 7 | val mid = low + (high - low) / 2 8 | if nums(mid) == target then return mid 9 | else if nums(mid) > target then high = mid - 1 10 | else low = mid + 1 11 | } 12 | low 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/binarysearch/SearchinRotatedSortedArray.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | object SearchinRotatedSortedArray { 4 | def search(nums: Array[Int], target: Int): Int = 5 | var (low, mid, high) = (0, nums.length / 2, nums.length - 1) 6 | while low <= high do { 7 | mid = (low + high) / 2 8 | if nums(mid) == target then return mid 9 | else if nums(mid) > target then { 10 | if nums(low) > target then low = mid + 1 else high = mid - 1 11 | } else { 12 | if nums(high) < target then high = mid - 1 else low = mid + 1 13 | } 14 | } 15 | -1 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/binarysearch/SearchinRotatedSortedArray2.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | object SearchinRotatedSortedArray2 { 4 | def search(nums: Array[Int], target: Int): Boolean = 5 | var (low, high) = (0, nums.length) 6 | while low <= high do { 7 | val mid = low + (high - low) / 2 8 | if target == nums(mid) then return true 9 | else if target < nums(mid) then 10 | if nums(high) < target then high = mid - 1 else low = mid + 1 11 | else 12 | if nums(low) > target then low = mid + 1 else high = mid - 1 13 | } 14 | false 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/binarysearch/Sqrt.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | object Sqrt { 4 | def mySqrt(x: Int): Int = x match 5 | case n if n <= 1 => n / 1 6 | case n if n <= 4 => n / 2 7 | case _ => var (low, mid, high) = (1, 1 + (x / 2 - 1) / 2, x / 2) 8 | while !(mid * mid == x || (mid * mid < x && (mid + 1) * (mid + 1) > x)) do 9 | if mid * mid < x then low = mid else high = mid 10 | mid = low + (high - low) / 2 11 | mid 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/bit/ConvertaNumbertoHexadecimal.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | object ConvertaNumbertoHexadecimal { 4 | def toHex(num: Int): String = num match 5 | case 0 => "0" 6 | case n => "0123456789abcdef".charAt(n & 15).toString + (if n >>> 4 != 0 then toHex(n >>> 4) else "") 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/bit/DivideTwoIntegers.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | object DivideTwoIntegers { 4 | def divide(dividend: Int, divisor: Int): Int = 5 | val sign = if (divisor ^ dividend) >= 0 then 1 else -1 6 | var (dvd, dvs, result, count) = (dividend.abs, divisor.abs, 0, 0) 7 | while dvd > dvs do 8 | while dvd > (dvs << count) do count = count + 1 9 | result = result + (1 << (count - 1)) 10 | dvd = dvd - (dvs << (count - 1)) 11 | count = 0 12 | result * sign 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/bit/GrayCode.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | object GrayCode { 4 | def grayCode(n: Int): List[Int] = n match 5 | case 1 => List(0, 1) 6 | case num => grayCode(num - 1) ::: grayCode(num - 1).reverse.map(_ | (1 << (num - 1))) 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/bit/Numberof1Bits.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | object Numberof1Bits { 4 | def hammingWeight(n: Int): Int = (0 to 31).count(i => ((n >>> i) & 1) == 1) 5 | } 6 | -------------------------------------------------------------------------------- /src/main/scala/bit/RepeatedDNASequences.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import scala.collection.mutable 4 | 5 | object RepeatedDNASequences { 6 | def findRepeatedDnaSequences(s: String): List[String] = 7 | val map = Map('A' -> 0, 'C' -> 1, 'G' -> 2, 'T' -> 3) 8 | val cache = mutable.HashSet[Int]() 9 | var seq = 0 10 | (0 until s.length).filter { index => 11 | seq = (seq << 2 | map(s.charAt(index))) & 0x000fffff 12 | index >= 9 && !cache.add(seq) 13 | }.map(i => s.substring(i - 9, i + 1)) 14 | .toList 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/bit/ReverseBits.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | object ReverseBits { 4 | def reverseBits(x: Int): Int = (0 to 31).foldLeft(0) { case (result, index) => (result << 1) | (x >> index & 1) } 5 | } 6 | -------------------------------------------------------------------------------- /src/main/scala/bit/SingleNumber.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | // 136. Single Number 4 | object SingleNumber { 5 | def singleNumber(nums: Array[Int]): Int = nums.reduceLeft { case (acc, num) => acc ^ num } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/scala/bit/SingleNumber2.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | object SingleNumber2 { 4 | def singleNumber(nums: Array[Int]): Int = 5 | (0 to 31).foldLeft(0) { case (result, shift) => 6 | nums.foldLeft(0) { case (count, num) => 7 | if ((num >> shift) & 1) == 1 then (count + 1) % 3 else count 8 | } << shift | result 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/bit/Subsets.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import scala.collection.mutable 4 | 5 | object Subsets { 6 | def subsets(nums: Array[Int]): List[List[Int]] = 7 | (0 until 1 << nums.length).collect[List[Int]] { case i1 => 8 | nums.zipWithIndex 9 | .filter { case (_, i2) => (i1 & (1 << i2)) != 0 } 10 | .map(_._1) 11 | .toList 12 | }.toList 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/bst/BinarySearchTreeIterator.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import tree.TreeNode 4 | 5 | import scala.collection.mutable 6 | 7 | class BinarySearchTreeIterator(_root: TreeNode[Int]) { 8 | private val _list = mutable.Stack[TreeNode[Int]]() 9 | private var _current = Option(_root) 10 | while _current.isDefined do { 11 | _list.push(_current.get) 12 | _current = _current.get.left 13 | } 14 | 15 | def next(): Int = 16 | val node = _list.pop() 17 | var curr = node.right 18 | while curr.isDefined do { 19 | _list.push(curr.get) 20 | curr = curr.get.left 21 | } 22 | node.value 23 | 24 | def hasNext: Boolean = _list.nonEmpty 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/bst/BinaryTreePaths.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import tree.TreeNode 4 | 5 | import scala.collection.mutable 6 | 7 | object BinaryTreePaths { 8 | def binaryTreePaths(root: TreeNode[Int]): List[String] = 9 | val result = mutable.ListBuffer[String]() 10 | _addToPath(root, "", result) 11 | result.toList 12 | 13 | private def _addToPath(node: TreeNode[Int], tmp: String, result: mutable.ListBuffer[String]): Unit = 14 | if node.left.isEmpty && node.right.isEmpty then result.addOne(tmp + node.value) 15 | if node.left.isDefined then _addToPath(node.left.get, tmp + node.value + "->", result) 16 | if node.right.isDefined then _addToPath(node.right.get, tmp + node.value + "->", result) 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/bst/ConvertSortedArraytoBST.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import tree.TreeNode 4 | 5 | object ConvertSortedArraytoBST { 6 | def sortedArrayToBST(nums: Array[Int]): TreeNode[Int] = nums.length match 7 | case 1 => TreeNode[Int](nums(0)) 8 | case 2 => new TreeNode[Int](nums(0), None, Option(TreeNode[Int](nums(1)))) 9 | case len => val mid = len / 2 10 | new TreeNode[Int](nums(mid), Option(sortedArrayToBST(nums.slice(0, mid))), Option(sortedArrayToBST(nums.slice(mid + 1, nums.length)))) 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/bst/InsertIntoaBST.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import tree.TreeNode 4 | 5 | object InsertIntoaBST { 6 | def insertIntoBST(root: TreeNode[Int], value: Int): TreeNode[Int] = 7 | value.compareTo(root.value) match 8 | case 0 => throw IllegalArgumentException(s"value $value already exists in the tree") 9 | case 1 => root.right match { 10 | case None => root.right = Option(TreeNode(value)) 11 | case Some(node) => insertIntoBST(node, value) 12 | } 13 | case -1 => root.left match { 14 | case None => root.left = Option(TreeNode(value)) 15 | case Some(node) => insertIntoBST(node, value) 16 | } 17 | root 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/bst/LowestCommonAncestorofBST.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import tree.TreeNode 4 | 5 | import scala.annotation.tailrec 6 | 7 | object LowestCommonAncestorofBST { 8 | @tailrec 9 | def lowestCommonAncestor(root: TreeNode[Int], p: TreeNode[Int], q: TreeNode[Int]): TreeNode[Int] = 10 | if root.value > p.value && root.value > q.value then lowestCommonAncestor(root.left.get, p, q) 11 | else if root.value < p.value && root.value < q.value then lowestCommonAncestor(root.right.get, q, q) 12 | else root 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/bst/SameTree.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import tree.TreeNode 4 | 5 | object SameTree { 6 | def isSameTree(p: TreeNode[Int], q: TreeNode[Int]): Boolean = _isSameTree(Option(p), Option(q)) 7 | 8 | private def _isSameTree(p: Option[TreeNode[Int]], q: Option[TreeNode[Int]]): Boolean = (p, q) match 9 | case (None, None) => true 10 | case (None, Some(_)) | (Some(_), None) => false 11 | case (Some(rp), Some(rq)) => rp.value == rq.value && _isSameTree(rp.right, rq.right) && _isSameTree(rp.left, rq.left) 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/bst/ValidateBinarySearchTree.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import tree.TreeNode 4 | 5 | object ValidateBinarySearchTree { 6 | def isValidBST(root: TreeNode[Int]): Boolean = (root.left, root.right) match 7 | case (Some(left), Some(right)) => left.value < root.value && root.value < right.value && isValidBST(left) && isValidBST(right) 8 | case (Some(_), None) | (None, Some(_)) => false 9 | case (None, None) => true 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/bucketsort/SortCharactersByFrequency.scala: -------------------------------------------------------------------------------- 1 | package bucketsort 2 | 3 | import scala.collection.mutable 4 | 5 | object SortCharactersByFrequency { 6 | def frequencySort(s: String): String = 7 | val (map, bucket) = (mutable.Map[Char, Int](), Array.fill(s.length + 1)(mutable.ListBuffer[Char]())) 8 | s.foreach { c => map.update(c, map.getOrElse(c, 0) + 1) } 9 | map.foreach((char, count) => bucket(count).addOne(char)) 10 | bucket.zipWithIndex 11 | .foldRight("") { case ((list, count), str) => 12 | str + list.foldLeft("") { case (result, char) => result + char.toString * count } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/bucketsort/TopKFrequentElements.scala: -------------------------------------------------------------------------------- 1 | package bucketsort 2 | 3 | import scala.collection.mutable 4 | 5 | object TopKFrequentElements { 6 | def topKFrequent(nums: Array[Int], k: Int): Array[Int] = 7 | nums. foldLeft (mutable.HashMap[Int, Int]()) { case (frequencyMap, num) => 8 | frequencyMap.update(num, frequencyMap.getOrElse(num, 0) + 1) 9 | frequencyMap 10 | }.foldLeft(Array.fill(nums.length + 1)(mutable.ListBuffer[Int]())) { case (bucket, (num, counts)) => 11 | bucket(counts).addOne(num) 12 | bucket 13 | }.foldRight(mutable.ListBuffer[Int]()) { case (result, nums) => 14 | result.addAll(nums) 15 | result 16 | }.takeRight(k) 17 | .toArray 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/bucketsort/TopKFrequentWords.scala: -------------------------------------------------------------------------------- 1 | package bucketsort 2 | 3 | import scala.collection.mutable 4 | 5 | object TopKFrequentWords { 6 | def topKFrequent(words: Array[String], k: Int): List[String] = 7 | words.foldLeft(mutable.HashMap[String, Int]()) { case (frequencyMap, word) => 8 | frequencyMap.update(word, frequencyMap.getOrElse(word, 0) + 1) 9 | frequencyMap 10 | }.foldLeft(Array.fill(words.length + 1)(mutable.ListBuffer[String]())) { case (bucket, (word, counts)) => 11 | bucket(counts).addOne(word) 12 | bucket 13 | }.foldRight(mutable.ListBuffer[String]()) { case (unsorted, result) => 14 | result.addAll(unsorted.sorted) 15 | result 16 | }.take(k) 17 | .toList 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/counting/ContainsDuplicate.scala: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | object ContainsDuplicate { 4 | def containsDuplicate(nums: Array[Int]): Boolean = 5 | val cache = collection.mutable.Set[Int]() 6 | nums.exists { i => cache.contains(i) || !cache.add(i) } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/counting/MajorityElement.scala: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | object MajorityElement { 4 | def majorityElement(nums: Array[Int]): Int = 5 | nums.foldLeft((nums(0), 0)) { 6 | case ((_, count), num) if count == 0 => (num, 1) 7 | case ((major, count), num) if major == num => (major, count + 1) 8 | case ((major, count), _) => (major, count - 1) 9 | }._1 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/counting/MajorityElement2.scala: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | object MajorityElement2 { 4 | def majorityElement(nums: Array[Int]): List[Int] = 5 | nums.foldLeft((nums(0), 0, nums(1), 0)) { 6 | case ((m1, c1, m2, c2), num) if num == m1 => (m1, c1 + 1, m2, c2) 7 | case ((m1, c1, m2, c2), num) if num == m2 => (m1, c1, m2, c2 + 1) 8 | case ((_, c1, m2, c2), num) if c1 == 0 => (num, 1, m2, c2) 9 | case ((m1, c1, _, c2), num) if c2 == 0 => (m1, c1, num, 1) 10 | case ((m1, c1, m2, c2), _) => (m1, c1 - 1, m2, c2 - 1) 11 | } match 12 | case (m1, _, m2, _) => List(m1, m2).filter(m => nums.count(_ == m) > nums.length / 3) 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/counting/RansomNote.scala: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | import scala.collection.mutable 4 | 5 | object RansomNote { 6 | def canConstruct(ransomNote: String, magazine: String): Boolean = 7 | val (rmap, mmap) = (mutable.HashMap[Char, Int](), mutable.HashMap[Char, Int]()) 8 | ransomNote.foreach(char => rmap.update(char, rmap.getOrElse(char, 0) + 1)) 9 | magazine.foreach(char => mmap.update(char, mmap.getOrElse(char, 0) + 1)) 10 | !rmap.exists { case (char, count) => count > mmap.getOrElse(char, 0) } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/dfs/BinaryTreeUpsideDown.scala: -------------------------------------------------------------------------------- 1 | package dfs 2 | 3 | import tree.TreeNode 4 | 5 | object BinaryTreeUpsideDown { 6 | def upsideDownBinaryTree(root: TreeNode[Int]): TreeNode[Int] = (root.left, root.right) match 7 | case (Some(left), Some(right)) => 8 | val result = if left.left.isDefined then upsideDownBinaryTree(left) else left 9 | left.left = Option(right) 10 | left.right = Option(root) 11 | root.left = None 12 | root.right = None 13 | result 14 | case (_, _) => root 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/dfs/PathSum.scala: -------------------------------------------------------------------------------- 1 | package dfs 2 | 3 | import tree.TreeNode 4 | 5 | object PathSum { 6 | def hasPathSum(root: TreeNode[Int], targetSum: Int): Boolean = 7 | root.value == targetSum 8 | || (root.left.isDefined && hasPathSum(root.left.get, targetSum - root.value)) 9 | || (root.right.isDefined && hasPathSum(root.right.get, targetSum - root.value)) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/dfs/PopulatingNextRightPointersinEachNode.scala: -------------------------------------------------------------------------------- 1 | package dfs 2 | 3 | object PopulatingNextRightPointersinEachNode { 4 | def connect(root: Node[Int]): Node[Int] = 5 | _connect(root.left, root.right) 6 | root 7 | 8 | private def _connect(node: Option[Node[Int]], next: Option[Node[Int]]): Unit = 9 | if node.isDefined then { 10 | node.get.next = next 11 | _connect(node.get.left, node.get.right) 12 | _connect(node.get.right, next.get.left) 13 | _connect(next.get.left, next.get.right) 14 | } 15 | } 16 | 17 | sealed class Node[T](var value: T, var left: Option[Node[T]], var next: Option[Node[T]], var right: Option[Node[T]]) -------------------------------------------------------------------------------- /src/main/scala/dfs/SumRoottoLeafNumbers.scala: -------------------------------------------------------------------------------- 1 | package dfs 2 | 3 | import tree.TreeNode 4 | 5 | object SumRoottoLeafNumbers { 6 | def sumNumbers(root: TreeNode[Int]): Int = _sumNumbers(root, 0) 7 | 8 | private def _sumNumbers(node: TreeNode[Int], preSum: Int): Int = 9 | val sum = preSum * 10 + node.value 10 | val left = if node.left.isDefined then _sumNumbers(node.left.get, sum) else 0 11 | val right = if node.right.isDefined then _sumNumbers(node.right.get, sum) else 0 12 | if left == 0 && right == 0 then sum else left + right 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/dfs/WordLadder.scala: -------------------------------------------------------------------------------- 1 | package dfs 2 | 3 | import scala.collection.mutable 4 | 5 | object WordLadder { 6 | def ladderLength(beginWord: String, endWord: String, wordList: List[String]): Int = 7 | _ladderLength(beginWord, endWord, mutable.HashSet().addAll(wordList), 0) 8 | 9 | private def _ladderLength(begin: String, end: String, words: mutable.HashSet[String], len: Int): Int = 10 | if begin.equals(end) then return len + 1 11 | words.filter(word => {1 == begin.toCharArray.zip(word.toCharArray).count { (c1, c2) => { c1 != c2 }}}) 12 | .map(word => { 13 | words.remove(word) 14 | val result = _ladderLength(word, end, words, 1 + len) 15 | words.add(word) 16 | result 17 | }) 18 | .filter(_!=0) 19 | .minOption 20 | .getOrElse(0) 21 | } 22 | -------------------------------------------------------------------------------- /src/main/scala/dp/BestTimetoBuyandSellStock3.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object BestTimetoBuyandSellStock3 { 4 | def maxProfit(prices: Array[Int]): Int = _maxProfit(prices, 0, 4, Array.fill(prices.length, 5)(-1)) 5 | 6 | private def _maxProfit(prices: Array[Int], day: Int, txn: Int, cache: Array[Array[Int]]): Int = 7 | if day == prices.length then 0 8 | else if txn == 0 then 0 9 | else { 10 | if cache(day)(txn) == -1 then { 11 | val notxn = _maxProfit(prices, day + 1, txn, cache) 12 | val yestxn = if txn % 2 == 0 then _maxProfit(prices, day + 1, txn - 1, cache) - prices(day) 13 | else _maxProfit(prices, day + 1, txn - 1, cache) + prices(day) 14 | cache(day)(txn) = notxn.max(yestxn) 15 | } 16 | cache(day)(txn) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/dp/ClimbingStairs.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object ClimbingStairs { 4 | def climbStairs(n: Int): Int = n match 5 | case n if n <= 2 => n 6 | case _ => (2 until n).foldLeft((1, 2)) { case ((n_2, n_1), _) => (n_1, n_2 + n_1) }._2 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/dp/CoinChange2.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object CoinChange2 { 4 | def change(amount: Int, coins: Array[Int]): Int = 5 | _change(0, amount, coins, Array.tabulate[Int](coins.length + 1, amount + 1)((_, _) => -1)) 6 | 7 | private def _change(i: Int, amount: Int, coins: Array[Int], cache: Array[Array[Int]]): Int = 8 | if amount == 0 then 1 9 | else if amount < 0 || i >= coins.length then 0 10 | else if cache(i)(amount) != -1 then cache(i)(amount) 11 | else { 12 | cache(i)(amount) = _change(i + 1, amount, coins, cache) + _change(i, amount - coins(i), coins, cache) 13 | cache(i)(amount) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/dp/DecodeWays.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object DecodeWays { 4 | def numDecodings(s: String): Int = 5 | val cache = Array.fill[Int](if s.length < 2 then 2 else s.length)(0) 6 | cache(0) = 1 7 | cache(1) = if s.charAt(0) == '0' then 1 else 2 8 | for (i <- 2 until s.length) { 9 | val (first, second) = (s.substring(i, i + 1).toInt, s.substring(i - 1, i + 1).toInt) 10 | if first >= 1 && first <= 9 then cache(i) = cache(i) + cache(i - 1) 11 | if second > 10 && second <= 26 then cache(i) = cache(i) + cache(i - 2) 12 | } 13 | cache(s.length - 1) 14 | } -------------------------------------------------------------------------------- /src/main/scala/dp/DistinctSubsequences.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object DistinctSubsequences { 4 | def numDistinct(s: String, t: String): Int = _numDistinct(s, 0, t, 0, Array.fill(s.length, t.length)(-1)) 5 | 6 | private def _numDistinct(s: String, i: Int, t: String, j: Int, cache: Array[Array[Int]]): Int = 7 | if j >= t.length then 1 8 | else if i >= s.length || (s.length - i) < (t.length - j) then 0 else { 9 | if cache(i)(j) == -1 then 10 | cache(i)(j) = s.drop(i).zipWithIndex.map { case (char, k) => 11 | if char == t(j) then _numDistinct(s, i + k + 1, t, j + 1, cache) else 0 12 | }.sum 13 | cache(i)(j) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/dp/JumpGame.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object JumpGame { 4 | def canJump(nums: Array[Int]): Boolean = _canJump(0, nums.length, nums, Array.fill[Option[Boolean]](nums.length)(None)) 5 | 6 | def _canJump(current: Int, n: Int, nums: Array[Int], cache: Array[Option[Boolean]]): Boolean = 7 | if cache(current).nonEmpty then cache(current).get 8 | else if nums(current) + current > n then true 9 | else (1 to nums(current)).foldLeft(false) { case (result, i) => 10 | cache(current + i) = Some(_canJump(current + i, n, nums, cache)) 11 | result || cache(current + i).get 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/dp/LongestPalindromicSubsequence.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object LongestPalindromicSubsequence { 4 | def longestPalindromeSubseq(s: String): Int = 5 | _longestPalindromeSubseq(0, s.length - 1, s, Array.tabulate[Int](s.length + 1, s.length + 1)((_, _) => -1)) 6 | 7 | private def _longestPalindromeSubseq(b: Int, e: Int, s: String, cache: Array[Array[Int]]): Int = 8 | if b > e then 0 9 | else if b == e then 1 10 | else if cache(b)(e) != -1 then cache(b)(e) 11 | else { 12 | cache(b)(e) = if s.charAt(b) == s.charAt(e) then 2 + _longestPalindromeSubseq(b + 1, e - 1, s, cache) 13 | else _longestPalindromeSubseq(b + 1, e, s, cache).max(_longestPalindromeSubseq(b, e - 1, s, cache)) 14 | cache(b)(e) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/dp/LongestPalindromicSubstring.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object LongestPalindromicSubstring { 4 | def longestPalindrome(s: String): String = 5 | val cache = Array.ofDim[Boolean](s.length, s.length) 6 | var result = "" 7 | for (i <- s.length - 1 to 0 by -1; j <- i until s.length) { 8 | cache(i)(j) = s.charAt(i) == s.charAt(j) && (j - i < 3 || cache(i + 1)(j - 1)) 9 | if cache(i)(j) && j - i + 1 > result.length then result = s.substring(i, j + 1) 10 | } 11 | result 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/scala/dp/MaximumSubarray.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import scala.math.Ordering 4 | 5 | object MaximumSubarray { 6 | def maxSubArray(nums: Array[Int]): Int = 7 | for (i <- 1 until nums.length) nums(i) = nums(i).max(nums(i) + nums(i - 1)) 8 | nums.reduceLeft(Ordering[Int].max) 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala/dp/MinimumPathSum.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object MinimumPathSum { 4 | def minPathSum(grid: Array[Array[Int]]): Int = 5 | for (i <- grid.indices; j <- grid(0).indices) { 6 | (i, j) match 7 | case (0, 0) => grid(i)(j) = grid(i)(j) 8 | case (0, _) => grid(i)(j) = grid(i)(j) + grid(i)(j - 1) 9 | case (_, 0) => grid(i)(j) = grid(i)(j) + grid(i - 1)(j) 10 | case _ => grid(i)(j) = grid(i)(j) + grid(i - 1)(j).min(grid(i)(j - 1)) 11 | } 12 | grid.last.last 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/dp/TargetSum.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object TargetSum { 4 | def findTargetSumWays(nums: Array[Int], target: Int): Int = 5 | val max = nums.sum 6 | _findTargetSumWays(0, target, max, nums, Array.tabulate[Int](nums.length + 1, max * 2 + target + 1)((_, _) => -1)) 7 | 8 | private def _findTargetSumWays(i: Int, amount: Int, max: Int, nums: Array[Int], cache: Array[Array[Int]]): Int = 9 | if i == nums.length then { 10 | if amount == 0 then 1 else 0 11 | } else if cache(i)(max + amount) != -1 then cache(i)(max + amount) 12 | else { 13 | cache(i)(max + amount) = _findTargetSumWays(i + 1, amount + nums(i), max, nums, cache) 14 | + _findTargetSumWays(i + 1, amount - nums(i), max, nums, cache) 15 | cache(i)(max + amount) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/dp/Triangle.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | object Triangle { 4 | def minimumTotal(triangle: List[List[Int]]): Int = 5 | _minimumTotal(0, 0, triangle, Array.fill(triangle.length, triangle.last.length)(-1)) 6 | 7 | private def _minimumTotal(level: Int, i: Int, triangle: List[List[Int]], cache: Array[Array[Int]]): Int = 8 | if level == triangle.size then 0 9 | else { 10 | if cache(level)(i) == -1 then 11 | cache(level)(i) = triangle(level)(i) 12 | + _minimumTotal(level + 1, i, triangle, cache).min(_minimumTotal(level + 1, i + 1, triangle, cache)) 13 | cache(level)(i) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/fastslowpointers/LinkedListCycle.scala: -------------------------------------------------------------------------------- 1 | package fastslowpointers 2 | 3 | import linkedlist.LinkedListNode 4 | 5 | object LinkedListCycle { 6 | def hasCycle(head: LinkedListNode[Int]): Boolean = 7 | var (fast, slow) = (head, head) 8 | while fast.next.isDefined && slow.next.isDefined do { 9 | fast = fast.next.get 10 | if (fast.next.isDefined) fast = fast.next.get 11 | slow = slow.next.get 12 | if (fast == slow) return true 13 | } 14 | false 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/fastslowpointers/LinkedListCycle2.scala: -------------------------------------------------------------------------------- 1 | package fastslowpointers 2 | 3 | import linkedlist.LinkedListNode 4 | 5 | object LinkedListCycle2 { 6 | def detectCycle(head: LinkedListNode[Int]): Option[LinkedListNode[Int]] = 7 | var (fast, slow, isCycle) = (head, head, false) 8 | while fast.next.isDefined && slow.next.isDefined && !isCycle do 9 | fast = fast.next.get 10 | if (fast.next.isDefined) { 11 | fast = fast.next.get 12 | slow = slow.next.get 13 | if (fast == slow) isCycle = true 14 | } 15 | 16 | if !isCycle then None 17 | else { 18 | fast = head 19 | while fast != slow do { 20 | fast = fast.next.get 21 | slow = slow.next.get 22 | } 23 | Option(fast) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/fastslowpointers/MiddleoftheLinkedList.scala: -------------------------------------------------------------------------------- 1 | package fastslowpointers 2 | 3 | import linkedlist.LinkedListNode 4 | 5 | object MiddleoftheLinkedList { 6 | def middleNode(head: LinkedListNode[Int]): LinkedListNode[Int] = 7 | var (fast, slow) = (head, head) 8 | while fast.next.isDefined do { 9 | fast = fast.next.get 10 | if (fast.next.isDefined) fast = fast.next.get 11 | slow = slow.next.get 12 | } 13 | slow 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/graph/CourseSchedule.scala: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import scala.collection.mutable 4 | 5 | object CourseSchedule { 6 | def canFinish(numCourses: Int, prerequisites: Array[Array[Int]]): Boolean = 7 | val nodes = new Array[Node[Int]](numCourses) 8 | for (i <- 0 until numCourses) nodes(i) = Node(i) 9 | prerequisites.foreach(p => nodes(p(0)).neighbors.addOne(nodes(p(1)))) 10 | !nodes.exists(_canFinish(_, mutable.HashSet[Int]())) 11 | 12 | private def _canFinish(node: Node[Int], visited: mutable.HashSet[Int]): Boolean = 13 | visited.contains(node.value) || { 14 | visited.addOne(node.value) 15 | node.neighbors.exists(_canFinish(_, visited)) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/greedy/BestTimetoBuyandSellStock2.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | object BestTimetoBuyandSellStock2 { 4 | def maxProfit(prices: Array[Int]): Int = 5 | prices.zipWithIndex.foldLeft(0) { case (r, (v, i)) => 6 | if (i + 1) < prices.length && v < prices(i + 1) then r + prices(i + 1) - v else r 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/greedy/Candy.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | // 135. Candy 4 | object Candy { 5 | def candy(ratings: Array[Int]): Int = 6 | ratings.zipWithIndex.foldLeft((0, 0)) { case ((r, p), (v, i)) => 7 | if i == 0 then (1, 1) else { 8 | if v > ratings(i - 1) then (r + p + 1, p + 1) else { 9 | if p > 1 then (r + 1, 1) else { 10 | var (acc, pi) = (0, i) 11 | while pi > 0 && ratings(pi - 1) > ratings(pi) do { 12 | pi = pi - 1 13 | acc = acc + 1 14 | } 15 | (r + acc + 1, 1) 16 | } 17 | } 18 | } 19 | }._1 20 | } 21 | -------------------------------------------------------------------------------- /src/main/scala/greedy/CourseSchedule3.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | import heap.PriorityQueue 4 | 5 | object CourseSchedule3 { 6 | def scheduleCourse(courses: Array[Array[Int]]): Int = 7 | courses.sortBy(_(1)) 8 | val heap = new PriorityQueue[Int]() 9 | var days = 0 10 | for (course <- courses) { 11 | days = days + course(0) 12 | heap.offer(course(0), course(0)) 13 | if (days > course(1)) then days = days - heap.poll() 14 | } 15 | heap.length() 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/greedy/GasStation.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | object GasStation { 4 | def canCompleteCircuit(gas: Array[Int], cost: Array[Int]): Int = 5 | gas.zip(cost).zipWithIndex.find { case ((g, c), i) => 6 | if g - c < 0 then false else { 7 | var (left, next) = (g - c, if i + 1 >= gas.length then 0 else i + 1) 8 | while left >= 0 && next != i do { 9 | left = left + gas(next) - cost(next) 10 | next = if next + 1 >= gas.length then 0 else next + 1 11 | } 12 | left >= 0 13 | } 14 | }.getOrElse(((0, 0), -1))._2 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/greedy/LargestNumber.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | // 179. Largest Number 4 | object LargestNumber { 5 | def largestNumber(nums: Array[Int]): String = 6 | nums.sortWith { case (n1, n2) => s"$n1$n2" > s"$n2$n1" } 7 | .foldLeft("") { case (r, n) => s"$r$n" } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/greedy/WildcardMatching.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | import scala.annotation.tailrec 4 | 5 | // 44. Wildcard Matching 6 | object WildcardMatching { 7 | @tailrec 8 | def isMatch(s: String, p: String): Boolean = 9 | if s.isEmpty && p.isEmpty then true 10 | else if s.isEmpty || p.isEmpty then false 11 | else p(0) match 12 | case '?' => isMatch(s.substring(1), p.substring(1)) 13 | case '*' => var curr = 0 14 | while curr < s.length && s(0) == s(curr) do curr = curr + 1 15 | isMatch(s.substring(curr), p.substring(1)) 16 | case _ => if p(0) == s(0) then isMatch(s.substring(1), p.substring(1)) else false 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/hashmap/BrickWall.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import scala.collection.mutable 4 | 5 | object BrickWall { 6 | def leastBricks(wall: List[List[Int]]): Int = 7 | val cache = mutable.Map[Int, Int]() 8 | wall.foreach(_.dropRight(1) 9 | .foldLeft(0) { case (sum, w) => 10 | cache.update(sum + w, cache.getOrElse(sum + w, 0) + 1) 11 | sum + w 12 | }) 13 | wall.length - (if cache.isEmpty then 0 else cache.values.max) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/hashmap/BullsandCows.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import scala.collection.mutable 4 | 5 | object BullsandCows { 6 | def getHint(secret: String, guess: String): String = 7 | val (scache, gcache) = (mutable.HashMap[Char, Int](), mutable.HashMap[Char, Int]()) 8 | val bull = secret.toCharArray.zip(guess.toCharArray).count { 9 | case (s, g) if s == g => true 10 | case (s, g) => 11 | scache.update(s, scache.getOrElse(s, 1)) 12 | gcache.update(g, gcache.getOrElse(g, 1)) 13 | false 14 | } 15 | val cow = scache.map { case (k, v) => v.min(gcache.getOrElse(k, 0)) }.sum 16 | s"${bull}A${cow}B" 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/hashmap/FirstUniqChar.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import scala.collection.mutable 4 | 5 | object FirstUniqChar { 6 | def firstUniqChar(s: String): Int = 7 | val cache = mutable.Map[Char, Int]() 8 | s.toArray.foreach(c => cache.update(c, cache.getOrElse(c, 0) + 1)) 9 | s.toArray.find(cache(_) == 1) match 10 | case Some(result) => s.indexOf(result) 11 | case _ => -1 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/hashmap/HappyNumber.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import scala.annotation.tailrec 4 | 5 | object HappyNumber { 6 | def isHappy(n: Int): Boolean = isHappyInernal(n, Set.empty[Int]) 7 | 8 | @tailrec 9 | private def isHappyInernal(n: Int, cache: Set[Int]): Boolean = n match 10 | case num if num == 1 => true 11 | case num if cache.contains(num) => false 12 | case num => isHappyInernal(num.toString.map(c => (c - '0') * (c - '0')).sum, cache + num) 13 | } -------------------------------------------------------------------------------- /src/main/scala/hashmap/InsertDeleteGetRandomO1.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import scala.collection.mutable 4 | 5 | class InsertDeleteGetRandomO1() { 6 | private val map = mutable.Map[Int, Int]() 7 | private val array = mutable.ArrayBuffer[Int]() 8 | private val random = new scala.util.Random 9 | 10 | def insert(value: Int): Boolean = 11 | if map.contains(value) then false 12 | else { 13 | map.put(value, array.length) 14 | array.addOne(value) 15 | true 16 | } 17 | 18 | def remove(value: Int): Boolean = 19 | if !map.contains(value) then false 20 | else { 21 | array(map(value)) = array(array.length - 1) 22 | array.dropRight(1) 23 | true 24 | } 25 | 26 | def getRandom: Int = array(random.nextInt(array.length)) 27 | } 28 | -------------------------------------------------------------------------------- /src/main/scala/hashmap/IsomorphicStrings.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import scala.collection.mutable 4 | 5 | object IsomorphicStrings { 6 | def isIsomorphic(s: String, t: String): Boolean = 7 | val (smap, tmap) = (mutable.Map[Char, Char](), mutable.Map[Char, Char]()) 8 | !s.toCharArray.zip(t.toCharArray).exists { case (schar, tchar) => 9 | (smap.get(schar), tmap.get(tchar)) match 10 | case (Some(_), None) | (None, Some(_)) => true 11 | case (Some(char1), Some(char2)) => char1 != tchar || char2 != schar 12 | case (None, None) => smap.put(schar, tchar) 13 | tmap.put(tchar, schar) 14 | false 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/hashmap/TwoSum.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import scala.collection.mutable 4 | 5 | object TwoSum { 6 | def twoSum(nums: Array[Int], target: Int): Array[Int] = 7 | val cache = mutable.Map[Int, Int]() 8 | nums.zipWithIndex.find { case (value, index) => cache.get(target - value) match 9 | case Some(_) => true 10 | case _ => cache.put(value, index).isDefined 11 | } match 12 | case Some((num, index)) => Array(cache(target - num), index) 13 | case _ => throw new IllegalArgumentException("invalid parameter, no valid result!") 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/heap/KthLargestElementinanArray.scala: -------------------------------------------------------------------------------- 1 | package heap 2 | 3 | object KthLargestElementinanArray { 4 | def findKthLargest(nums: Array[Int], k: Int): Int = 5 | val pq = new PriorityQueue[Int](unique = false) 6 | nums.foreach(num => pq.offer(num, num)) 7 | (0 until k).map(_ => pq.poll()).last 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/heap/RelativeRanks.scala: -------------------------------------------------------------------------------- 1 | package heap 2 | 3 | object RelativeRanks { 4 | def findRelativeRanks(score: Array[Int]): Array[String] = 5 | val (pq, buffer) = (new PriorityQueue[Int](score.length), Array.ofDim[String](score.length)) 6 | score.zipWithIndex.foreach { case (num, index) => pq.offer(index, num) } 7 | for (n <- buffer.indices) { 8 | buffer(pq.poll()) = n match 9 | case 0 => "Gold Medal" 10 | case 1 => "Silver Medal" 11 | case 2 => "Bronze Medal" 12 | case n => (n + 1).toString 13 | } 14 | buffer 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/heap/UglyNumber2.scala: -------------------------------------------------------------------------------- 1 | package heap 2 | 3 | object UglyNumber2 { 4 | def nthUglyNumber(n: Int): Int = n match 5 | case s if s < 7 => s 6 | case _ => val (pq, factors) = (new PriorityQueue[Int](n * 2, (a, b) => a < b), Array(2, 3, 5)) 7 | var (last, count) = (1, 1) 8 | while count < n do { 9 | count = count + 1 10 | factors.foreach(n => pq.offer(n * last, n * last)) 11 | last = pq.poll() 12 | } 13 | last 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/linkedlist/CopyListwithRandomPointer.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | import scala.collection.mutable 4 | 5 | object CopyListwithRandomPointer { 6 | def copyRandomList(head: LinkedListWithPointer[Int]): LinkedListWithPointer[Int] = 7 | val cache = mutable.HashMap[LinkedListWithPointer[Int], LinkedListWithPointer[Int]]() 8 | 9 | var node = Option(head) 10 | while node.isDefined do 11 | cache.put(node.get, new LinkedListWithPointer[Int](node.get.value, None, None)) 12 | node = node.get.next 13 | 14 | node = Option(head) 15 | while node.isDefined do 16 | cache(node.get).next = node.get.next.map { key => cache(key) } 17 | cache(node.get).random = node.get.random.map { key => cache(key) } 18 | node = node.get.next 19 | 20 | cache(head) 21 | } 22 | -------------------------------------------------------------------------------- /src/main/scala/linkedlist/IntersectionofTwoLinkedLists.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | object IntersectionofTwoLinkedLists { 4 | def getIntersectionNode(headA: LinkedListNode[Int], headB: LinkedListNode[Int]): Option[LinkedListNode[Int]] = 5 | val diff = headA.getLen() - headB.getLen() 6 | var (pl, ps) = if diff > 0 then (Option(headA), Option(headB)) else (Option(headB), Option(headA)) 7 | for (n <- 0 until diff.abs) pl = pl.get.next 8 | while pl != ps && pl.isDefined do 9 | pl = pl.get.next 10 | ps = ps.get.next 11 | pl 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/linkedlist/PartitionList.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | object PartitionList { 4 | def partition(head: LinkedListNode[Int], x: Int): LinkedListNode[Int] = 5 | var (smallp, bigp, tmp) = (new LinkedListNode[Int](0, None), new LinkedListNode[Int](0, None), Option(head)) 6 | val (smallhead, bighead) = (smallp, bigp) 7 | while tmp.isDefined do { 8 | if tmp.get.value < x then { 9 | smallp.next = tmp 10 | smallp = smallp.next.get 11 | } else { 12 | bigp.next = tmp 13 | bigp = bigp.next.get 14 | } 15 | tmp = tmp.get.next 16 | } 17 | bigp.next = None 18 | smallp.next = Option(bighead.next.get) 19 | smallhead.next.get 20 | } 21 | -------------------------------------------------------------------------------- /src/main/scala/linkedlist/RemoveDuplicatesfromSortedList.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | object RemoveDuplicatesfromSortedList { 4 | def deleteDuplicates(head: LinkedListNode[Int]): LinkedListNode[Int] = 5 | var first = head 6 | while first.next.isDefined do 7 | if first.value == first.next.get.value then first.next = first.next.get.next 8 | else first = first.next.get 9 | head 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/main/scala/linkedlist/RemoveDuplicatesfromSortedListII.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | object RemoveDuplicatesfromSortedListII { 4 | def deleteDuplicates(head: LinkedListNode[Int]): LinkedListNode[Int] = 5 | val temphead = new LinkedListNode[Int](-1, Option(head)) 6 | var (pre, curr) = (temphead, Option(head)) 7 | while curr.isDefined do { 8 | while curr.get.next.isDefined && curr.get.value == curr.get.next.get.value do curr = curr.get.next 9 | if pre.next.get.value == curr.get.value then pre = pre.next.get 10 | else pre.next = curr.get.next 11 | curr = curr.get.next 12 | } 13 | temphead.next.get 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/linkedlist/RemoveNthFromEnd.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | object RemoveNthFromEnd { 4 | def removeNthFromEnd(head: LinkedListNode[Int], n: Int): LinkedListNode[Int] = 5 | val len = head.getLen() 6 | n match 7 | case num if num > len => throw IllegalArgumentException("n is larger than the length of head") 8 | case num if num == len => head.next.get 9 | case _ => 10 | var (dummy, fast, slow) = (head, Option(head), Option(head)) 11 | (0 to n).foreach(_ => fast = fast.get.next) 12 | while fast.isDefined do 13 | fast = fast.get.next 14 | slow = slow.get.next 15 | slow.get.next = slow.get.next.get.next 16 | dummy 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/linkedlist/ReorderList.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | object ReorderList { 4 | def reorderList(head: LinkedListNode[Int]): Unit = 5 | var (p1, p2) = (head, head) 6 | while p1.next.isDefined && p2.next.isDefined do 7 | p1 = p1.next.get 8 | p2 = p2.next.get.next.get 9 | 10 | val (premid, precurr) = (p1, p1.next.get) 11 | while precurr.next.isDefined do 12 | val curr = precurr.next.get 13 | precurr.next = curr.next 14 | curr.next = premid.next 15 | premid.next = Option(curr) 16 | 17 | p1 = head 18 | p2 = premid.next.get 19 | while p1 != premid do 20 | premid.next = p2.next 21 | p2.next = p1.next 22 | p1.next = Option(p2) 23 | p1 = p2.next.get 24 | if premid.next.isDefined then p2 = premid.next.get 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/linkedlist/ReverseList.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | object ReverseList { 4 | def reverseList(head: LinkedListNode[Int]): LinkedListNode[Int] = head.next match 5 | case None => head 6 | case _ => var (pre, curr) = (head, head.next.get) 7 | while curr.next.isDefined do 8 | val next = curr.next.get 9 | curr.next = Option(pre) 10 | pre = curr 11 | curr = next 12 | curr.next = Option(pre) 13 | curr 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/linkedlist/RotateList.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | import scala.annotation.tailrec 4 | 5 | object RotateList { 6 | def rotateRight(head: LinkedListNode[Int], k: Int): LinkedListNode[Int] = 7 | var offset = k % head.getLen() 8 | var (kpoint, tail) = (head, Option(head)) 9 | 10 | while tail.get.next.isDefined do 11 | offset = offset - 1 12 | if offset == 0 then kpoint = tail.get 13 | tail = tail.get.next 14 | 15 | val newhead = kpoint.next.get 16 | kpoint.next = None 17 | tail.get.next = Some(head) 18 | newhead 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/math/ExcelSheetColumnNumber.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | object ExcelSheetColumnNumber { 4 | def titleToNumber(columnTitle: String): Int = 5 | columnTitle.foldLeft(0) { case (sum, char) => sum * 26 + (char - 'A'.toInt + 1) } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/scala/math/ExcelSheetColumnTitle.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | object ExcelSheetColumnTitle { 4 | def convertToTitle(columnNumber: Int): String = columnNumber match 5 | case 0 => "" 6 | case num => convertToTitle(num / 26) + ((num % 26) + 64).toChar 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/math/FactorialTrailingZeroes.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | object FactorialTrailingZeroes { 4 | def trailingZeroes(n: Int): Int = n match 5 | case 0 => 0 6 | case num => num / 5 + trailingZeroes(num / 5) 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/math/Integer2Roman.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | object Integer2Roman { 4 | def intToRoman(num: Int): String = 5 | List((1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), (100, "C"), (90, "XC"), (50, "L"), (40, "XL"), (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I")) 6 | .find { case (int, _) => num >= int } 7 | .map { case (int, roman) => if num == int then roman else roman + intToRoman(num - int) } 8 | .get 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala/math/PlusOne.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | object PlusOne { 4 | def plusOne(digits: Array[Int]): Array[Int] = 5 | digits.zipWithIndex.foldRight(1) { 6 | case ((_, _), carry) if carry == 0 => 0 7 | case ((n, i), _) if n < 9 => digits(i) = n + 1; 0 8 | case ((n, i), _) if n == 9 => digits(i) = 0; 1 9 | } match 10 | case 0 => digits 11 | case _ => Array(1) ++ digits 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/math/PowXn.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | object PowXn { 4 | def myPow(x: Double, n: Int): Double = (x, n) match 5 | case (in, pow) if pow == 1 => in 6 | case (in, pow) if pow < 0 => myPow(1 / in, -pow) 7 | case (in, pow) if pow % 2 == 0 => myPow(in * in, pow / 2) 8 | case (in, pow) => in * myPow(in * in, (pow - 1) / 2) 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala/math/Roman2Integer.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | object Roman2Integer { 4 | def romanToInt(s: String): Int = 5 | List((1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), (100, "C"), (90, "XC"), (50, "L"), (40, "XL"), (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I")) 6 | .find { case (_, roman) => s.startsWith(roman) } 7 | .map { case (int, roman) => if s.equals(roman) then int else int + romanToInt(s.drop(roman.length)) } 8 | .get 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala/math/UniqueBinarySearchTrees.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | object UniqueBinarySearchTrees { 4 | def numTrees(n: Int): Int = n match 5 | case 0 => 1 6 | case n if n <= 2 => n 7 | case n => (0 until n).foldRight(0) { case (num, acc) => acc + numTrees(num) * numTrees(n - 1 - num) } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/matrix/RotateImage.scala: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | object RotateImage { 4 | def rotate(matrix: Array[Array[Int]]): Unit = 5 | for (r <- 0 until matrix.length / 2; c <- matrix(0).indices) swap(matrix, r, c, matrix.length - 1 - r, c) 6 | for (r <- 0 until (matrix.length - 1); c <- (r + 1) until matrix(0).length) swap(matrix, r, c, c, r) 7 | 8 | private def swap(matrix: Array[Array[Int]], r1: Int, c1: Int, r2: Int, c2: Int): Unit = 9 | val tmp = matrix(r1)(c1) 10 | matrix(r1)(c1) = matrix(r2)(c2) 11 | matrix(r2)(c2) = tmp 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/matrix/Searcha2DMatrix.scala: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | object Searcha2DMatrix { 4 | def searchMatrix(matrix: Array[Array[Int]], target: Int): Boolean = 5 | val (rows, cols) = (matrix.length, matrix(0).length) 6 | var (mini, maxi) = (0, rows * cols - 1) 7 | while mini <= maxi do 8 | val midi = mini + (maxi - mini) / 2 9 | if target > matrix(midi / cols)(midi % cols) then mini = midi + 1 10 | else if target < matrix(midi / cols)(midi % cols) then maxi = midi - 1 11 | else return true 12 | false 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/matrix/SetMatrixZeroes.scala: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | object SetMatrixZeroes { 4 | def setZeroes(matrix: Array[Array[Int]]): Unit = 5 | var (row0, col0) = (false, false) 6 | for (r <- matrix.indices; c <- matrix(0).indices) 7 | if matrix(r)(c) == 0 then { 8 | matrix(0)(c) = 0 9 | matrix(r)(0) = 0 10 | if r == 0 then row0 = true 11 | if c == 0 then col0 = true 12 | } 13 | for (r <- 1 until matrix.length; c <- 1 until matrix(0).length) 14 | if matrix(0)(c) == 0 || matrix(r)(0) == 0 then matrix(r)(c) = 0 15 | if row0 then for (r <- matrix.indices) matrix(r)(0) = 0 16 | if col0 then for (c <- matrix(0).indices) matrix(0)(c) = 0 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/matrix/SpiralMatrix2.scala: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | object SpiralMatrix2 { 4 | def generateMatrix(n: Int): Array[Array[Int]] = 5 | val result = Array.ofDim[Int](n, n) 6 | var (i, top, bottom, left, right) = (1, 0, n - 1, 0, n - 1) 7 | while i <= n * n do { 8 | for (j <- left to right if i <= n * n) { result(top)(j) = i; i = i + 1 } 9 | top = top + 1 10 | for (j <- top to bottom if i <= n * n) { result(j)(right) = i; i = i + 1 } 11 | right = right - 1 12 | for (j <- right to left by -1 if i <= n * n) { result(bottom)(j) = i; i = i + 1 } 13 | bottom = bottom - 1 14 | for (j <- bottom to top by -1 if i <= n * n) { result(j)(left) = i; i = i + 1 } 15 | left = left + 1 16 | } 17 | result 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/matrix/ValidSudoku.scala: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | import scala.collection.mutable 4 | 5 | object ValidSudoku { 6 | def isValidSudoku(board: Array[Array[Char]]): Boolean = 7 | val (rows, cols, sqrs) = (List.fill(9)(mutable.HashSet[Char]()), List.fill(9)(mutable.HashSet[Char]()), List.fill(9)(mutable.HashSet[Char]())) 8 | !board.zipWithIndex.exists { case (line, row) => 9 | line.zipWithIndex.exists { 10 | case ('.', _) => false 11 | case (char, col) => !rows(row).add(char) || !cols(col).add(char) || !sqrs((row / 3) * 3 + col / 3).add(char) 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/monotonicstack/LargestRectangleinHistogram.scala: -------------------------------------------------------------------------------- 1 | package monotonicstack 2 | 3 | import stack.MinStack 4 | 5 | object LargestRectangleinHistogram { 6 | def largestRectangleArea(heights: Array[Int]): Int = 7 | val stack = new MinStack[Integer]() 8 | var result = 0 9 | for (i <- 0 to heights.length) { 10 | val h = if i == heights.length then 0 else heights(i) 11 | while !stack.isEmpty && h < heights(stack.top()) do 12 | val ch = heights(stack.pop()) 13 | val pi: Integer = if stack.isEmpty then -1 else stack.top() 14 | result = result.max(ch * (i - pi - 1)) 15 | stack.push(i) 16 | } 17 | result 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/monotonicstack/NextGreaterElement.scala: -------------------------------------------------------------------------------- 1 | package monotonicstack 2 | 3 | object NextGreaterElement { 4 | def nextGreaterElement(nums1: Array[Int], nums2: Array[Int]): Array[Int] = 5 | val map = scala.collection.mutable.Map[Int, Int]() 6 | val stack = scala.collection.mutable.Stack[Int]() 7 | 8 | for (num <- nums2) 9 | while (stack.nonEmpty && stack.top < num) 10 | map += (stack.pop() -> num) 11 | stack.push(num) 12 | 13 | nums1.map(num => map.getOrElse(num, -1)) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/monotonicstack/NextGreaterElement2.scala: -------------------------------------------------------------------------------- 1 | package monotonicstack 2 | 3 | object NextGreaterElement2 { 4 | def nextGreaterElements(nums: Array[Int]): Array[Int] = 5 | val result = Array.fill(nums.length)(-1) 6 | val stack = scala.collection.mutable.Stack[Int]() 7 | for (i <- 0 until nums.length * 2) { 8 | while (stack.nonEmpty && nums(stack.top) < nums(i % nums.length)) 9 | result(stack.pop()) = nums(i % nums.length) 10 | stack.push(i % nums.length) 11 | } 12 | result 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/monotonicstack/NextGreaterElement3.scala: -------------------------------------------------------------------------------- 1 | package monotonicstack 2 | 3 | object NextGreaterElement3 { 4 | def nextGreaterElement(n: Int): Int = 5 | val stack = scala.collection.mutable.Stack[Int]() 6 | val str = n.toString 7 | for (i <- str.length - 1 to 0 by -1) { 8 | if stack.nonEmpty && str.charAt(stack.top) > str.charAt(i) then { 9 | val result = str.substring(0, i) + str.charAt(stack.pop()) 10 | stack.push(i) 11 | return (result + stack.map(str.charAt).sorted.mkString).toInt 12 | } 13 | stack.push(i) 14 | } 15 | -1 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/number/PalindromeNumber.scala: -------------------------------------------------------------------------------- 1 | package number 2 | 3 | object PalindromeNumber { 4 | def isPalindrome(x: Int): Boolean = 5 | var (org, result) = (x, 0) 6 | while org > result do 7 | result = result * 10 8 | result = result + org % 10 9 | org = org / 10 10 | org == result || org == result / 10 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/number/ReverseInteger.scala: -------------------------------------------------------------------------------- 1 | package number 2 | 3 | object ReverseInteger { 4 | def reverse(x: Int): Int = 5 | var (org, result) = (x, 0) 6 | while org > 0 do 7 | result = result * 10 8 | result = result + org % 10 9 | org = org / 10 10 | result 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/orderedset/MinimumAbsoluteSumDifference.scala: -------------------------------------------------------------------------------- 1 | package orderedset 2 | 3 | import scala.collection.mutable 4 | 5 | object MinimumAbsoluteSumDifference { 6 | def minAbsoluteSumDiff(nums1: Array[Int], nums2: Array[Int]): Int = 7 | val cache = mutable.TreeSet[Int]().addAll(nums1) 8 | nums1.zip(nums2).foldLeft((0L, 0)) { case ((sum, maxdiff), (n1, n2)) => 9 | val diff1 = Math.abs(cache.minAfter(n2).getOrElse(Int.MinValue) - n2) 10 | val diff2 = Math.abs(cache.maxBefore(n2).getOrElse(Int.MaxValue) - n2) 11 | val diff = Math.abs(n1 - n2) 12 | (sum + diff, maxdiff.max(diff - diff1.min(diff2))) 13 | } match 14 | case (sum, maxdiff) => ((sum - maxdiff.toLong) % (Math.pow(10, 9).toInt + 7)).toInt 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/orderedset/MyCalendar.scala: -------------------------------------------------------------------------------- 1 | package orderedset 2 | 3 | import scala.collection.mutable 4 | 5 | class MyCalendar { 6 | private[this] val cache = mutable.TreeMap[Int, Int]() 7 | 8 | def book(start: Int, end: Int): Boolean = 9 | if cache.minAfter(start).getOrElse((Int.MaxValue, Int.MaxValue))._1 > end 10 | && cache.maxBefore(start).getOrElse((Int.MinValue, Int.MinValue))._2 < start 11 | then { 12 | cache(start) = end 13 | true 14 | } else false 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/orderedset/MyCalendar3.scala: -------------------------------------------------------------------------------- 1 | package orderedset 2 | 3 | import scala.collection.mutable 4 | 5 | class MyCalendar3 { 6 | private[this] val cache = mutable.TreeMap[Int, Int]() 7 | 8 | def book(startTime: Int, endTime: Int): Int = 9 | cache(startTime) = cache.getOrElse(startTime, 0) + 1 10 | cache(endTime) = cache.getOrElse(endTime, 0) - 1 11 | cache.values.foldLeft(0, 0) { case ((max, ongoing), booking) => 12 | val curr = ongoing + booking 13 | (max.max(curr), curr) 14 | }._1 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/prefixsum/ContiguousArray.scala: -------------------------------------------------------------------------------- 1 | package prefixsum 2 | 3 | import scala.collection.mutable 4 | 5 | object ContiguousArray { 6 | def findMaxLength(nums: Array[Int]): Int = 7 | val cache = mutable.HashMap[Int, Int]() 8 | nums.map(n => if n == 0 then -1 else 1) 9 | .scanLeft(0) { case (sum, n) => sum + n } 10 | .zipWithIndex 11 | .foldLeft(0) { case (max, (sum, i)) => 12 | if !cache.contains(sum) then cache.put(sum, i) 13 | max.max(i - cache(sum)) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/prefixsum/ContinuousSubarraySum.scala: -------------------------------------------------------------------------------- 1 | package prefixsum 2 | 3 | import scala.collection.mutable 4 | 5 | object ContinuousSubarraySum { 6 | def checkSubarraySum(nums: Array[Int], k: Int): Boolean = 7 | val cache = mutable.HashSet[Int]() // fast lookup of all reminders 8 | var sum = 0 9 | nums.exists { num => 10 | sum = sum + num 11 | !cache.add(sum % k) // when there is a matched reminder, the subarray sum could be divided by k 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/prefixsum/FindPivotIndex.scala: -------------------------------------------------------------------------------- 1 | package prefixsum 2 | 3 | object FindPivotIndex { 4 | def pivotIndex(nums: Array[Int]): Int = 5 | val leftprefixsum: Array[Int] = nums.scanLeft(0)(_ + _) 6 | val rightprefixsum: Array[Int] = nums.scanRight(0)(_ + _) 7 | leftprefixsum.zipWithIndex.find { case (num, index) => index + 1 < rightprefixsum.length && num == rightprefixsum(index + 1) } match 8 | case Some(_, i) => i 9 | case _ => -1 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/prefixsum/ProductofArrayExceptSelf.scala: -------------------------------------------------------------------------------- 1 | package prefixsum 2 | 3 | object ProductofArrayExceptSelf { 4 | def productExceptSelf(nums: Array[Int]): Array[Int] = 5 | val result = Array.fill[Int](nums.length)(1) 6 | nums.drop(1).zipWithIndex.foldLeft(nums.head) { case (prod, (num, index)) => 7 | result(index + 1) = prod 8 | prod * num 9 | } 10 | nums.dropRight(1).zipWithIndex.foldRight(nums.last) { case ((num, index), prod) => 11 | result(index) = prod * result(index) 12 | prod * num 13 | } 14 | result 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/prefixsum/RangeSumQueryImmutable.scala: -------------------------------------------------------------------------------- 1 | package prefixsum 2 | 3 | class RangeSumQueryImmutable(nums: Array[Int]) { 4 | private val prefixSum = nums.scanLeft(0)(_ + _) 5 | 6 | def sumRange(left: Int, right: Int): Int = prefixSum(right + 1) - (if left == 0 then 0 else prefixSum(left)) 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/queue/Dota2Senate.scala: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import scala.collection.mutable 4 | 5 | object Dota2Senate { 6 | def predictPartyVictory(senate: String): String = 7 | val (qr, qd) = (mutable.ArrayDeque[Int](), mutable.ArrayDeque[Int]()) 8 | senate.zipWithIndex.foreach { 9 | case ('R', index) => qr.addOne(index) 10 | case (_, index) => qd.addOne(index) 11 | } 12 | while qr.nonEmpty && qd.nonEmpty do 13 | val (ri, di) = (qr.removeHead(), qd.removeHead()) 14 | if ri < di then qr.addOne(senate.length + ri) else qd.addOne(senate.length + di) 15 | if qr.size > qd.size then "Radiant" else "Dire" 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/queue/MyQueue.scala: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import scala.collection.mutable 4 | 5 | class MyQueue[T] { 6 | private val input = mutable.Stack[T]() 7 | private val output = mutable.Stack[T]() 8 | 9 | def push(x: T): Unit = input.push(x) 10 | 11 | def pop(): T = 12 | this.peek() 13 | output.pop() 14 | 15 | def peek(): T = 16 | if output.isEmpty then while input.nonEmpty do output.push(input.pop()) 17 | output.head 18 | 19 | def empty(): Boolean = input.isEmpty && output.isEmpty 20 | } 21 | -------------------------------------------------------------------------------- /src/main/scala/queue/MyStack.scala: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import scala.collection.mutable 4 | 5 | class MyStack[T <: Comparable[T]] { 6 | private val q1 = mutable.Queue[T]() 7 | private val q2 = mutable.Queue[T]() 8 | 9 | def push(x: T): Unit = 10 | val (qe, qf) = if q1.isEmpty then (q1, q2) else (q2, q1) 11 | qe.enqueue(x) 12 | while qf.nonEmpty do qe.enqueue(qf.dequeue()) 13 | 14 | def pop(): T = 15 | val q = if q1.isEmpty then q2 else q1 16 | if q.isEmpty then throw new IllegalArgumentException("empty stack") 17 | else q.dequeue() 18 | 19 | def top(): T = 20 | val q = if q1.isEmpty then q2 else q1 21 | if q.isEmpty then throw new IllegalArgumentException("empty stack") 22 | else q.head 23 | 24 | def empty(): Boolean = q1.isEmpty && q2.isEmpty 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/queue/RevealCardsInIncreasingOrder.scala: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import scala.collection.mutable 4 | 5 | object RevealCardsInIncreasingOrder { 6 | def deckRevealedIncreasing(deck: Array[Int]): Array[Int] = 7 | deck.sorted.reverse 8 | .foldLeft(mutable.ArrayDeque[Int]()) { case (q, num) => 9 | if q.nonEmpty then q.prepend(q.removeLast()) 10 | q.prepend(num) 11 | }.toArray 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/queue/ZigzagIterator.scala: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import scala.collection.mutable 4 | 5 | class ZigzagIterator(val l1: List[Int], val l2: List[Int]) { 6 | private[this] val iterators = mutable.Queue[Iterator[Int]]() 7 | if l1.nonEmpty then iterators.enqueue(l1.iterator) 8 | if l2.nonEmpty then iterators.enqueue(l2.iterator) 9 | 10 | def next: Int = 11 | val iterator = iterators.dequeue() 12 | val result = iterator.next() 13 | if iterator.hasNext then iterators.enqueue(iterator) 14 | result 15 | 16 | def hasNext: Boolean = iterators.nonEmpty 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/recursion/RegularExpressionMatching.scala: -------------------------------------------------------------------------------- 1 | package recursion 2 | 3 | object RegularExpressionMatching { 4 | def isMatch(s: String, p: String): Boolean = p.toSeq match 5 | case Seq() => s.isEmpty 6 | case Seq(head, tail*) => 7 | val firstMatch = s.headOption.exists(_ == head || head == '.') 8 | tail.headOption.filter(_ == '*') match 9 | case Some(_) => isMatch(s, p.drop(2)) || (firstMatch && isMatch(s.drop(1), p)) 10 | case None => firstMatch && isMatch(s.drop(1), p.drop(1)) 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/recursion/ReverseNodesinkGroup.scala: -------------------------------------------------------------------------------- 1 | package recursion 2 | 3 | import linkedlist.LinkedListNode 4 | 5 | object ReverseNodesinkGroup { 6 | def reverseKGroup(head: LinkedListNode[Int], k: Int): LinkedListNode[Int] = 7 | var (tmphead, tail, count) = (head, Option(head), 0) 8 | while tail.isDefined && count != k do { 9 | tail = tail.get.next 10 | count = count + 1 11 | } 12 | if count < k then head 13 | else { 14 | tail = Option(reverseKGroup(tail.get, k)) 15 | while count > 0 do { 16 | count = count - 1 17 | val tmp = tmphead.next 18 | tmphead.next = tail 19 | tail = Option(tmphead) 20 | tmphead = tmp.get 21 | } 22 | tail.get 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/scala/recursion/ScrambleString.scala: -------------------------------------------------------------------------------- 1 | package recursion 2 | 3 | object ScrambleString { 4 | def isScramble(s1: String, s2: String): Boolean = 5 | if s1.length != s2.length then false 6 | else if s1.equals(s2) then true 7 | else if s1.length <= 2 then s1.equals(s2.reverse) 8 | else { 9 | (1 until s1.length).exists { i => 10 | (isScramble(s1.substring(0, i), s2.substring(0, i)) && isScramble(s1.substring(i), s2.substring(i))) 11 | || (isScramble(s1.substring(0, i), s2.substring(s1.length - i)) && isScramble(s1.substring(i), s2.substring(0, s1.length - i))) 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/recursion/StrobogrammaticNumber2.scala: -------------------------------------------------------------------------------- 1 | package recursion 2 | 3 | object StrobogrammaticNumber2 { 4 | def generate(n: Int): Array[String] = n match 5 | case 0 => Array("") 6 | case 1 => Array("0", "1", "8") 7 | case 2 => Array("11", "69", "88", "96") 8 | case _ => generate(n - 2).flatMap(num => Array("1" + num + "1", "6" + num + "9", "9" + num + "6", "8" + num + "8")) 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala/recursion/SwapNodesinPairs.scala: -------------------------------------------------------------------------------- 1 | package recursion 2 | 3 | import linkedlist.LinkedListNode 4 | 5 | object SwapNodesinPairs { 6 | def swapPairs(head: LinkedListNode[Int]): LinkedListNode[Int] = 7 | if head.next.isEmpty then head 8 | else { 9 | val next = head.next.get 10 | if next.next.isEmpty then { 11 | head.next = None 12 | next.next = Some(head) 13 | next 14 | } else { 15 | val newhead = next.next.get 16 | next.next = Some(head) 17 | head.next = Some(swapPairs(newhead)) 18 | next 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/scala/sort/GroupAnagrams.scala: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import scala.collection.mutable 4 | 5 | object GroupAnagrams { 6 | def groupAnagrams(strs: Array[String]): List[List[String]] = 7 | val cache = mutable.HashMap[String, List[String]]() 8 | strs.foreach { str => cache.update(str.sorted, cache.getOrElse(str.sorted, List.empty[String]) :+ str) } 9 | cache.values.toList 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/sort/MergeIntervals.scala: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import scala.collection.mutable 4 | import scala.collection.mutable.ArrayBuffer 5 | 6 | object MergeIntervals { 7 | def merge(intervals: Array[Array[Int]]): Array[Array[Int]] = 8 | val sorted = intervals.sortBy(_ (0)) 9 | sorted.tail.foldLeft(new ArrayBuffer[Array[Int]]().addOne(sorted.head)) { 10 | case (result, curr) if result.last(1) >= curr(0) => result.last(1) = result.last(1).max(curr(1)) 11 | result 12 | case (result, curr) => result.addOne(curr) 13 | }.toArray 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/stack/EvaluateReversePolishNotation.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | object EvaluateReversePolishNotation { 4 | def evalRPN(tokens: Array[String]): Int = 5 | val stack = new MinStack[Integer]() 6 | tokens.foreach { 7 | case "+" => stack.push(stack.pop() + stack.pop()) 8 | case "*" => stack.push(stack.pop() * stack.pop()) 9 | case "-" => stack.push(-stack.pop() + stack.pop()) 10 | case "/" => stack.push((1.0 / stack.pop().toDouble * stack.pop()).toInt) 11 | case num => stack.push(num.toInt) 12 | } 13 | stack.pop() 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/stack/LongestValidParentheses.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | object LongestValidParentheses { 4 | def longestValidParentheses(s: String): Int = 5 | val stack = new MinStack[Character]() 6 | var (max, count) = (0, 0) 7 | s.foreach { 8 | case '(' => stack.push('(') 9 | case _ => if stack.isEmpty then { 10 | max = max.max(count * 2) 11 | count = 0 12 | } else { 13 | stack.pop() 14 | count = count + 1 15 | } 16 | } 17 | max.max(count * 2) 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/stack/OnlineStockSpan.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | import scala.collection.mutable 4 | 5 | object OnlineStockSpan { 6 | def calulcateSpan(prices: Array[Int]): Array[Int] = prices match 7 | case Array() => Array() 8 | case Array(_) => Array(0) 9 | case _ => val (stack, array) = (new MinStack[Integer](), mutable.ArrayBuffer[Int](0)) 10 | stack.push(0) 11 | prices.drop(1).zipWithIndex.foreach { case (price, index) => 12 | var (span, i) = (1, index + 1) 13 | while prices(stack.top()) < price do 14 | span = span + 1 15 | stack.pop() 16 | stack.push(i) 17 | array.append(span) 18 | } 19 | array.toArray 20 | } 21 | -------------------------------------------------------------------------------- /src/main/scala/stack/ShortestUnsortedContinuousSubarray.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | object ShortestUnsortedContinuousSubarray { 4 | def findUnsortedSubarray(nums: Array[Int]): Int = 5 | def getEnd(nums: Array[Int]): Int = 6 | var (end, stack) = (nums.length, new MinStack[Integer]()) 7 | nums.zipWithIndex.foreach { case (num, index) => 8 | while !stack.isEmpty && nums(stack.top()) > num do end = end.min(stack.pop()) 9 | stack.push(index) 10 | } 11 | end + 1 12 | 13 | val (left, right) = (getEnd(nums), nums.length - getEnd(nums.reverse)) 14 | if right > left then right - left + 1 else 0 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/stack/SimplifyPath.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | object SimplifyPath { 4 | def simplifyPath(path: String): String = 5 | val stack = new MinStack[String]() 6 | path.split("/") 7 | .foreach { 8 | case ".." => if !stack.isEmpty then stack.pop() 9 | case str => if str.nonEmpty && !".".equals(str) then stack.push(str) 10 | } 11 | var result = "" 12 | while !stack.isEmpty do result = "/" + stack.pop() + result 13 | if result.isEmpty then "/" else result 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/stack/ValidParentheses.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | object ValidParentheses { 4 | def isValid(s: String): Boolean = 5 | val stack = new MinStack[Character]() 6 | val map = Map(')' -> '(', ']' -> '[', '}' -> '{') 7 | !s.toArray.exists { 8 | case char@('(' | '[' | '{') => stack.push(char); false 9 | case char@(')' | ']' | '}') => if stack.pop() == map(char) then false else true 10 | case _ => true 11 | } && stack.isEmpty 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/string/AddBinary.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | object AddBinary { 4 | def addBinary(a: String, b: String): String = 5 | a.reverse.zipAll(b.reverse, '0', '0').reverse 6 | .foldRight(("", 0)) { case ((s1, s2), (result, carry)) => 7 | val sum = carry + (s1 - '0') + (s2 - '0') 8 | (s"${sum % 2}$result", sum / 2) 9 | } match 10 | case (result, 1) => "1" + result 11 | case (result, _) => result 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/string/AddStrings.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | object AddStrings { 4 | def addStrings(num1: String, num2: String): String = 5 | num1.reverse.zipAll(num2.reverse, '0', '0').reverse 6 | .foldRight(("", 0)) { case ((n1, n2), (result, carry)) => 7 | val sum = carry + (n1 - '0') + (n2 - '0') 8 | (s"${sum % 10}$result", sum / 10) 9 | } match 10 | case (result, 1) => "1" + result 11 | case (result, _) => result 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/string/CompareVersionNumbers.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | object CompareVersionNumbers { 4 | def compareVersion(version1: String, version2: String): Int = 5 | val (vs1, vs2) = (version1.split("\\."), version2.split("\\.")) 6 | for (i <- 0 until vs1.length.max(vs2.length)) { 7 | val v1v = if i >= vs1.length then 0 else getVersion(vs1(i)) 8 | val v2v = if i >= vs2.length then 0 else getVersion(vs2(i)) 9 | if v1v != v2v then return v1v.compare(v2v) 10 | } 11 | 0 12 | 13 | private def getVersion(v: String): Int = v.indexWhere(c => c.isDigit && !c.isSpaceChar) match 14 | case len if len >= v.length => 0 15 | case len => v.substring(len).toInt 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/string/CountandSay.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | object CountandSay { 4 | def countAndSay(n: Int): String = 5 | (1 until n).foldLeft("1") { case (result, _) => 6 | (result + "A").zipWithIndex.foldLeft(("", 0)) { 7 | case ((sb, lp), (char, rp)) if rp == 0 || char == result(rp - 1) => (sb, lp) 8 | case ((sb, lp), (_, rp)) => (s"$sb${rp - lp}${result(rp - 1).toString}", rp) 9 | }._1 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/main/scala/string/LongestCommonPrefix.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | object LongestCommonPrefix { 4 | def longestCommonPrefix(strs: Array[String]): String = strs match 5 | case Array() => "" 6 | case _ => var prefix = strs(0) 7 | strs.drop(1).foreach(str => { 8 | while str.indexOf(prefix) == -1 do prefix = prefix.dropRight(1) 9 | }) 10 | prefix 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/string/OneEditDistance.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | object OneEditDistance { 4 | def isOneEditDistance(s: String, t: String): Boolean = 5 | if s.length == t.length then s.zip(t).count { case (sc, tc) => !sc.equals(tc) } == 1 6 | else { 7 | val (ss, ls) = if s.length > t.length then (t, s) else (s, t) 8 | var (count, sp, lp) = (0, 0, 0) 9 | while lp < ls.length do 10 | if ss(sp) != ls(lp) then count = count + 1 else sp = sp + 1 11 | lp = lp + 1 12 | count == 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/string/PartitionLabels.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | import scala.collection.mutable 4 | 5 | object PartitionLabels { 6 | def partitionLabels(s: String): List[Int] = 7 | val (cache, result) = (mutable.Map[Char, Int](), mutable.ListBuffer[Int]()) 8 | var (i, start, end) = (0, 0, 0) 9 | s.zipWithIndex.foreach { case (char, index) => cache.update(char, index) } 10 | while i < s.length do 11 | end = cache(s.charAt(i)) 12 | while end > i do 13 | i = i + 1 14 | end = end.max(cache(s.charAt(i))) 15 | result.append(end + 1 - start) 16 | i = i + 1 17 | start = i 18 | end = i 19 | result.toList 20 | } 21 | -------------------------------------------------------------------------------- /src/main/scala/string/ZigZagConversion.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | import scala.collection.mutable 4 | 5 | object ZigZagConversion { 6 | def convert(s: String, numRows: Int): String = numRows match 7 | case 1 => s 8 | case _ => val cache = (0 until numRows).map(_ => new mutable.ArrayBuffer[Char]()).toArray 9 | var (pos, num, down) = (0, 0, true) 10 | while pos < s.length do 11 | cache(num).append(s.charAt(pos)) 12 | pos = pos + 1 13 | num = if down then num + 1 else num - 1 14 | if num == numRows then { 15 | down = false 16 | num = numRows - 2 17 | } 18 | if num == -1 then { 19 | down = true 20 | num = 1 21 | } 22 | cache.reduce(_ ++ _).mkString("") 23 | } 24 | -------------------------------------------------------------------------------- /src/main/scala/tree/BalancedBinaryTree.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | object BalancedBinaryTree { 4 | def isBalanced(root: TreeNode[Int]): Boolean = (root.left, root.right) match 5 | case (Some(left), Some(right)) => isBalanced(left) && isBalanced(right) 6 | case (Some(_), None) | (None, Some(_)) => false 7 | case _ => true 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/tree/FlattenBinaryTreetoLinkedList.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | object FlattenBinaryTreetoLinkedList { 4 | def flatten(root: TreeNode[Int]): Unit = (root.left, root.right) match 5 | case (None, None) => 6 | case (None, Some(rnode)) => flatten(rnode) 7 | case (Some(lnode), None) => flatten(lnode) 8 | root.right = Option(lnode) 9 | root.left = None 10 | case (Some(lnode), Some(rnode)) => 11 | flatten(rnode) 12 | flatten(lnode) 13 | root.right = Option(lnode) 14 | root.left = None 15 | var end = lnode 16 | while end.right.isDefined do end = end.right.get 17 | end.right = Option(rnode) 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/tree/InvertBinaryTree.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | object InvertBinaryTree { 4 | def invertTree(root: TreeNode[Int]): TreeNode[Int] = 5 | (root.left, root.right) match { 6 | case (Some(left), Some(right)) => 7 | root.left = Option(invertTree(right)) 8 | root.right = Option(invertTree(left)) 9 | case _ => 10 | } 11 | root 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/tree/MaximumDepthofBinaryTree.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | object MaximumDepthofBinaryTree { 4 | def maxDepth(root: TreeNode[Int]): Int = 1 + ((root.left, root.right) match { 5 | case (None, None) => 0 6 | case (Some(n), None) => maxDepth(n) 7 | case (None, Some(n)) => maxDepth(n) 8 | case (Some(n1), Some(n2)) => maxDepth(n1).max(maxDepth(n2)) 9 | }) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/tree/MinimumDepthofBinaryTree.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | object MinimumDepthofBinaryTree { 4 | def minDepth(root: TreeNode[Int]): Int = (root.left, root.right) match 5 | case (Some(lnode), Some(rnode)) => 1 + minDepth(lnode).min(minDepth(rnode)) 6 | case _ => 1 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/tree/SymmetricTree.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | object SymmetricTree { 4 | def isSymmetric(root: TreeNode[Int]): Boolean = isSymmeticInternal(root.left, root.right) 5 | 6 | private def isSymmeticInternal(left: Option[TreeNode[Int]], right: Option[TreeNode[Int]]): Boolean = (left, right) match 7 | case (None, None) => true 8 | case (Some(_), None) | (None, Some(_)) => false 9 | case (Some(n1), Some(n2)) => isSymmeticInternal(n1.right, n2.left) && isSymmeticInternal(n1.left, n2.right) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/tries/WordBreak.scala: -------------------------------------------------------------------------------- 1 | package tries 2 | 3 | object WordBreak { 4 | def wordBreak(s: String, wordDict: List[String]): Boolean = 5 | val trie = Trie.empty[Int] 6 | wordDict.foreach(trie.insert(_, 0)) 7 | val dp = Array.fill(s.length + 1)(false) 8 | dp(0) = true 9 | for (i <- 0 until s.length - 1; j <- i + 1 to s.length) 10 | if !dp(j) then dp(j) = dp(i) && trie.search(s.substring(i, j)).isDefined 11 | dp.last 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/ContainerWithMostWater.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | object ContainerWithMostWater { 4 | def maxArea(height: Array[Int]): Int = 5 | var (max, left, right) = (0, 0, height.length - 1) 6 | while left < right do 7 | max = max.max(height(left).min(height(right)) * (right - left)) 8 | if height(left) > height(right) then right = right - 1 9 | else left = left + 1 10 | max 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/ContainsDuplicate2.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import scala.collection.mutable 4 | 5 | object ContainsDuplicate2 { 6 | def containsNearbyDuplicate(nums: Array[Int], k: Int): Boolean = 7 | val cache = mutable.HashSet[Int]() 8 | nums.zipWithIndex.exists { case (num, index) => 9 | if index > k then cache.remove(nums(index - k - 1)) 10 | if !cache.add(num) then true else false 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/ImplementstrStr.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | object ImplementstrStr { 4 | def strStr(haystack: String, needle: String): Int = 5 | haystack.toCharArray.zipWithIndex.find { case (_, index) => 6 | !needle.toCharArray.zipWithIndex.exists { case (char2, index2) => 7 | haystack(index + index2) != char2 8 | } 9 | }.map(_._2).getOrElse(-1) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/LengthOfLongestSubString.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import scala.collection.mutable 4 | 5 | object LengthOfLongestSubString { 6 | def lengthOfLongestSubstring(s: String): Int = 7 | val cache = mutable.Map[Char, Int]() 8 | s.zipWithIndex.foldLeft((0, 0)) { case ((max, lp), (char, rp)) => 9 | if cache.contains(char) then (max, cache(char) + 1) else { 10 | cache.update(char, rp) 11 | (max.max(rp - lp + 1), lp) 12 | } 13 | }._1 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/LongestSubstringwithAtMostTwoDistinctCharacters.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import scala.collection.mutable 4 | 5 | object LongestSubstringwithAtMostTwoDistinctCharacters { 6 | def lengthOfLongestSubstringTwoDistinct(s: String): Int = 7 | val cache = mutable.HashSet[Char]() 8 | var (max, left, right) = (0, 0, 0) 9 | while left < s.length do 10 | while cache.size < 2 && right < s.length do 11 | cache.add(s.charAt(right)) 12 | right = right + 1 13 | max = max.max(right - left + 1) 14 | cache.remove(s.charAt(left)) 15 | left = left + 1 16 | max 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/RemoveDuplicatesfromSortedArrayII.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | object RemoveDuplicatesfromSortedArrayII { 4 | def removeDuplicates(nums: Array[Int]): Int = 5 | var (count, actualp, searchp) = (1, 1, 1) 6 | while searchp < nums.length do { 7 | if nums(searchp) != nums(searchp - 1) then 8 | count = 1 9 | actualp = actualp + 1 10 | nums(actualp) = nums(searchp) 11 | else if count < 2 then { 12 | count = count + 1 13 | actualp = actualp + 1 14 | nums(actualp) = nums(searchp) 15 | } 16 | searchp = searchp + 1 17 | } 18 | actualp 19 | } -------------------------------------------------------------------------------- /src/main/scala/twopointers/SortColors.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | object SortColors { 4 | def sortColors(nums: Array[Int]): Unit = _sortColors(nums, _sortColors(nums, 0, 0), 1) 5 | 6 | private def _sortColors(nums: Array[Int], start: Int, target: Int): Int = 7 | var lp = start 8 | while nums(lp) == target do lp = lp + 1 9 | var rp = lp + 1 10 | while rp < nums.length do { 11 | if nums(rp) == target then 12 | nums(rp) = nums(lp) 13 | nums(lp) = target 14 | lp = lp + 1 15 | end if 16 | rp = rp + 1 17 | } 18 | lp 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/StringCompression.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | object StringCompression { 4 | def compress(chars: Array[Char]): Int = 5 | val compressed = (chars :+ 'A').zipWithIndex.foldLeft(("", 0)) { 6 | case ((result, lp), (char, rp)) => 7 | if chars(lp) == char then (result, lp) 8 | else { 9 | val str = if (rp - lp) == 1 then "" else (rp - lp).toString 10 | (s"$result${chars(lp).toString}$str", rp) 11 | } 12 | }._1 13 | compressed.zipWithIndex.foreach { case (char, index) => chars(index) = char } 14 | compressed.length 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/SubstringwithConcatenationofAllWords.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import scala.collection.mutable 4 | 5 | object SubstringwithConcatenationofAllWords { 6 | def findSubstring(s: String, words: Array[String]): List[Int] = 7 | val len = words(0).length 8 | val ss = s.grouped(len).toArray 9 | val map = mutable.HashMap[String, Int]() 10 | words.foreach { word => map.update(word, map.getOrElse(word, 0) + 1) } 11 | ss.zipWithIndex.filter { case (_, index) => 12 | val wordmap = mutable.HashMap[String, Int]().addAll(map) 13 | for (n <- words.indices if n + index < ss.length) wordmap.update(ss(index + n), map.getOrElse(ss(index + n), 0) - 1) 14 | wordmap.values.count(_ != 0) == 0 15 | }.map { case (_, index) => index * len } 16 | .toList 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/SummaryRanges.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import scala.collection.mutable 4 | 5 | object SummaryRanges { 6 | def summaryRanges(nums: Array[Int]): List[String] = 7 | val result = mutable.ListBuffer[String]() 8 | var (left, right) = (0, 0) 9 | while right < nums.length do 10 | while right + 1 < nums.length && nums(right) + 1 == nums(right + 1) do right = right + 1 11 | if left == right then result.addOne(s"${nums(left)}") else result.addOne(s"${nums(left)}->${nums(right)}") 12 | right = right + 1 13 | left = right 14 | result.toList 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/ThreeSumClosest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | object ThreeSumClosest { 4 | def threeSumClosest(nums: Array[Int], target: Int): Int = 5 | var closest = 0 6 | val sortednum = nums.sorted 7 | sortednum.zipWithIndex.foreach { case (_, index) => 8 | var (left, right) = (index + 1, nums.length - 1) 9 | while left < right do 10 | val sum = sortednum(index) + sortednum(left) + sortednum(right) 11 | closest = if (closest - sum).abs < (target - sum).abs then closest else sum 12 | if sum > target then right = right - 1 13 | else left = left + 1 14 | } 15 | closest 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/TwoSumII.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | object TwoSumII { 4 | def twoSum(numbers: Array[Int], target: Int): Array[Int] = 5 | var (lp, rp) = (0, numbers.length - 1) 6 | while lp < rp && numbers(lp) + numbers(rp) != target do 7 | numbers(lp) + numbers(rp) match 8 | case sum if sum < target => lp = lp + 1 9 | case _ => rp = rp - 1 10 | Array(lp + 1, rp + 1) 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/ValidPalindrome.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | object ValidPalindrome { 4 | def isPalindrome(s: String): Boolean = 5 | var (lp, rp) = (0, s.length - 1) 6 | while lp < rp do 7 | (s.charAt(lp), s.charAt(rp)) match 8 | case (lc, _) if !lc.isLetterOrDigit => lp = lp + 1 9 | case (_, rc) if !rc.isLetterOrDigit => rp = rp - 1 10 | case (lc, rc) if lc.toLower != rc.toLower => return false 11 | case (_, _) => 12 | lp = lp + 1 13 | rp = rp - 1 14 | true 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/ValidPalindrome2.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | object ValidPalindrome2 { 4 | def validPalindrome(s: String): Boolean = isValidPalindrome(s, 0, s.length - 1) match 5 | case (false, sp, ep) => isValidPalindrome(s, sp + 1, ep)._1 || isValidPalindrome(s, sp, ep - 1)._1 6 | case _ => true 7 | 8 | private def isValidPalindrome(str: String, s: Int, e: Int): (Boolean, Int, Int) = 9 | var (sp, ep) = (s, e) 10 | while sp < ep do 11 | (str.charAt(sp), str.charAt(ep)) match 12 | case (sc, ec) if sc != ec => return (false, sp, ep) 13 | case (_, _) => sp = sp + 1 14 | ep = ep - 1 15 | (true, s, e) 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/twopointers/ValidPalindrome4.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | object ValidPalindrome4 { 4 | def makePalindrome(s: String): Boolean = 5 | var (b, e, mismatch) = (0, s.length - 1, 0) 6 | while b < e do { 7 | if s.charAt(b)!=s.charAt(e) then mismatch = mismatch + 1 8 | b = b + 1 9 | e = e - 1 10 | } 11 | mismatch <= 2 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/unionfind/NumberofProvinces.scala: -------------------------------------------------------------------------------- 1 | package unionfind 2 | 3 | object NumberofProvinces { 4 | def findCircleNum(isConnected: Array[Array[Int]]): Int = 5 | var result = isConnected.length 6 | val parent = isConnected.indices.toArray 7 | for (i <- isConnected.indices; j <- isConnected.indices) { 8 | if i != j && isConnected(i)(j) == 1 && UF.union(i, j, parent) then result = result - 1 9 | } 10 | result 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/unionfind/UF.scala: -------------------------------------------------------------------------------- 1 | package unionfind 2 | 3 | object UF { 4 | def union(nid1: Int, nid2: Int, parent: Array[Int]): Boolean = 5 | val (pid1, pid2) = (find(nid1, parent), find(nid2, parent)) 6 | pid1 != pid2 && { 7 | parent(pid1) = pid2 8 | true 9 | } 10 | 11 | private def find(nid: Int, parent: Array[Int]): Int = 12 | if parent(nid) == nid then nid else { 13 | parent(nid) = find(parent(nid), parent) 14 | parent(nid) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/array/MinimumIncrementtoMakeArrayUniqueTest.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class MinimumIncrementtoMakeArrayUniqueTest extends AnyFunSuite { 7 | test("can find the min increment") { 8 | val nums = Array(3, 2, 1, 2, 1, 7) 9 | val result = MinimumIncrementtoMakeArrayUnique.minIncrementForUnique(nums) 10 | result shouldEqual 6 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/array/MoveZeroesTest.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class MoveZeroesTest extends AnyFunSuite { 7 | test("can move zeroes") { 8 | val nums = Array(0, 1, 0, 3, 12) 9 | MoveZeroes.moveZeroes(nums) 10 | nums shouldEqual Array(1, 3, 12, 0, 0) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/array/RemoveDuplicatesfromSortedArrayTest.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class RemoveDuplicatesfromSortedArrayTest extends AnyFunSuite { 7 | test("can remove duplicates") { 8 | val nums = Array(1, 1, 2, 2) 9 | val result = RemoveDuplicatesfromSortedArray.removeDuplicates(nums) 10 | result shouldEqual 2 11 | } 12 | 13 | test("can remove duplicates with single element") { 14 | val nums = Array(1) 15 | val result = RemoveDuplicatesfromSortedArray.removeDuplicates(nums) 16 | result shouldEqual 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/array/ReverseWordsinaStringTest.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class ReverseWordsinaStringTest extends AnyFunSuite { 7 | test("reverse words in a string") { 8 | val s = "the sky is blue" 9 | val result = ReverseWordsinaString.reverseWords(s) 10 | result shouldEqual "blue is sky the" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/array/RotateArrayTest.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class RotateArrayTest extends AnyFunSuite { 7 | test("can rotate array by reverse") { 8 | val nums = Array(1, 2, 3, 4, 5, 6, 7) 9 | RotateArray.rotate(nums, 3) 10 | nums shouldEqual Array(4, 5, 6, 7, 1, 2, 3) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/array/SubsetsTest.scala: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class SubsetsTest extends AnyFunSuite { 7 | test("can get all sub sets") { 8 | val nums = Array(1, 2, 3) 9 | val result = Subsets.subsets(nums) 10 | result.length shouldEqual 8 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/backtracking/CombinationSum2Test.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class CombinationSum2Test extends AnyFunSuite { 7 | test("can get all combinations") { 8 | val nums = Array(10, 1, 2, 7, 6, 1, 5) 9 | val result = CombinationSum2.combinationSum2(nums, 8) 10 | result shouldEqual List(List(1, 1, 6), List(1, 2, 5), List(1, 7), List(2, 6)) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/backtracking/GenerateParenthesesTest.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class GenerateParenthesesTest extends AnyFunSuite { 7 | test("can generate well formed parentheses") { 8 | val n = 3 9 | val result = GenerateParentheses.generateParenthesis(3) 10 | result shouldEqual List("((()))", "(()())", "(())()", "()(())", "()()()") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/backtracking/LetterCombinationsofaPhoneNumberTest.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class LetterCombinationsofaPhoneNumberTest extends AnyFunSuite { 7 | test("can list all combinations") { 8 | val result = LetterCombinationsofaPhoneNumber.letterCombinations("23") 9 | result shouldEqual List("ad", "bd", "cd", "ae", "be", "ce", "af", "bf", "cf") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/scala/backtracking/NQueens2Test.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class NQueens2Test extends AnyFunSuite { 7 | test("can find n-queens for 1") { 8 | NQueens2.totalNQueens(1) shouldEqual 1 9 | } 10 | 11 | test("can find n-queens for 2") { 12 | NQueens2.totalNQueens(2) shouldEqual 0 13 | } 14 | 15 | test("can find n-queens for 4") { 16 | NQueens2.totalNQueens(4) shouldEqual 2 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/backtracking/NQueensTest.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class NQueensTest extends AnyFunSuite { 7 | test("can find 4 queens") { 8 | val result = NQueens.solveNQueens(4) 9 | result shouldEqual List(List(".Q..","...Q","Q...","..Q."), List("..Q.","Q...","...Q",".Q..")) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/scala/backtracking/Permutations2Test.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class Permutations2Test extends AnyFunSuite { 7 | test("can get all permutations") { 8 | val nums = Array(1, 2, 3) 9 | val result = Permutations2.permuteUnique(nums) 10 | result shouldEqual List(List(3, 2, 1), List(2, 3, 1), List(3, 1, 2), List(1, 3, 2), List(2, 1, 3), List(1, 2, 3)) 11 | } 12 | } -------------------------------------------------------------------------------- /src/test/scala/backtracking/PermutationsTest.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class PermutationsTest extends AnyFunSuite { 7 | test("can get all permutations") { 8 | val nums = Array(1, 2, 3) 9 | val result = Permutations.permute(nums) 10 | result shouldEqual List(List(1, 2, 3), List(1, 3, 2), List(2, 1, 3), List(2, 3, 1), List(3, 1, 2), List(3, 2, 1)) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/backtracking/WordSearchTest.scala: -------------------------------------------------------------------------------- 1 | package backtracking 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class WordSearchTest extends AnyFunSuite { 7 | test("can find word") { 8 | val board = Array(Array('A', 'B', 'C', 'E'), Array('S', 'F', 'C', 'S'), Array('A', 'D', 'E', 'E')) 9 | val result = WordSearch.exist(board, "SEE") 10 | result shouldEqual true 11 | } 12 | 13 | test("can not find word") { 14 | val board = Array(Array('A', 'B', 'C', 'E'), Array('S', 'F', 'C', 'S'), Array('A', 'D', 'E', 'E')) 15 | val result = WordSearch.exist(board, "ABCB") 16 | result shouldEqual false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/bfs/BinaryTreeRightSideViewTest.scala: -------------------------------------------------------------------------------- 1 | package bfs 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import tree.TreeNode 6 | 7 | class BinaryTreeRightSideViewTest extends AnyFunSuite { 8 | test("can get the right side view") { 9 | val root = TreeNode(1) 10 | root.right = Option(TreeNode(3)) 11 | val left = TreeNode(2) 12 | root.left = Option(left) 13 | left.left = Option(TreeNode(4)) 14 | left.right = Option(TreeNode(5)) 15 | val result = BinaryTreeRightSideView.rightSideView(root) 16 | result shouldEqual List(1, 3, 5) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/binarysearch/FindFirstAndLastPositionInSortedArrayTest.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class FindFirstAndLastPositionInSortedArrayTest extends AnyFunSuite { 7 | test("can find the 1st and last") { 8 | val nums = Array(5, 7, 7, 8, 8, 10) 9 | val result = FindFirstAndLastPositionInSortedArray.searchRange(nums, 8) 10 | result shouldEqual Array(3, 4) 11 | } 12 | 13 | test("can return -1 -1 if there is no valid result") { 14 | val nums = Array(5, 7, 7, 8, 8, 10) 15 | val result = FindFirstAndLastPositionInSortedArray.searchRange(nums, 6) 16 | result shouldEqual Array(-1, -1) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/binarysearch/FindMinimuminRotatedSortedArray2Test.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class FindMinimuminRotatedSortedArray2Test extends AnyFunSuite { 7 | test("can find min of rotated array") { 8 | val nums = Array(4, 5, 6, 7, 0, 1, 4) 9 | val result = FindMinimuminRotatedSortedArray2.findMin(nums) 10 | result shouldEqual 0 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/binarysearch/FindMinimuminRotatedSortedArrayTest.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class FindMinimuminRotatedSortedArrayTest extends AnyFunSuite { 7 | test("can find min in rotated array") { 8 | val nums = Array(4, 5, 6, 1, 2, 3) 9 | val result = FindMinimuminRotatedSortedArray.findMin(nums) 10 | result shouldEqual 1 11 | } 12 | 13 | test("can find min in normal array") { 14 | val nums = Array(1, 2, 3, 4, 5, 6) 15 | val result = FindMinimuminRotatedSortedArray.findMin(nums) 16 | result shouldEqual 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/binarysearch/FindPeakElementTest.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class FindPeakElementTest extends AnyFunSuite { 7 | test("can find local peak in between") { 8 | val nums = Array(1, 2, 1, 3, 5, 6, 4) 9 | val result = FindPeakElement.findPeakElement(nums) 10 | result shouldEqual 5 11 | } 12 | 13 | test("can find local peak at edge") { 14 | val nums = Array(6, 5, 4, 3, 2) 15 | val result = FindPeakElement.findPeakElement(nums) 16 | result shouldEqual 0 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/binarysearch/FirstBadVersionTest.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class FirstBadVersionTest extends AnyFunSuite { 7 | test("can find the 1st bad version") { 8 | val result = new FirstBadVersion(4).firstBadVersion(10) 9 | result shouldEqual 4 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/scala/binarysearch/HIndex2Test.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class HIndex2Test extends AnyFunSuite { 7 | test("can get h index") { 8 | val citations = Array(0, 1, 3, 5, 6) 9 | val result = HIndex2.hIndex(citations) 10 | result shouldEqual 3 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/binarysearch/MedianofTwoSortedArraysTest.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class MedianofTwoSortedArraysTest extends AnyFunSuite { 7 | test("can find median of 2 sort array") { 8 | val nums1 = Array(1, 3, 5) 9 | val nums2 = Array(2, 4) 10 | val result = MedianofTwoSortedArrays.findMedianSortedArrays(nums1, nums2) 11 | result shouldEqual 3 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/binarysearch/SearchinRotatedSortedArray2Test.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class SearchinRotatedSortedArray2Test extends AnyFunSuite { 7 | test("can find index of sorted array") { 8 | val nums = Array(2, 5, 6, 0, 0, 1, 2) 9 | val result = SearchinRotatedSortedArray2.search(nums, 0) 10 | result shouldEqual true 11 | } 12 | 13 | test("can not find index of sorted array") { 14 | val nums = Array(2, 5, 6, 0, 0, 1, 2) 15 | val result = SearchinRotatedSortedArray2.search(nums, 4) 16 | result shouldEqual false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/binarysearch/SearchinRotatedSortedArrayTest.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class SearchinRotatedSortedArrayTest extends AnyFunSuite { 7 | test("can find in a sorted array") { 8 | val nums = Array(0, 1, 2, 3, 4, 5, 6) 9 | val result = SearchinRotatedSortedArray.search(nums, 3) 10 | result shouldEqual 3 11 | } 12 | 13 | test("can return -1 if could not find") { 14 | val nums = Array(0, 1, 2, 3, 5, 6, 7) 15 | val result = SearchinRotatedSortedArray.search(nums, 4) 16 | result shouldEqual -1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/binarysearch/SqrtTest.scala: -------------------------------------------------------------------------------- 1 | package binarysearch 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class SqrtTest extends AnyFunSuite { 7 | test("can get sqrt of <= 4") { 8 | Sqrt.mySqrt(0) shouldEqual 0 9 | Sqrt.mySqrt(1) shouldEqual 1 10 | Sqrt.mySqrt(2) shouldEqual 1 11 | Sqrt.mySqrt(3) shouldEqual 1 12 | Sqrt.mySqrt(4) shouldEqual 2 13 | 14 | } 15 | 16 | test("can get sqrt of 16") { 17 | val result = Sqrt.mySqrt(16) 18 | result shouldEqual 4 19 | } 20 | 21 | test("can get sqrt of 17") { 22 | val result = Sqrt.mySqrt(15) 23 | result shouldEqual 3 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/scala/bit/ConvertaNumbertoHexadecimalTest.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class ConvertaNumbertoHexadecimalTest extends AnyFunSuite { 7 | test("can convert 0") { 8 | val result = ConvertaNumbertoHexadecimal.toHex(0) 9 | result shouldEqual "0" 10 | } 11 | 12 | test("can convert 26") { 13 | val result = ConvertaNumbertoHexadecimal.toHex(26) 14 | result shouldEqual "a1" 15 | } 16 | 17 | test("can convert -1") { 18 | val result = ConvertaNumbertoHexadecimal.toHex(-1) 19 | result shouldEqual "ffffffff" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/scala/bit/DivideTwoIntegersTest.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class DivideTwoIntegersTest extends AnyFunSuite { 7 | test("can divide 10 by 3") { 8 | val result = DivideTwoIntegers.divide(10, 3) 9 | result shouldEqual 3 10 | } 11 | 12 | test("can divide 100 by 3") { 13 | val result = DivideTwoIntegers.divide(100, 3) 14 | result shouldEqual 33 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/bit/GrayCodeTest.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class GrayCodeTest extends AnyFunSuite { 7 | test("can handle 2") { 8 | val result = GrayCode.grayCode(2) 9 | result shouldEqual List(0, 1, 3, 2) 10 | } 11 | 12 | test("can handl 3") { 13 | val result = GrayCode.grayCode(3) 14 | result shouldEqual List(0, 1, 3, 2, 6, 7, 5, 4) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/bit/Numberof1BitsTest.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class Numberof1BitsTest extends AnyFunSuite { 7 | test("can count number of 1 bits") { 8 | val result = Numberof1Bits.hammingWeight(11) 9 | result shouldEqual 3 10 | } 11 | 12 | test("can count number of 1 bits of negative int") { 13 | val result = Numberof1Bits.hammingWeight(-3) 14 | result shouldEqual 31 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/bit/RepeatedDNASequencesTest.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class RepeatedDNASequencesTest extends AnyFunSuite { 7 | test("can find repeating sequence") { 8 | val s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" 9 | val result = RepeatedDNASequences.findRepeatedDnaSequences(s) 10 | result shouldEqual List("AAAAACCCCC", "CCCCCAAAAA") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/bit/ReverseBitsTest.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class ReverseBitsTest extends AnyFunSuite { 7 | test("can reverse bit") { 8 | val result = ReverseBits.reverseBits(43261596) 9 | result shouldEqual 964176192 10 | } 11 | 12 | test("can reverse bit of negative value") { 13 | val result = ReverseBits.reverseBits(-11) 14 | result shouldEqual -1342177281 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/bit/SingleNumber2Test.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class SingleNumber2Test extends AnyFunSuite { 7 | test("can get single number") { 8 | val nums = Array(0, 1, 0, 1, 0, 1, 99) 9 | val result = SingleNumber2.singleNumber(nums) 10 | result shouldEqual 99 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/bit/SingleNumberTest.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class SingleNumberTest extends AnyFunSuite { 7 | test("can get single number") { 8 | val nums = Array(4, 1, 2, 1, 2) 9 | val result = SingleNumber.singleNumber(nums) 10 | result shouldEqual 4 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/bit/SubsetsTest.scala: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class SubsetsTest extends AnyFunSuite { 7 | test("can get all sub sets") { 8 | val nums = Array(1, 2, 3) 9 | val result = Subsets.subsets(nums) 10 | result shouldEqual List(List(), List(1), List(2), List(1, 2), List(3), List(1, 3), List(2, 3), List(1, 2, 3)) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/bst/BinarySearchTreeIteratorTest.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import tree.TreeNode 6 | 7 | class BinarySearchTreeIteratorTest extends AnyFunSuite { 8 | test("can iterate a BST") { 9 | val root = new TreeNode[Int](7, Option(TreeNode(3)), Option(new TreeNode[Int](15, Option(TreeNode(9)), Option(TreeNode(20))))) 10 | val iterator = new BinarySearchTreeIterator(root) 11 | iterator.next() shouldEqual 3 12 | iterator.next() shouldEqual 7 13 | iterator.next() shouldEqual 9 14 | iterator.next() shouldEqual 15 15 | iterator.next() shouldEqual 20 16 | iterator.hasNext shouldEqual false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/bst/BinaryTreePathsTest.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import tree.TreeNode 6 | 7 | class BinaryTreePathsTest extends AnyFunSuite { 8 | test("can find paths") { 9 | val root = TreeNode(4) 10 | root.right = Option(TreeNode(5)) 11 | val left = TreeNode(2) 12 | root.left = Option(left) 13 | left.left = Option(TreeNode(1)) 14 | left.right = Option(TreeNode(3)) 15 | val result = BinaryTreePaths.binaryTreePaths(root) 16 | result shouldEqual List("4->2->1", "4->2->3", "4->5") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/bst/DeleteNodeinaBSTTest.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | import tree.TreeNode 6 | 7 | class DeleteNodeinaBSTTest extends AnyFunSuite { 8 | test("can delete node from tree") { 9 | val root = TreeNode(4) 10 | root.right = Option(TreeNode(5)) 11 | val left = TreeNode(2) 12 | root.left = Option(left) 13 | left.left = Option(TreeNode(1)) 14 | left.right = Option(TreeNode(3)) 15 | 16 | val result = DeleteNodeinaBST.deleteNode(root, 2) 17 | result.left.get.value shouldEqual 3 18 | result.left.get.left.get.value shouldEqual 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/bst/RecoverBinarySearchTreeTest.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import tree.TreeNode 6 | 7 | class RecoverBinarySearchTreeTest extends AnyFunSuite { 8 | test("can switch the tree") { 9 | val root = new TreeNode(1, Option(new TreeNode(3, None, Option(TreeNode(2)))), None) 10 | RecoverBinarySearchTree.recoverTree(root) 11 | root.value shouldEqual 3 12 | var node = root.left.get 13 | node.value shouldEqual 1 14 | node = node.right.get 15 | node.value shouldEqual 2 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/scala/bst/SameTreeTest.scala: -------------------------------------------------------------------------------- 1 | package bst 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import tree.TreeNode 6 | 7 | class SameTreeTest extends AnyFunSuite { 8 | test("can match same tree") { 9 | val p = new TreeNode(1, Option(TreeNode(2)), Option(TreeNode(3))) 10 | val q = new TreeNode(1, Option(TreeNode(2)), Option(TreeNode(3))) 11 | val result = SameTree.isSameTree(p, q) 12 | result shouldEqual true 13 | } 14 | 15 | test("can not match diff tree") { 16 | val p = new TreeNode(1, None, Option(TreeNode(3))) 17 | val q = new TreeNode(1, Option(TreeNode(3)), None) 18 | val result = SameTree.isSameTree(p, q) 19 | result shouldEqual false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/scala/bucketsort/MaximumGapTest.scala: -------------------------------------------------------------------------------- 1 | package bucketsort 2 | 3 | import bucketsort.MaximumGap 4 | import linkedlist.LinkedListNode 5 | import org.scalatest.funsuite.AnyFunSuite 6 | import org.scalatest.matchers.should.Matchers.* 7 | 8 | class MaximumGapTest extends AnyFunSuite { 9 | test("can find max gap") { 10 | val nums = Array(3, 6, 9, 1) 11 | val result = MaximumGap.maximumGap(nums) 12 | result shouldEqual 3 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/scala/bucketsort/SortCharactersByFrequencyTest.scala: -------------------------------------------------------------------------------- 1 | package bucketsort 2 | 3 | import bucketsort.SortCharactersByFrequency 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class SortCharactersByFrequencyTest extends AnyFunSuite { 8 | test("can sort string") { 9 | val str = "tree" 10 | val result = SortCharactersByFrequency.frequencySort(str); 11 | result shouldEqual "eert" 12 | } 13 | 14 | test("can sort empty string") { 15 | val str = "" 16 | val result = SortCharactersByFrequency.frequencySort(str); 17 | result shouldEqual "" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/bucketsort/TopKFrequentElementsTest.scala: -------------------------------------------------------------------------------- 1 | package bucketsort 2 | 3 | import bucketsort.TopKFrequentElements 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | import tree.TreeNode 7 | 8 | class TopKFrequentElementsTest extends AnyFunSuite { 9 | test("can take k elements") { 10 | val nums = Array(1, 1, 1, 2, 2, 3) 11 | val result = TopKFrequentElements.topKFrequent(nums, 2) 12 | result shouldEqual Array(2, 1) 13 | } 14 | 15 | test("can take 1 element") { 16 | val nums = Array(1) 17 | val result = TopKFrequentElements.topKFrequent(nums, 1) 18 | result shouldEqual Array(1) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/counting/ContainsDuplicateTest.scala: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.shouldEqual 5 | 6 | class ContainsDuplicateTest extends AnyFunSuite { 7 | test("can detect duplicates") { 8 | val nums = Array(1, 1, 1, 3, 3, 4, 3, 2, 4, 2) 9 | val result = ContainsDuplicate.containsDuplicate(nums) 10 | result shouldEqual true 11 | } 12 | 13 | test("can detect duplicates false") { 14 | val nums = Array(1, 2, 3, 4) 15 | val result = ContainsDuplicate.containsDuplicate(nums) 16 | result shouldEqual false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/counting/MajorityElement2Test.scala: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import tree.TreeNode 6 | 7 | class MajorityElement2Test extends AnyFunSuite { 8 | test("can find majorities") { 9 | val nums = Array(1, 1, 2, 2, 3) 10 | val result = MajorityElement2.majorityElement(nums) 11 | result shouldEqual List(1, 2) 12 | } 13 | 14 | test("can find majority") { 15 | val nums = Array(3, 2, 3) 16 | val result = MajorityElement2.majorityElement(nums) 17 | result shouldEqual List(3) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/counting/MajorityElementTest.scala: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class MajorityElementTest extends AnyFunSuite { 7 | test("can find major") { 8 | val nums = Array(3, 2, 3) 9 | val result = MajorityElement.majorityElement(nums) 10 | result shouldEqual 3 11 | } 12 | 13 | test("can find major in longer array") { 14 | val nums = Array(2, 2, 1, 1, 1, 2, 2) 15 | val result = MajorityElement.majorityElement(nums) 16 | result shouldEqual 2 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/counting/RansomNoteTest.scala: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class RansomNoteTest extends AnyFunSuite { 7 | test("can construct the rasom note") { 8 | val ransom = "aa" 9 | val magazine = "aab" 10 | val result = RansomNote.canConstruct(ransom, magazine) 11 | result shouldEqual true 12 | } 13 | 14 | test("can not construct the rasom note") { 15 | val ransom = "aabb" 16 | val magazine = "aab" 17 | val result = RansomNote.canConstruct(ransom, magazine) 18 | result shouldEqual false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/counting/RearrangeStringkDistanceApartTest.scala: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class RearrangeStringkDistanceApartTest extends AnyFunSuite { 7 | test("can rearrange string") { 8 | val s = "aabbcc" 9 | val result = RearrangeStringkDistanceApart.rearrangeString(s, 3) 10 | result shouldEqual "abcabc" 11 | } 12 | 13 | test("can not rearrange string") { 14 | val s = "aaabc" 15 | val result = RearrangeStringkDistanceApart.rearrangeString(s, 3) 16 | result shouldEqual "" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/dfs/SumRoottoLeafNumbersTest.scala: -------------------------------------------------------------------------------- 1 | package dfs 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import tree.TreeNode 6 | 7 | class SumRoottoLeafNumbersTest extends AnyFunSuite { 8 | test("can sum root to left numbers") { 9 | val root = TreeNode(4) 10 | root.right = Option(TreeNode(0)) 11 | val left = TreeNode(9) 12 | root.left = Option(left) 13 | left.left = Option(TreeNode(5)) 14 | left.right = Option(TreeNode(1)) 15 | val result = SumRoottoLeafNumbers.sumNumbers(root) 16 | result shouldEqual 1026 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/dfs/WordLadderTest.scala: -------------------------------------------------------------------------------- 1 | package dfs 2 | 3 | import dfs.WordLadder 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class WordLadderTest extends AnyFunSuite { 8 | test("can find word ladder") { 9 | val words = List("hot","dot","dog","lot","log","cog") 10 | val result = WordLadder.ladderLength("hit", "cog", words) 11 | result shouldEqual 5 12 | } 13 | 14 | test("can not find word ladder") { 15 | val words = List("hot","doz","dog","loz","log","cog") 16 | val result = WordLadder.ladderLength("hit", "cog", words) 17 | result shouldEqual 0 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/dp/BestTimetoBuyandSellStock3Test.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class BestTimetoBuyandSellStock3Test extends AnyFunSuite { 7 | test("can not find best time") { 8 | val prices = Array(7, 6, 4, 3, 1) 9 | val result = BestTimetoBuyandSellStock3.maxProfit(prices) 10 | result shouldEqual 0 11 | } 12 | 13 | test("can find best time") { 14 | val prices = Array(3, 3, 5, 0, 0, 3, 1, 4) 15 | val result = BestTimetoBuyandSellStock3.maxProfit(prices) 16 | result shouldEqual 6 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/dp/BestTimetoBuyandSellStock4Test.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.shouldEqual 5 | 6 | class BestTimetoBuyandSellStock4Test extends AnyFunSuite { 7 | test("can get max profit") { 8 | val prices = Array(2, 4, 1) 9 | val k = 2 10 | val result = BestTimetoBuyandSellStock4.maxProfit(k, prices) 11 | result shouldEqual 2 12 | } 13 | 14 | test("can get max profit 2") { 15 | val prices = Array(3, 2, 6, 5, 0, 3) 16 | val k = 2 17 | val result = BestTimetoBuyandSellStock4.maxProfit(k, prices) 18 | result shouldEqual 7 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/dp/ClimbingStairsTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class ClimbingStairsTest extends AnyFunSuite { 7 | test("can handle 2") { 8 | val result = ClimbingStairs.climbStairs(2) 9 | result shouldEqual 2 10 | } 11 | 12 | test("can handle 3") { 13 | val result = ClimbingStairs.climbStairs(3) 14 | result shouldEqual 3 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/dp/CoinChange2Test.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.shouldEqual 5 | 6 | class CoinChange2Test extends AnyFunSuite { 7 | test("can get the change") { 8 | val coins = Array(1, 2, 5) 9 | val amount = 5 10 | val result = CoinChange2.change(amount, coins) 11 | result shouldEqual 4 12 | } 13 | 14 | test("can not get the change") { 15 | val coins = Array(2) 16 | val amount = 3 17 | val result = CoinChange2.change(amount, coins) 18 | result shouldEqual 0 19 | } 20 | 21 | test("can get 1 change") { 22 | val coins = Array(10) 23 | val amount = 10 24 | val result = CoinChange2.change(amount, coins) 25 | result shouldEqual 1 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/scala/dp/CoinChangeTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class CoinChangeTest extends AnyFunSuite { 7 | test("can get the min number") { 8 | val coins = Array(1, 2, 5) 9 | val amount = 11 10 | val result = CoinChange.coinChange(coins, amount) 11 | result shouldEqual 3 12 | } 13 | 14 | test("can handle negative case") { 15 | val coins = Array(2) 16 | val amount = 3 17 | val result = CoinChange.coinChange(coins, amount) 18 | result shouldEqual -1 19 | } 20 | 21 | test("can handle 0 amount") { 22 | val coins = Array(2) 23 | val amount = 0 24 | val result = CoinChange.coinChange(coins, amount) 25 | result shouldEqual 0 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/scala/dp/DecodeWaysTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class DecodeWaysTest extends AnyFunSuite { 7 | test("can decode two ways") { 8 | val s = "223" 9 | val result = DecodeWays.numDecodings(s) 10 | result shouldEqual 3 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/dp/DistinctSubsequencesTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class DistinctSubsequencesTest extends AnyFunSuite { 7 | test("can find rabbit") { 8 | val (s, t) = ("rabbbit", "rabbit") 9 | val result = DistinctSubsequences.numDistinct(s, t) 10 | result shouldEqual 3 11 | } 12 | 13 | test("can find babgbag") { 14 | val (s, t) = ("babgbag", "bag") 15 | val result = DistinctSubsequences.numDistinct(s, t) 16 | result shouldEqual 5 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/dp/DungeonGameTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class DungeonGameTest extends AnyFunSuite { 7 | test("can find min hp") { 8 | val dungeon = Array(Array(-2, -3, 3), Array(-5, -10, 1), Array(10, 30, -5)) 9 | val result = DungeonGame.calculateMinimumHP(dungeon) 10 | result shouldEqual 7 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/dp/JumpGameTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class JumpGameTest extends AnyFunSuite { 7 | test("can test jump true") { 8 | val nums = Array(2, 3, 1, 1, 4) 9 | val result = JumpGame.canJump(nums) 10 | result shouldEqual true 11 | } 12 | 13 | test("can test jump false") { 14 | val nums = Array(3, 2, 1, 0, 4) 15 | val result = JumpGame.canJump(nums) 16 | result shouldEqual false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/dp/LongestPalindromicSubsequenceTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.shouldEqual 5 | 6 | class LongestPalindromicSubsequenceTest extends AnyFunSuite { 7 | test("can get longest subsequence") { 8 | val s = "bbbab" 9 | val result = LongestPalindromicSubsequence.longestPalindromeSubseq(s) 10 | result shouldEqual 4 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/dp/LongestPalindromicSubstringTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class LongestPalindromicSubstringTest extends AnyFunSuite { 7 | test("can find the longest palindromic substring") { 8 | val s = "babad" 9 | val result = LongestPalindromicSubstring.longestPalindrome(s) 10 | result shouldEqual "aba" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/dp/MaximumSubarrayTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class MaximumSubarrayTest extends AnyFunSuite { 7 | test("can find the max sub array") { 8 | val nums = Array(-2, 1, -3, 4, -1, 2, 1, -5, 4) 9 | val result = MaximumSubarray.maxSubArray(nums) 10 | result shouldEqual 6 11 | } 12 | 13 | test("can find the max sub array case 2") { 14 | val nums = Array(5, 4, -1, 7, 8) 15 | val result = MaximumSubarray.maxSubArray(nums) 16 | result shouldEqual 23 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/dp/MinimumPathSumTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class MinimumPathSumTest extends AnyFunSuite { 7 | test("can get the min sum") { 8 | val nums = Array(Array(1, 3, 1), Array(1, 5, 1), Array(4, 2, 1)) 9 | val result = MinimumPathSum.minPathSum(nums) 10 | result shouldEqual 7 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/dp/TargetSumTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.shouldEqual 5 | 6 | class TargetSumTest extends AnyFunSuite { 7 | test("can get sum") { 8 | val nums = Array(1, 1, 1, 1, 1) 9 | val target = 3 10 | val result = TargetSum.findTargetSumWays(nums, target) 11 | result shouldEqual 5 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/dp/TriangleTest.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class TriangleTest extends AnyFunSuite { 7 | test("can find path simple") { 8 | val triangle = List(List(2), List(3, 4)) 9 | val result = Triangle.minimumTotal(triangle) 10 | result shouldEqual 5 11 | } 12 | 13 | test("can find path") { 14 | val triangle = List(List(2), List(3, 4), List(6, 5, 7), List(4, 1, 8, 3)) 15 | val result = Triangle.minimumTotal(triangle) 16 | result shouldEqual 11 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/dp/ValidPalindrome3Test.scala: -------------------------------------------------------------------------------- 1 | package dp 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.shouldEqual 5 | 6 | class ValidPalindrome3Test extends AnyFunSuite { 7 | test("can find valid palindrome") { 8 | val s = "abcdeca" 9 | val k = 2 10 | val result = ValidPalindrome3.isPalindrome(s, k) 11 | result shouldEqual true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/fastslowpointers/MiddleoftheLinkedListTest.scala: -------------------------------------------------------------------------------- 1 | package fastslowpointers 2 | 3 | import linkedlist.LinkedListNode 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers._ 6 | 7 | class MiddleoftheLinkedListTest extends org.scalatest.funsuite.AnyFunSuite { 8 | test("can find the middle of the list") { 9 | val node = new LinkedListNode(1, None) 10 | node.append(2).append(3).append(4).append(5) 11 | val result = MiddleoftheLinkedList.middleNode(node) 12 | result.value shouldEqual 3 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/scala/graph/CourseSchedule2Test.scala: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class CourseSchedule2Test extends AnyFunSuite { 7 | test("can find the schedule") { 8 | val values = Array(Array(1, 0), Array(2, 0), Array(3, 1), Array(3, 2)) 9 | val result = CourseSchedule2.findOrder(4, values) 10 | result shouldEqual Array(0, 1, 2, 3) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/graph/CourseScheduleTest.scala: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class CourseScheduleTest extends AnyFunSuite { 7 | test("can finish") { 8 | val values = Array(Array(1, 0)) 9 | val result = CourseSchedule.canFinish(2, values) 10 | result shouldEqual true 11 | } 12 | 13 | test("can not finish") { 14 | val values = Array(Array(1, 0), Array(0, 1)) 15 | val result = CourseSchedule.canFinish(2, values) 16 | result shouldEqual false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/graph/MinimumHeightTreesTest.scala: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class MinimumHeightTreesTest extends AnyFunSuite { 7 | test("can get MHT") { 8 | val edges = Array(Array(1, 0), Array(1, 2), Array(1, 3)) 9 | val result = MinimumHeightTrees.findMinHeightTrees(4, edges) 10 | result shouldEqual List(1) 11 | } 12 | 13 | test("can get MHT 2") { 14 | val edges = Array(Array(3, 0), Array(3, 1), Array(3, 2), Array(3, 4), Array(5, 4)) 15 | val result = MinimumHeightTrees.findMinHeightTrees(6, edges) 16 | result shouldEqual List(3, 4) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/greedy/CandyTest.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class CandyTest extends AnyFunSuite { 7 | test("can get from normal list") { 8 | val ratings = Array(1, 2, 2) 9 | val result = Candy.candy(ratings) 10 | result shouldEqual 4 11 | } 12 | 13 | test("can get from backtrack list") { 14 | val ratings = Array(1, 0, 2) 15 | val result = Candy.candy(ratings) 16 | result shouldEqual 5 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/greedy/CourseSchedule3Test.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.shouldEqual 5 | 6 | class CourseSchedule3Test extends AnyFunSuite { 7 | test("can find the schedule") { 8 | val courses = Array(Array(100, 200), Array(200, 1300), Array(1000, 1250), Array(2000, 3200)) 9 | val result = CourseSchedule3.scheduleCourse(courses) 10 | result shouldEqual 3 11 | } 12 | 13 | test("can not find the schedule") { 14 | val courses = Array(Array(3, 2), Array(4, 3)) 15 | val result = CourseSchedule3.scheduleCourse(courses) 16 | result shouldEqual 0 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/greedy/GasStationTest.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class GasStationTest extends AnyFunSuite { 7 | test("can travel in cycle") { 8 | val gas = Array(1, 2, 3, 4, 5) 9 | val cost = Array(3, 4, 5, 1, 2) 10 | val result = GasStation.canCompleteCircuit(gas, cost) 11 | result shouldEqual 3 12 | } 13 | 14 | test("can not travel in cycle") { 15 | val gas = Array(2, 3, 4) 16 | val cost = Array(3, 4, 3) 17 | val result = GasStation.canCompleteCircuit(gas, cost) 18 | result shouldEqual -1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/greedy/LargestNumberTest.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class LargestNumberTest extends AnyFunSuite { 7 | test("can get largest number") { 8 | val nums = Array(10, 2) 9 | val result = LargestNumber.largestNumber(nums) 10 | result shouldEqual "210" 11 | } 12 | 13 | test("can get largest number with random order") { 14 | val nums = Array(3, 30, 34, 5, 9) 15 | val result = LargestNumber.largestNumber(nums) 16 | result shouldEqual "9534330" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/greedy/WildcardMatchingTest.scala: -------------------------------------------------------------------------------- 1 | package greedy 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class WildcardMatchingTest extends AnyFunSuite { 7 | test("can match without wildcard") { 8 | val s = "aa" 9 | val p = "a" 10 | val result = WildcardMatching.isMatch(s, p) 11 | result shouldEqual false 12 | } 13 | 14 | test("can match with *") { 15 | val s = "aa" 16 | val p = "*" 17 | val result = WildcardMatching.isMatch(s, p) 18 | result shouldEqual true 19 | } 20 | 21 | test("can match with ?") { 22 | val s = "cb" 23 | val p = "?a" 24 | val result = WildcardMatching.isMatch(s, p) 25 | result shouldEqual false 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/scala/hashmap/BrickWallTest.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class BrickWallTest extends AnyFunSuite { 7 | test("can find the min number") { 8 | val wall = List(List(1, 2, 2, 1), List(3, 1, 2), List(1, 3, 2), List(2, 4), List(3, 1, 2), List(1, 3, 1, 1)) 9 | val result = BrickWall.leastBricks(wall) 10 | result shouldEqual 2 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/hashmap/BullsandCowsTest.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class BullsandCowsTest extends AnyFunSuite { 7 | test("can find bulls and cows") { 8 | val (secret, guess) = ("1807", "7810") 9 | val result = BullsandCows.getHint(secret, guess) 10 | result shouldEqual "1A3B" 11 | } 12 | 13 | test("can find when there duplicates") { 14 | val (secret, guess) = ("1123", "0111") 15 | val result = BullsandCows.getHint(secret, guess) 16 | result shouldEqual "1A1B" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/hashmap/FirstUniqCharTest.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class FirstUniqCharTest extends AnyFunSuite { 7 | test("can find the 1st unqiue character") { 8 | val data = "leetcode" 9 | val result = FirstUniqChar.firstUniqChar(data) 10 | result shouldEqual 0 11 | } 12 | 13 | test("can find the 1st unique character 2") { 14 | val data = "leetcodel" 15 | val result = FirstUniqChar.firstUniqChar(data) 16 | result shouldEqual 3 17 | } 18 | 19 | test("can throw exception if there is no unique chacter") { 20 | val data = "aabb" 21 | val result = FirstUniqChar.firstUniqChar(data) 22 | result shouldEqual -1 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/scala/hashmap/HappyNumberTest.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class HappyNumberTest extends AnyFunSuite { 7 | test("can handle 1") { 8 | HappyNumber.isHappy(1) shouldEqual true 9 | } 10 | 11 | test("can handle 0") { 12 | HappyNumber.isHappy(0) shouldEqual false 13 | } 14 | 15 | test("can handle 19") { 16 | HappyNumber.isHappy(19) shouldEqual true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/hashmap/InsertDeleteGetRandomO1Test.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class InsertDeleteGetRandomO1Test extends AnyFunSuite { 7 | test("can function as required") { 8 | val set = new InsertDeleteGetRandomO1() 9 | set.insert(1) shouldEqual true 10 | set.remove(2) shouldEqual false 11 | set.insert(2) shouldEqual true 12 | set.remove(1) shouldEqual true 13 | set.insert(2) shouldEqual false 14 | set.getRandom shouldEqual 2 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/hashmap/IsomorphicStringsTest.scala: -------------------------------------------------------------------------------- 1 | package hashmap 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class IsomorphicStringsTest extends AnyFunSuite { 7 | test("can detect a valid one") { 8 | val (s, t) = ("egg", "add") 9 | val result = IsomorphicStrings.isIsomorphic(s, t) 10 | result shouldEqual true 11 | } 12 | 13 | test("can detect an invalid case") { 14 | val (s, t) = ("foo", "bar") 15 | val result = IsomorphicStrings.isIsomorphic(s, t) 16 | result shouldEqual false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/heap/KthLargestElementinanArrayTest.scala: -------------------------------------------------------------------------------- 1 | package heap 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import tree.TreeNode 6 | 7 | class KthLargestElementinanArrayTest extends AnyFunSuite { 8 | test("can find kth largest element in unique array") { 9 | val nums = Array(3, 2, 1, 5, 6, 4) 10 | val result = KthLargestElementinanArray.findKthLargest(nums, 2) 11 | result shouldEqual 5 12 | } 13 | 14 | test("can find kth largest element in non-unique array") { 15 | val nums = Array(3, 2, 3, 1, 2, 4, 5, 5, 6) 16 | val result = KthLargestElementinanArray.findKthLargest(nums, 4) 17 | result shouldEqual 4 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/heap/TheSkylineProblemTest.scala: -------------------------------------------------------------------------------- 1 | package heap 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import tree.TreeNode 6 | 7 | class TheSkylineProblemTest extends AnyFunSuite { 8 | test("can find the sky line") { 9 | val buildings = Array(Array(0, 2, 3), Array(2, 5, 3)) 10 | val result = TheSkylineProblem.getSkyline(buildings) 11 | result shouldEqual List(List(0, 3), List(5, 0)) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/heap/UglyNumber2Test.scala: -------------------------------------------------------------------------------- 1 | package heap 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import tree.TreeNode 6 | 7 | class UglyNumber2Test extends AnyFunSuite { 8 | test("can find a small ugly number") { 9 | val result = UglyNumber2.nthUglyNumber(4) 10 | result shouldEqual 4 11 | } 12 | 13 | test("can find a big ugly number") { 14 | val result = UglyNumber2.nthUglyNumber(10) 15 | result shouldEqual 12 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/scala/linkedlist/RemoveDuplicatesfromSortedListIITest.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class RemoveDuplicatesfromSortedListIITest extends AnyFunSuite { 7 | test("can remove duplicates") { 8 | val head = new LinkedListNode[Int](1, None) 9 | head.append(2).append(3).append(3).append(4).append(4).append(5) 10 | var result = RemoveDuplicatesfromSortedListII.deleteDuplicates(head); 11 | result.value shouldEqual 1 12 | result = result.next.get 13 | result.value shouldEqual 2 14 | result = result.next.get 15 | result.value shouldEqual 3 16 | result = result.next.get 17 | result.value shouldEqual 5 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/linkedlist/ReorderListTest.scala: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class ReorderListTest extends AnyFunSuite { 7 | test("can reorder list") { 8 | val head = new LinkedListNode[Int](1, None) 9 | head.append(2).append(3).append(4).append(5) 10 | ReorderList.reorderList(head) 11 | head.value shouldEqual 1 12 | var next = head.next.get 13 | next.value shouldEqual 5 14 | next = next.next.get 15 | next.value shouldEqual 2 16 | next = next.next.get 17 | next.value shouldEqual 4 18 | next = next.next.get 19 | next.value shouldEqual 3 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/scala/math/ExcelSheetColumnNumberTest.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class ExcelSheetColumnNumberTest extends AnyFunSuite { 7 | test("can get A") { 8 | val result = ExcelSheetColumnNumber.titleToNumber("A") 9 | result shouldEqual 1 10 | } 11 | 12 | test("can get FXSHRXW") { 13 | val result = ExcelSheetColumnNumber.titleToNumber("FXSHRXW") 14 | result shouldEqual 2147483647 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/math/ExcelSheetColumnTitleTest.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class ExcelSheetColumnTitleTest extends AnyFunSuite { 7 | test("can convert to 1 letter") { 8 | val result = ExcelSheetColumnTitle.convertToTitle(1) 9 | result shouldEqual "A" 10 | } 11 | 12 | test("can convert big number") { 13 | val result = ExcelSheetColumnTitle.convertToTitle(2147483647) 14 | result shouldEqual "FXSHRXW" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/math/FactorialTrailingZeroesTest.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | // 172. Factorial Trailing Zeroes 7 | class FactorialTrailingZeroesTest extends AnyFunSuite { 8 | test("get for less than 5") { 9 | val result = FactorialTrailingZeroes.trailingZeroes(4) 10 | result shouldEqual 0 11 | } 12 | 13 | test("get for greater than 5") { 14 | val result = FactorialTrailingZeroes.trailingZeroes(100) 15 | result shouldEqual 24 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/scala/math/Fraction2RecurringDecimalTest.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class Fraction2RecurringDecimalTest extends AnyFunSuite { 7 | test("can handle large numerator") { 8 | val result = Fraction2RecurringDecimal.fractionToDecimal(2, 1) 9 | result shouldEqual "2" 10 | } 11 | 12 | test("can handle smarl numerator") { 13 | val result = Fraction2RecurringDecimal.fractionToDecimal(1, 2) 14 | result shouldEqual "0.5" 15 | } 16 | 17 | test("can handle repeating") { 18 | val result = Fraction2RecurringDecimal.fractionToDecimal(2, 3) 19 | result shouldEqual "0.(6)" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/scala/math/Integer2RomanTest.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class Integer2RomanTest extends AnyFunSuite { 7 | test("can convert 1994") { 8 | val num = 1994 9 | val result = Integer2Roman.intToRoman(num) 10 | result shouldEqual "MCMXCIV" 11 | } 12 | 13 | test("can convert 3") { 14 | val num = 3 15 | val result = Integer2Roman.intToRoman(num) 16 | result shouldEqual "III" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/math/MaxPointsonaLineTest.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class MaxPointsonaLineTest extends AnyFunSuite { 7 | test("can find 3 points") { 8 | val points = Array(Array(1, 1), Array(2, 2), Array(3, 3)) 9 | val result = MaxPointsonaLine.maxPoints(points) 10 | result shouldEqual 3 11 | } 12 | 13 | test("can find 4 points") { 14 | val points = Array(Array(1, 1), Array(3, 2), Array(5, 3), Array(4, 1), Array(2, 3), Array(1, 4)) 15 | val result = MaxPointsonaLine.maxPoints(points) 16 | result shouldEqual 4 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/math/PlusOneTest.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class PlusOneTest extends AnyFunSuite { 7 | test("can plus 1") { 8 | val digits = Array(1, 2, 3) 9 | val result = PlusOne.plusOne(digits) 10 | result shouldEqual Array(1, 2, 4) 11 | } 12 | 13 | test("can plus 1 with 9") { 14 | val digits = Array(1, 2, 9) 15 | val result = PlusOne.plusOne(digits) 16 | result shouldEqual Array(1, 3, 0) 17 | } 18 | 19 | test("can plus 1 with 999") { 20 | val digits = Array(9, 9, 9) 21 | val result = PlusOne.plusOne(digits) 22 | result shouldEqual Array(1, 0, 0, 0) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/scala/math/PowXnTest.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class PowXnTest extends AnyFunSuite { 7 | test("can calculate power") { 8 | val x = 2.0 9 | val n = 10 10 | val result = PowXn.myPow(x, n) 11 | result shouldEqual 1024.0 12 | } 13 | 14 | test("can calculate odd power") { 15 | val x = 2.0 16 | val n = 9 17 | val result = PowXn.myPow(x, n) 18 | result shouldEqual 512.0 19 | } 20 | 21 | test("can calculate neagive power") { 22 | val x = 2.0 23 | val n = -2 24 | val result = PowXn.myPow(x, n) 25 | result shouldEqual 0.25 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/scala/math/Roman2IntegerTest.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class Roman2IntegerTest extends AnyFunSuite { 7 | test("can convert MCMXCIV") { 8 | val roman = "MCMXCIV" 9 | val result = Roman2Integer.romanToInt(roman) 10 | result shouldEqual 1994 11 | } 12 | 13 | test("can convert III") { 14 | val roman = "III" 15 | val result = Roman2Integer.romanToInt(roman) 16 | result shouldEqual 3 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/math/UniqueBinarySearchTreesTest.scala: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class UniqueBinarySearchTreesTest extends AnyFunSuite { 7 | test("can get 3") { 8 | val result = UniqueBinarySearchTrees.numTrees(3) 9 | result shouldEqual 5 10 | } 11 | 12 | test("can get 4") { 13 | val result = UniqueBinarySearchTrees.numTrees(4) 14 | result shouldEqual 14 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/matrix/Searcha2DMatrixTest.scala: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class Searcha2DMatrixTest extends AnyFunSuite { 8 | test("can find target in 2d matrix") { 9 | val matrix = Array(Array(1, 3, 5, 7), Array(10, 11, 16, 20), Array(23, 30, 34, 60)) 10 | val result = Searcha2DMatrix.searchMatrix(matrix, 3) 11 | result shouldEqual true 12 | } 13 | 14 | test("can not find target in 2d matrix") { 15 | val matrix = Array(Array(1, 3, 5, 7), Array(10, 11, 16, 20), Array(23, 30, 34, 60)) 16 | val result = Searcha2DMatrix.searchMatrix(matrix, 13) 17 | println(s"result=$result") 18 | result shouldEqual false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/matrix/SetMatrixZeroesTest.scala: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class SetMatrixZeroesTest extends AnyFunSuite { 8 | test("can set matrix zero for central zeros") { 9 | val m = Array(Array(1, 1, 1), Array(1, 0, 1), Array(1, 1, 1)) 10 | SetMatrixZeroes.setZeroes(m) 11 | m.foreach { line => println(line.mkString(" ")) } 12 | } 13 | 14 | test("can set matrix zero for edge zeros") { 15 | val m = Array(Array(0, 1, 2, 0), Array(3, 4, 5, 2), Array(1, 3, 1, 5)) 16 | SetMatrixZeroes.setZeroes(m) 17 | m.foreach { line => println(line.mkString(" ")) } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/matrix/SpiralMatrix2Test.scala: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class SpiralMatrix2Test extends AnyFunSuite { 8 | test("can handle 1") { 9 | val result = SpiralMatrix2.generateMatrix(1) 10 | result.foreach(line => println(line.mkString(" "))) 11 | } 12 | 13 | test("can handle 2") { 14 | val result = SpiralMatrix2.generateMatrix(2) 15 | result.foreach(line => println(line.mkString(" "))) 16 | } 17 | 18 | test("can handle 3") { 19 | val result = SpiralMatrix2.generateMatrix(3) 20 | result.foreach(line => println(line.mkString(" "))) 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/test/scala/matrix/SpiralMatrixTest.scala: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class SpiralMatrixTest extends AnyFunSuite { 8 | test("can transpose matrix") { 9 | val matrix = Array(Array(1, 2, 3, 4, 5), Array(6, 7, 8, 9, 10), Array(11, 12, 13, 14, 15)) 10 | val result = SpiralMatrix.spiralOrder(matrix) 11 | result shouldEqual List(1, 2, 3, 4, 5, 10, 15, 14, 13, 12, 11, 6, 7, 8, 9) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/monotonicstack/LargestRectangleinHistogramTest.scala: -------------------------------------------------------------------------------- 1 | package monotonicstack 2 | 3 | import monotonicstack.LargestRectangleinHistogram 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | import stack.MinStack 7 | 8 | class LargestRectangleinHistogramTest extends AnyFunSuite { 9 | test("can find largest rect") { 10 | val heights = Array(2, 4) 11 | val result = LargestRectangleinHistogram.largestRectangleArea(heights) 12 | result shouldEqual 4 13 | } 14 | 15 | test("can find largest rect 2") { 16 | val heights = Array(2, 1, 5, 6, 2, 3) 17 | val result = LargestRectangleinHistogram.largestRectangleArea(heights) 18 | result shouldEqual 10 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/monotonicstack/NextGreaterElement2Test.scala: -------------------------------------------------------------------------------- 1 | package monotonicstack 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.shouldEqual 5 | 6 | class NextGreaterElement2Test extends AnyFunSuite { 7 | test("can get next greater element") { 8 | val nums = Array(1, 2, 1) 9 | val result = NextGreaterElement2.nextGreaterElements(nums) 10 | result shouldEqual Array(2, -1, 2) 11 | } 12 | 13 | test("can get next greater element 2") { 14 | val nums = Array(1, 2, 3, 4, 3) 15 | val result = NextGreaterElement2.nextGreaterElements(nums) 16 | result shouldEqual Array(2, 3, 4, -1, 4) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/monotonicstack/NextGreaterElement3Test.scala: -------------------------------------------------------------------------------- 1 | package monotonicstack 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.shouldEqual 5 | 6 | class NextGreaterElement3Test extends AnyFunSuite { 7 | test("can find next greater element") { 8 | val n = 12 9 | val result = NextGreaterElement3.nextGreaterElement(n) 10 | result shouldEqual 21 11 | } 12 | 13 | test("can not find next greater element") { 14 | val n = 21 15 | val result = NextGreaterElement3.nextGreaterElement(n) 16 | result shouldEqual -1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/monotonicstack/NextGreaterElementTest.scala: -------------------------------------------------------------------------------- 1 | package monotonicstack 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | 7 | class NextGreaterElementTest extends AnyFunSuite { 8 | test("can find with head not valid") { 9 | val nums1 = Array(4, 1, 2) 10 | val nums2 = Array(1, 3, 4, 2) 11 | val expected = Array(-1, 3, -1) 12 | val actual = NextGreaterElement.nextGreaterElement(nums1, nums2) 13 | actual shouldEqual expected 14 | } 15 | 16 | test("can find with end not valid") { 17 | val nums1 = Array(2, 4) 18 | val nums2 = Array(1, 2, 3, 4) 19 | val expected = Array(3, -1) 20 | val actual = NextGreaterElement.nextGreaterElement(nums1, nums2) 21 | actual shouldEqual expected 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/scala/number/MultiplyStringsTest.scala: -------------------------------------------------------------------------------- 1 | package number 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class MultiplyStringsTest extends AnyFunSuite { 7 | test("can calculate 1 digit mutiple 4 digits") { 8 | val num1 = "2468" 9 | val num2 = "3" 10 | val result = MultiplyStrings.multiply(num1, num2) 11 | result shouldEqual "7404" 12 | } 13 | 14 | test("can calculate 2 digit mutiple 4 digits") { 15 | val num1 = "2468" 16 | val num2 = "32" 17 | val result = MultiplyStrings.multiply(num1, num2) 18 | result shouldEqual "78976" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/number/PalindromeNumberTest.scala: -------------------------------------------------------------------------------- 1 | package number 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class PalindromeNumberTest extends AnyFunSuite { 7 | test("can verify single digit number") { 8 | PalindromeNumber.isPalindrome(5) shouldEqual true 9 | } 10 | 11 | test("can verify palindrome number") { 12 | PalindromeNumber.isPalindrome(919) shouldEqual true 13 | } 14 | 15 | test("can verify palindrome number - failure") { 16 | PalindromeNumber.isPalindrome(9191) shouldEqual false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/number/ReverseIntegerTest.scala: -------------------------------------------------------------------------------- 1 | package number 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class ReverseIntegerTest extends AnyFunSuite { 7 | test("can reverse single digit number") { 8 | ReverseInteger.reverse(1) shouldEqual 1 9 | } 10 | 11 | test("can reverse number with more than 1 digit") { 12 | ReverseInteger.reverse(198) shouldEqual 891 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/scala/orderedset/MyCalendar2Test.scala: -------------------------------------------------------------------------------- 1 | package orderedset 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class MyCalendar2Test extends AnyFunSuite { 7 | test("can add no overlap") { 8 | val cal = new MyCalendar2() 9 | cal.book(10, 20) shouldEqual true 10 | cal.book(30, 40) shouldEqual true 11 | } 12 | 13 | test("can add 1 overlap") { 14 | val cal = new MyCalendar2() 15 | cal.book(10, 30) shouldEqual true 16 | cal.book(20, 40) shouldEqual true 17 | } 18 | 19 | test("can NOT add 2 overlaps") { 20 | val cal = new MyCalendar2() 21 | cal.book(10, 30) shouldEqual true 22 | cal.book(20, 40) shouldEqual true 23 | cal.book(25, 60) shouldEqual false 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/scala/orderedset/MyCalendar3Test.scala: -------------------------------------------------------------------------------- 1 | package orderedset 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class MyCalendar3Test extends AnyFunSuite { 7 | test("can detect the max") { 8 | val calendar = new MyCalendar3() 9 | calendar.book(10, 20) shouldEqual 1 10 | calendar.book(50, 60) shouldEqual 1 11 | calendar.book(10, 40) shouldEqual 2 12 | calendar.book(5, 15) shouldEqual 3 13 | calendar.book(5, 10) shouldEqual 3 14 | calendar.book(25, 55) shouldEqual 3 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/orderedset/MyCalendarTest.scala: -------------------------------------------------------------------------------- 1 | package orderedset 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class MyCalendarTest extends AnyFunSuite { 7 | test("can add non-overlap") { 8 | val cal = new MyCalendar() 9 | cal.book(10, 20) shouldEqual true 10 | cal.book(30, 40) shouldEqual true 11 | } 12 | 13 | test("can not add if start overlap") { 14 | val cal = new MyCalendar() 15 | cal.book(10, 20) shouldEqual true 16 | cal.book(15, 30) shouldEqual false 17 | } 18 | 19 | test("can not add if end overlap") { 20 | val cal = new MyCalendar() 21 | cal.book(30, 40) shouldEqual true 22 | cal.book(10, 35) shouldEqual false 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/scala/prefixsum/ContiguousArrayTest.scala: -------------------------------------------------------------------------------- 1 | package prefixsum 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class ContiguousArrayTest extends AnyFunSuite { 8 | test("can find contiguous array") { 9 | val nums = Array(0, 1, 0) 10 | val result = ContiguousArray.findMaxLength(nums) 11 | result shouldEqual 2 12 | } 13 | 14 | test("can find odd distributed contiguous array") { 15 | val nums = Array(0, 0, 0, 0, 0, 1, 1, 1, 1) 16 | val result = ContiguousArray.findMaxLength(nums) 17 | result shouldEqual 8 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/prefixsum/ContinuousSubarraySumTest.scala: -------------------------------------------------------------------------------- 1 | package prefixsum 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class ContinuousSubarraySumTest extends AnyFunSuite { 8 | test("can find sub array") { 9 | val nums = Array(23, 2, 4, 6, 7) 10 | val result = ContinuousSubarraySum.checkSubarraySum(nums, 6) 11 | result shouldEqual true 12 | } 13 | 14 | test("can not find sub array") { 15 | val nums = Array(23, 2, 6, 4, 7) 16 | val result = ContinuousSubarraySum.checkSubarraySum(nums, 13) 17 | result shouldEqual false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/prefixsum/FindPivotIndexTest.scala: -------------------------------------------------------------------------------- 1 | package prefixsum 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class FindPivotIndexTest extends AnyFunSuite { 8 | test("can find the pivot index") { 9 | val nums = Array(1, 7, 3, 6, 5, 6) 10 | val result = FindPivotIndex.pivotIndex(nums) 11 | result shouldEqual 3 12 | } 13 | 14 | test("can not find the pivot index") { 15 | val nums = Array(1, 2, 3) 16 | val result = FindPivotIndex.pivotIndex(nums) 17 | result shouldEqual -1 18 | } 19 | 20 | test("can find the pivot index at 0") { 21 | val nums = Array(2, 1, -1) 22 | val result = FindPivotIndex.pivotIndex(nums) 23 | result shouldEqual 0 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/scala/prefixsum/RangeSumQueryImmutableTest.scala: -------------------------------------------------------------------------------- 1 | package prefixsum 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class RangeSumQueryImmutableTest extends AnyFunSuite { 8 | test("can query range sum") { 9 | val nums = Array(-2, 0, 3, -5, 2, -1) 10 | val query = new RangeSumQueryImmutable(nums) 11 | val result = query.sumRange(0, 2) 12 | result shouldEqual 1 13 | } 14 | 15 | test("can query range sum in between") { 16 | val nums = Array(-2, 0, 3, -5, 2, -1) 17 | val query = new RangeSumQueryImmutable(nums) 18 | val result = query.sumRange(2, 5) 19 | result shouldEqual -1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/scala/queue/Dota2SenateTest.scala: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class Dota2SenateTest extends AnyFunSuite { 8 | test("can vote with same number of D and R") { 9 | val senate = "RD" 10 | val result = Dota2Senate.predictPartyVictory(senate) 11 | result shouldEqual "Radiant" 12 | } 13 | 14 | test("can vote with diff number of D and R") { 15 | val senate = "RDD" 16 | val result = Dota2Senate.predictPartyVictory(senate) 17 | result shouldEqual "Dire" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/queue/MyQueueTest.scala: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class MyQueueTest extends AnyFunSuite { 8 | test("can work as queue") { 9 | val queue = new MyQueue[Integer]() 10 | queue.push(1) 11 | queue.push(2) 12 | val peek = queue.peek() 13 | peek shouldEqual 1 14 | val pop = queue.pop() 15 | pop shouldEqual 1 16 | val empty = queue.empty() 17 | empty shouldEqual false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/queue/MyStackTest.scala: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class MyStackTest extends AnyFunSuite { 8 | test("can behave as a stack") { 9 | val mystack = new MyStack[Integer]() 10 | mystack.push(1) 11 | mystack.push(1) 12 | mystack.push(2) 13 | val top = mystack.top() 14 | top shouldEqual 2 15 | val result = mystack.pop() 16 | result shouldEqual 2 17 | val isempty = mystack.empty() 18 | isempty shouldEqual false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/queue/RevealCardsInIncreasingOrderTest.scala: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class RevealCardsInIncreasingOrderTest extends AnyFunSuite { 8 | test("can reveal cards") { 9 | val deck = Array(17, 13, 11, 2, 3, 5, 7) 10 | val result = RevealCardsInIncreasingOrder.deckRevealedIncreasing(deck) 11 | result shouldEqual Array(2, 13, 3, 11, 5, 17, 7) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/queue/SlidingWindowMaximumTest.scala: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import matrix.SpiralMatrix 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class SlidingWindowMaximumTest extends AnyFunSuite { 8 | test("can find the maxs") { 9 | val nums = Array(1, 3, -1, -3, 5, 3, 6, 7) 10 | val result = SlidingWindowMaximum.maxSlidingWindow(nums, 3) 11 | result shouldEqual Array(3, 3, 5, 5, 6, 7) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/recursion/MergeTwoSortedListsTest.scala: -------------------------------------------------------------------------------- 1 | package recursion 2 | 3 | import linkedlist.LinkedListNode 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers._ 6 | 7 | class MergeTwoSortedListsTest extends AnyFunSuite { 8 | test("can merge two list") { 9 | val list1 = new LinkedListNode(1, None) 10 | list1.append(3) 11 | val list2 = new LinkedListNode(2, None) 12 | list2.append(4) 13 | val result = MergeTwoSortedLists.mergeTwoLists(list1, list2) 14 | result.toList shouldEqual List(1, 2, 3, 4) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/recursion/PermutationSequenceTest.scala: -------------------------------------------------------------------------------- 1 | package recursion 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class PermutationSequenceTest extends AnyFunSuite { 7 | test("can find the permutation") { 8 | val result = PermutationSequence.getPermutation(3, 3) 9 | result shouldEqual "213" 10 | } 11 | 12 | test("can find the permutation 2") { 13 | val result = PermutationSequence.getPermutation(4, 9) 14 | result shouldEqual "2314" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/recursion/ScrambleStringTest.scala: -------------------------------------------------------------------------------- 1 | package recursion 2 | 3 | import linkedlist.LinkedListNode 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class ScrambleStringTest extends AnyFunSuite { 8 | test("can scramble") { 9 | val (s1, s2) = ("great", "rgeat") 10 | val result = ScrambleString.isScramble(s1, s2) 11 | result shouldEqual true 12 | } 13 | 14 | test("can not scramble") { 15 | val (s1, s2) = ("abcde", "caebd") 16 | val result = ScrambleString.isScramble(s1, s2) 17 | result shouldEqual false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/sort/GroupAnagramsTest.scala: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import linkedlist.LinkedListNode 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class GroupAnagramsTest extends AnyFunSuite { 8 | test("can group anagrams") { 9 | val strs = Array("eat", "tea", "tan", "ate", "nat", "bat") 10 | val result = GroupAnagrams.groupAnagrams(strs) 11 | result shouldEqual List(List("eat", "tea", "ate"), List("bat"), List("tan", "nat")) 12 | } 13 | 14 | test("can group anagrams of 1 element") { 15 | val strs = Array("eat") 16 | val result = GroupAnagrams.groupAnagrams(strs) 17 | result shouldEqual List(List("eat")) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/sort/SortListTest.scala: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import linkedlist.LinkedListNode 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class SortListTest extends AnyFunSuite { 8 | test("can sort the list") { 9 | val head = new LinkedListNode[Int](-1, None) 10 | head.append(5).append(3).append(4).append(0) 11 | var result = SortList.sortList(head) 12 | result.value shouldEqual 5 13 | result = result.next.get 14 | result.value shouldEqual 4 15 | result = result.next.get 16 | result.value shouldEqual 3 17 | result = result.next.get 18 | result.value shouldEqual 0 19 | result = result.next.get 20 | result.value shouldEqual -1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/scala/stack/DecodeStringTest.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import stack.MinStack 6 | 7 | class DecodeStringTest extends AnyFunSuite { 8 | test("can decode string") { 9 | val s = "3[a]2[bc]" 10 | val result = DecodeString.decodeString(s) 11 | result shouldEqual "aaabcbc" 12 | } 13 | 14 | test("can decode nested string") { 15 | val s = "3[a2[c]]" 16 | val result = DecodeString.decodeString(s) 17 | result shouldEqual "accaccacc" 18 | } 19 | 20 | test("can decode string with literal at last") { 21 | val s = "2[abc]3[cd]ef" 22 | val result = DecodeString.decodeString(s) 23 | result shouldEqual "abcabccdcdcdef" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/scala/stack/LongestValidParenthesesTest.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import stack.MinStack 6 | 7 | class LongestValidParenthesesTest extends AnyFunSuite { 8 | test("can find longest valid parenteses") { 9 | val result = LongestValidParentheses.longestValidParentheses("(()") 10 | result shouldEqual 2 11 | } 12 | 13 | test("can find longest valid parenteses with 1st invalid char") { 14 | val result = LongestValidParentheses.longestValidParentheses(")()())") 15 | result shouldEqual 4 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/scala/stack/ShortestUnsortedContinuousSubarrayTest.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class ShortestUnsortedContinuousSubarrayTest extends AnyFunSuite { 7 | test("can find the length of shortest unsorted sub array") { 8 | val nums = Array(2, 6, 4, 8, 10, 9, 15) 9 | val result = ShortestUnsortedContinuousSubarray.findUnsortedSubarray(nums) 10 | result shouldEqual 5 11 | } 12 | 13 | test("can handle sorted case") { 14 | val nums = Array(2, 3, 4, 8, 10, 15) 15 | val result = ShortestUnsortedContinuousSubarray.findUnsortedSubarray(nums) 16 | result shouldEqual 0 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/stack/SimplifyPathTest.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class SimplifyPathTest extends AnyFunSuite { 7 | test("can simplify /home/") { 8 | val result = SimplifyPath.simplifyPath("/home/") 9 | result shouldEqual "/home" 10 | } 11 | 12 | test("can simplify /../") { 13 | val result = SimplifyPath.simplifyPath("/../") 14 | result shouldEqual "/" 15 | } 16 | 17 | test("can simplify /a/./b/../../c/") { 18 | val result = SimplifyPath.simplifyPath("/a/./b/../../c/") 19 | result shouldEqual "/c" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/scala/stack/ValidParenthesesTest.scala: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class ValidParenthesesTest extends AnyFunSuite { 7 | test("can match parentheses ()") { 8 | val str="()" 9 | val result = ValidParentheses.isValid(str) 10 | result shouldEqual true 11 | } 12 | 13 | test("can not match parentheses ()(") { 14 | val str="()(" 15 | val result = ValidParentheses.isValid(str) 16 | result shouldEqual false 17 | } 18 | 19 | test("can fail with invalid char") { 20 | val str="(a)" 21 | val result = ValidParentheses.isValid(str) 22 | result shouldEqual false 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/scala/string/AddBinaryTest.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class AddBinaryTest extends AnyFunSuite { 7 | test("can add 11 and 1") { 8 | val result = AddBinary.addBinary("11", "1") 9 | result shouldEqual "100" 10 | } 11 | 12 | test("can add 1010 and 1011") { 13 | val result = AddBinary.addBinary("1010", "1011") 14 | result shouldEqual "10101" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/string/CountandSayTest.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class CountandSayTest extends AnyFunSuite { 7 | test("can count say for 1") { 8 | val result = CountandSay.countAndSay(1) 9 | result shouldEqual "1" 10 | } 11 | 12 | test("can count say for 2") { 13 | val result = CountandSay.countAndSay(2) 14 | result shouldEqual "11" 15 | } 16 | 17 | test("can count say for 3") { 18 | val result = CountandSay.countAndSay(3) 19 | result shouldEqual "21" 20 | } 21 | 22 | test("can count say for 4") { 23 | val result = CountandSay.countAndSay(4) 24 | result shouldEqual "1211" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/scala/string/LongestCommonPrefixTest.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class LongestCommonPrefixTest extends AnyFunSuite { 7 | test("can get the longest common prefix string") { 8 | val strs = Array("flower", "flow", "flight") 9 | val result = LongestCommonPrefix.longestCommonPrefix(strs) 10 | result shouldEqual "fl" 11 | } 12 | 13 | test("can return empty string if there is no common prefix") { 14 | val strs = Array("1flower", "2flow", "3flight") 15 | val result = LongestCommonPrefix.longestCommonPrefix(strs) 16 | result shouldEqual "" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/string/PartitionLabelsTest.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class PartitionLabelsTest extends AnyFunSuite { 7 | test("can get partition") { 8 | val str = "ababcbacadefegdehijhklij" 9 | val result = PartitionLabels.partitionLabels(str) 10 | result shouldEqual List(9, 7, 8) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/string/ZigZagConversionTest.scala: -------------------------------------------------------------------------------- 1 | package string 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class ZigZagConversionTest extends AnyFunSuite { 7 | test("can convert zigzag strings") { 8 | val s = "PAYPALISHIRING" 9 | val result = ZigZagConversion.convert(s, 3) 10 | result shouldEqual "PAHNAPLSIIGYIR" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/tree/BalancedBinaryTreeTest.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class BalancedBinaryTreeTest extends AnyFunSuite { 7 | test("can detect a not-balanced tree") { 8 | val root = TreeNode(1) 9 | root.left = Option(TreeNode(2)) 10 | val result = BalancedBinaryTree.isBalanced(root) 11 | result shouldEqual false 12 | } 13 | 14 | test("can detect a balanced tree") { 15 | val root = TreeNode(1) 16 | root.left = Option(TreeNode(2)) 17 | root.right = Option(TreeNode(3)) 18 | val result = BalancedBinaryTree.isBalanced(root) 19 | result shouldEqual true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/scala/tree/ConstructBinaryTreefromInorderandPostorderTest.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class ConstructBinaryTreefromInorderandPostorderTest extends AnyFunSuite { 7 | test("can construct tree") { 8 | val in = Array(9, 3, 15, 20, 7) 9 | val post = Array(9, 15, 7, 20, 3) 10 | var root = ConstructBinaryTreefromInorderandPostorder.buildTree(in, post) 11 | root.value shouldEqual 3 12 | root.left.get.value shouldEqual 9 13 | root = root.right.get 14 | root.value shouldEqual 20 15 | root.right.get.value shouldEqual 7 16 | root.left.get.value shouldEqual 15 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/tree/ConstructBinaryTreefromPreorderandInorderTest.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class ConstructBinaryTreefromPreorderandInorderTest extends AnyFunSuite { 7 | test("can construct tree") { 8 | val pre = Array(3, 9, 20, 15, 7) 9 | val in = Array(9, 3, 15, 20, 7) 10 | var root = ConstructBinaryTreefromPreorderandInorder.buildTree(pre, in) 11 | root.value shouldEqual 3 12 | root.left.get.value shouldEqual 9 13 | root = root.right.get 14 | root.value shouldEqual 20 15 | root.right.get.value shouldEqual 7 16 | root.left.get.value shouldEqual 15 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/tree/InvertBinaryTreeTest.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class InvertBinaryTreeTest extends AnyFunSuite { 7 | test("can invert a single node") { 8 | val root = TreeNode(1) 9 | val result = InvertBinaryTree.invertTree(root) 10 | result.value shouldEqual 1 11 | result.left shouldEqual None 12 | result.right shouldEqual None 13 | } 14 | 15 | test("can invert a tree") { 16 | val root = TreeNode(1) 17 | root.left = Option(TreeNode(2)) 18 | root.right = Option(TreeNode(3)) 19 | val result = InvertBinaryTree.invertTree(root) 20 | root.value shouldEqual 1 21 | root.left.get.value shouldEqual 3 22 | root.right.get.value shouldEqual 2 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/scala/tree/MaximumDepthofBinaryTreeTest.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class MaximumDepthofBinaryTreeTest extends AnyFunSuite { 7 | test("can get depth of root only") { 8 | val root = TreeNode(1) 9 | val result = MaximumDepthofBinaryTree.maxDepth(root) 10 | result shouldEqual 1 11 | } 12 | 13 | test("can get depth of a tree") { 14 | val left = new TreeNode(3, Option(TreeNode(4)), None) 15 | val root = new TreeNode(1, Option(left), Option(TreeNode(2))) 16 | val result = MaximumDepthofBinaryTree.maxDepth(root) 17 | result shouldEqual 3 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/tree/SymmetricTreeTest.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class SymmetricTreeTest extends AnyFunSuite { 7 | test("can detect a valid case") { 8 | val root = new TreeNode(1, Option(TreeNode(2)), Option(TreeNode(3))) 9 | val result = SymmetricTree.isSymmetric(root) 10 | result shouldEqual true 11 | } 12 | 13 | test("can detect an invalid case") { 14 | val root = new TreeNode(1, Option(TreeNode(2)), None) 15 | val result = SymmetricTree.isSymmetric(root) 16 | result shouldEqual false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/tree/TreeNodeTest.scala: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class TreeNodeTest extends AnyFunSuite { 7 | test("can create a tree and print the tree structure") { 8 | val root = TreeNode(1) 9 | root.right = Option(TreeNode(2)) 10 | root.left = Option(TreeNode(3)) 11 | root.value shouldEqual (1) 12 | root.right.get.value shouldEqual (2) 13 | val output = root.toString 14 | output shouldEqual 15 | """1 16 | |+ 2 17 | |\ 3 18 | |""".stripMargin 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/tries/IndexPairsofaStringTest.scala: -------------------------------------------------------------------------------- 1 | package tries 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class IndexPairsofaStringTest extends AnyFunSuite { 7 | test("can index pairs of a string") { 8 | val s = "thestoryofleetcodeandme" 9 | val words = List("story","fleet","leetcode") 10 | val result = IndexPairsofaString.indexPairs(s, words) 11 | result shouldEqual List(List(3, 7), List(9, 13), List(10, 17)) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/tries/WordBreak2Test.scala: -------------------------------------------------------------------------------- 1 | package tries 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class WordBreak2Test extends AnyFunSuite { 7 | test("can break the words") { 8 | val s = "catsanddog" 9 | val words = List("cat","cats","and","sand","dog") 10 | val result = WordBreak2.wordBreak(s, words) 11 | result shouldEqual List("cat sand dog", "cats and dog") 12 | } 13 | 14 | test("can not break the words") { 15 | val s = "catsandog" 16 | val words = List("cats","dog","sand","and","cat") 17 | val result = WordBreak2.wordBreak(s, words) 18 | result shouldEqual List.empty[String] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/tries/WordBreakTest.scala: -------------------------------------------------------------------------------- 1 | package tries 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class WordBreakTest extends AnyFunSuite { 7 | test("can break word") { 8 | val s = "leetcode" 9 | val words = List("leet", "code") 10 | val result = WordBreak.wordBreak(s, words) 11 | result shouldEqual true 12 | } 13 | 14 | test("can not break word") { 15 | val s = "catsandog" 16 | val words = List("cats", "dog", "sand", "and", "cat") 17 | val result = WordBreak.wordBreak(s, words) 18 | result shouldEqual false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/tries/WordSearch2Test.scala: -------------------------------------------------------------------------------- 1 | package tries 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class WordSearch2Test extends AnyFunSuite { 7 | test("can search all words") { 8 | val board = Array(Array('o', 'a', 'a', 'n'), Array('e', 't', 'a', 'e'), Array('i', 'h', 'k', 'r'), Array('i', 'f', 'l', 'v')) 9 | val words = Array("oath", "pea", "eat", "rain") 10 | val result = WordSearch2.findWords(board, words) 11 | result shouldEqual List("oath", "eat") 12 | } 13 | 14 | test("can find any words") { 15 | val board = Array(Array('a', 'b'), Array('c', 'd')) 16 | val words = Array("abcb") 17 | val result = WordSearch2.findWords(board, words) 18 | result shouldEqual List.empty[String] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/ContainsDuplicate2Test.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import linkedlist.LinkedListNode 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | import twopointers.ContainsDuplicate2 7 | 8 | class ContainsDuplicate2Test extends AnyFunSuite { 9 | test("can find duplicates") { 10 | val nums = Array(1, 2, 3, 1) 11 | val k = 3 12 | val result = ContainsDuplicate2.containsNearbyDuplicate(nums, k) 13 | result shouldEqual true 14 | } 15 | 16 | test("can not find duplicates") { 17 | val nums = Array(1, 2, 3, 1, 2, 3) 18 | val k = 2 19 | val result = ContainsDuplicate2.containsNearbyDuplicate(nums, k) 20 | result shouldEqual false 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/ImplementstrStrTest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class ImplementstrStrTest extends AnyFunSuite { 7 | test("can find hello/ll") { 8 | val haystack = "hello" 9 | val needle = "ll" 10 | val result = ImplementstrStr.strStr(haystack, needle) 11 | result shouldEqual 2 12 | } 13 | 14 | test("can not find aaaaa bba") { 15 | val haystack = "aaaaa" 16 | val needle = "bba" 17 | val result = ImplementstrStr.strStr(haystack, needle) 18 | result shouldEqual -1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/LengthOfLongestSubStringTest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class LengthOfLongestSubStringTest extends AnyFunSuite { 7 | test("can get longest sub string") { 8 | val s = "abcabcbb" 9 | val result = LengthOfLongestSubString.lengthOfLongestSubstring(s) 10 | result shouldEqual 3 11 | } 12 | 13 | test("can handle empty string") { 14 | val s = "" 15 | val result = LengthOfLongestSubString.lengthOfLongestSubstring(s) 16 | result shouldEqual 0 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/LongestSubstringwithAtMostTwoDistinctCharactersTest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class LongestSubstringwithAtMostTwoDistinctCharactersTest extends AnyFunSuite { 7 | test("can get longest substring") { 8 | val s = "eceba" 9 | val result = LongestSubstringwithAtMostTwoDistinctCharacters.lengthOfLongestSubstringTwoDistinct(s) 10 | result shouldEqual 3 11 | } 12 | 13 | test("can get longest substring 2") { 14 | val s = "ccaabbb" 15 | val result = LongestSubstringwithAtMostTwoDistinctCharacters.lengthOfLongestSubstringTwoDistinct(s) 16 | result shouldEqual 5 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/RemoveDuplicatesfromSortedArrayIITest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class RemoveDuplicatesfromSortedArrayIITest extends AnyFunSuite { 7 | test("can remove duplicates from sorted array") { 8 | val nums = Array(1,1,1,2,2,3) 9 | val result = RemoveDuplicatesfromSortedArrayII.removeDuplicates(nums) 10 | result shouldEqual 5 11 | } 12 | 13 | test("can remove duplicates from sorted array 2") { 14 | val nums = Array(0,0,1,1,1,1,2,3,3) 15 | val result = RemoveDuplicatesfromSortedArrayII.removeDuplicates(nums) 16 | result shouldEqual 7 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/SortColorsTest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class SortColorsTest extends AnyFunSuite { 7 | test("can sort colors") { 8 | val nums = Array(2, 0, 2, 1, 1, 0) 9 | SortColors.sortColors(nums) 10 | nums shouldEqual Array(0, 0, 1, 1, 2, 2) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/SummaryRangesTest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class SummaryRangesTest extends AnyFunSuite { 7 | test("can get array range with break at end") { 8 | val nums = Array(0, 1, 2, 4, 5, 7) 9 | val result = SummaryRanges.summaryRanges(nums) 10 | result shouldEqual List("0->2", "4->5", "7") 11 | } 12 | 13 | test("can get array range with break at beginning") { 14 | val nums = Array(0, 2, 3, 4, 6, 8, 9) 15 | val result = SummaryRanges.summaryRanges(nums) 16 | result shouldEqual List("0", "2->4", "6", "8->9") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/ThreeSumClosestTest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers._ 5 | 6 | class ThreeSumClosestTest extends AnyFunSuite { 7 | test("can find the closest") { 8 | val nums = Array(-1, 2, 1, -4) 9 | val result = ThreeSumClosest.threeSumClosest(nums, 1) 10 | result shouldEqual 2 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/ThreeSumTest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class ThreeSumTest extends AnyFunSuite { 7 | test("can find all combination") { 8 | val nums = Array(-1, 0, 1, 2, -1, -4) 9 | val result = ThreeSum.threeSum(nums) 10 | result shouldEqual Array(Array(-1, -1, 2), Array(-1, 0, 1)) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/TrappingRainWaterTest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class TrappingRainWaterTest extends AnyFunSuite { 7 | test("can trap water") { 8 | val height = Array(4, 2, 0, 3, 2, 5) 9 | val water = TrappingRainWater.trap(height) 10 | water shouldEqual 9 11 | } 12 | 13 | test("can trap water with low edges") { 14 | val height = Array(1, 4, 2, 0, 3, 2, 5, 1) 15 | val water = TrappingRainWater.trap(height) 16 | water shouldEqual 9 17 | } 18 | 19 | test("can trap water from right") { 20 | val height = Array(5, 2, 3, 0, 2, 4) 21 | val water = TrappingRainWater.trap(height) 22 | water shouldEqual 9 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/TwoSumIITest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | 6 | class TwoSumIITest extends AnyFunSuite { 7 | test("can get two sum") { 8 | val nums = Array(2, 7, 11, 15) 9 | val result = TwoSumII.twoSum(nums, 9) 10 | result shouldEqual Array(1, 2) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/ValidPalindrome4Test.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.shouldEqual 5 | 6 | class ValidPalindrome4Test extends AnyFunSuite { 7 | test("can validate palindrome") { 8 | val s = "abcdba" 9 | val result = ValidPalindrome4.makePalindrome(s) 10 | result shouldEqual true 11 | } 12 | 13 | test("can invalidate palindrome") { 14 | val s = "abcdef" 15 | val result = ValidPalindrome4.makePalindrome(s) 16 | result shouldEqual false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/twopointers/ValidPalindromeTest.scala: -------------------------------------------------------------------------------- 1 | package twopointers 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers.* 5 | import twopointers.ValidPalindrome 6 | 7 | class ValidPalindromeTest extends AnyFunSuite { 8 | test("can validate palindrome") { 9 | val s = "A man, a plan, a canal: Panama" 10 | val result = ValidPalindrome.isPalindrome(s) 11 | result shouldEqual true 12 | } 13 | 14 | test("can validate non palindrome") { 15 | val s = "race a car" 16 | val result = ValidPalindrome.isPalindrome(s) 17 | result shouldEqual false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/unionfind/NumberofIslands2Test.scala: -------------------------------------------------------------------------------- 1 | package unionfind 2 | 3 | import linkedlist.LinkedListNode 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class NumberofIslands2Test extends AnyFunSuite { 8 | test("can detect islands") { 9 | val points = Array(Array(0, 0), Array(0, 2), Array(0, 1), Array(2, 2)) 10 | val result = NumberofIslands2.numIslands(3, 3, points) 11 | result shouldEqual Array(1, 2, 1, 2) 12 | } 13 | 14 | test("can detect connected islands") { 15 | val points = Array(Array(0, 0), Array(0, 1), Array(1, 2), Array(2, 1)) 16 | val result = NumberofIslands2.numIslands(3, 3, points) 17 | result shouldEqual Array(1, 1, 2, 3) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/unionfind/NumberofProvincesTest.scala: -------------------------------------------------------------------------------- 1 | package unionfind 2 | 3 | import linkedlist.LinkedListNode 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.should.Matchers.* 6 | 7 | class NumberofProvincesTest extends AnyFunSuite { 8 | test("can count number of connected provinces") { 9 | val isConnected = Array(Array(1, 1, 0), Array(1, 1, 0), Array(0, 0, 1)) 10 | val result = NumberofProvinces.findCircleNum(isConnected) 11 | result shouldEqual 2 12 | } 13 | 14 | test("can count number of no connected provinces") { 15 | val isConnected = Array(Array(1, 0, 0), Array(0, 1, 0), Array(0, 0, 1)) 16 | val result = NumberofProvinces.findCircleNum(isConnected) 17 | result shouldEqual 3 18 | } 19 | } 20 | --------------------------------------------------------------------------------