├── README.MD └── src ├── 1.scala ├── 100.scala ├── 101.scala ├── 108.scala ├── 121.scala ├── 136.scala ├── 199.scala ├── 202.scala ├── 205.scala ├── 226.scala ├── 230.scala ├── 26.scala ├── 268.scala ├── 36.scala ├── 387.scala ├── 389.scala ├── 412.scala ├── 476.scala ├── 49.scala ├── 504.scala ├── 515.scala ├── 520.scala ├── 53.scala ├── 538.scala ├── 55.scala ├── 551.scala ├── 561.scala ├── 572.scala ├── 599.scala ├── 606.scala ├── 617.scala ├── 657.scala ├── 669.scala ├── 697.scala ├── 7.scala ├── 733.scala ├── 744.scala ├── 747.scala ├── 781.scala ├── 784.scala ├── 804.scala ├── 806.scala ├── 811.scala ├── 819.scala ├── 821.scala ├── 824.scala ├── 825.scala ├── 830.scala ├── 831.scala ├── 832.scala ├── 833.scala ├── 841.scala ├── 844.scala ├── 848.scala ├── 884.scala ├── 94.scala ├── 941.scala └── MyHashSet.scala /README.MD: -------------------------------------------------------------------------------- 1 | 2 | ## Solutions in Scala to Leetcode Problems 3 | 4 | Familiarizing myself with Scala language using Leetcode problems, and these are my solutions. 5 | 6 | 7 | 8 | | Quiz Name | My Solution | Keywords | 9 | |-----------|-------------|------------------------------| 10 | |[811.Subdomain Visit Count](https://leetcode.com/problems/subdomain-visit-count/description/) |[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/811.scala)|`for...yield`, `Tuple`, `groupBy`, `mapValues`| 11 | |[819.Most Common Word](https://leetcode.com/problems/most-common-word/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/819.scala)|`Regular Expression`, `groupBy`, `maxBy`| 12 | |[121.Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/121.scala) |`for-loop`, `if-else` | 13 | |[551.Student Attendance Record I](https://leetcode.com/problems/student-attendance-record-i/description/) |[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/551.scala) |`Boolean` | 14 | |[268.Missing Number](https://leetcode.com/problems/missing-number/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/268.scala)|`filter`| 15 | |[476.Number Complement](https://leetcode.com/problems/number-complement/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/476.scala)|`Parse Integer`| 16 | |[821.Shortest Distance to a Character](https://leetcode.com/problems/shortest-distance-to-a-character/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/821.scala)|`map`, `filter`, `min`, `abs`| 17 | |[389.Find the Difference](https://leetcode.com/problems/find-the-difference/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/389.scala)|`distinct`, `filter`, `! (NOT)`, `contains` (similar to `in` in Python)| 18 | |[561.Array Partition I](https://leetcode.com/problems/array-partition-i/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/561.scala)|`Sort an Array (or List)`, `sum`| 19 | |[784.Letter Case Permutation](https://leetcode.com/problems/letter-case-permutation/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/784.scala)|`Regular Expression`, `def` (function), `toUpperCase`, `toLowerCase`, `for...yield`| 20 | |[657.Judge Route Circle](https://leetcode.com/problems/judge-route-circle/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/657.scala)|`map`, `filter`, `&` (AND)| 21 | |[136.Single Number](https://leetcode.com/problems/single-number/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/136.scala)|`distinct`, `filter`| 22 | |[804.Unique Morse Code Words](https://leetcode.com/problems/unique-morse-code-words/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/804.scala)|`Map`, `Map.getOrElse`, `for...yield`, `distinct`, `Concatenate Strings`| 23 | |[412.Fizz Buzz](https://leetcode.com/problems/fizz-buzz/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/412.scala)|`def` (function), `%` (modulus operator), `if-else`| 24 | |[520.Detect Capital](https://leetcode.com/problems/detect-capital/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/520.scala)|`toUpper` (for Char), `toUpperCase` (for String), `toLowerCase`, `OR operator`, `if-else`, `drop` (string)| 25 | |Implement a Hash Set|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/MyHashSet.scala)|`Class`, `Array Concatenation`, `List Concatenation`, `contains`, `function`| 26 | |[202.Happy Number](https://leetcode.com/problems/happy-number/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/202.scala)|`(Mutable) Set`, `While Loop`, `scala.math.pow()` (exponentiation), `Type Change among Int, String, Char`| 27 | |[1.Two Sum](https://leetcode.com/problems/two-sum/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/1.scala)|`(mutable) HashMap`, `While Loop`| 28 | |[205.Isomorphic Strings](https://leetcode.com/problems/isomorphic-strings/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/205.scala)|`(mutable) HashMap`, `if-else`, `filter`, `char to Int`, `distinct`, `zip`| 29 | |[599.Minimum Index Sum of Two Lists](https://leetcode.com/problems/minimum-index-sum-of-two-lists/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/599.scala)|`(mutable) HashMap`, `zip`, `contains method (in Map)`, `Array Concatenation`| 30 | |[387.First Unique Character in a String](https://leetcode.com/problems/first-unique-character-in-a-string/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/387.scala)|`ArrayBuffer`, `(mutable) HashMap`, `zipWithIndex`, `Map.retain`| 31 | |[49.Group Anagrams](https://leetcode.com/problems/group-anagrams/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/49.scala)|`ListBuffer`, `HashMap`| 32 | |[36.Valid Sudoku](https://leetcode.com/problems/valid-sudoku/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/36.scala)|`break` (control flow), `self-define function`, `Array.distinct`, `Array Slicing [Array.slice()]`, `flatMap`| 33 | |[830.Positions of Large Groups](https://leetcode.com/problems/positions-of-large-groups/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/830.scala)|`ListBuffer`, `for-loop`, `if-else`| 34 | |[831.Masking Personal Information](https://leetcode.com/problems/masking-personal-information/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/831.scala)|`findAllIn (Regular Expression)`, `Array.mkString` (merge a list of Chars into a String), `Array.slice()`, `String.split()`| 35 | |[824.Goat Latin](https://leetcode.com/problems/goat-latin/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/824.scala)|`String.split`, `String.toUpperCase`, `self-defined function`, `List.exists` (check if there is any element meeting a specific condition), `String.startsWith`, `zipWithIndex`, `List.mkString` (merge a list of Chars into a String)| 36 | |[832.Flipping an Image](https://leetcode.com/problems/flipping-an-image/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/832.scala)|`Array.map`, `Array.reverse`| 37 | |[833.Find And Replace in String](https://leetcode.com/problems/find-and-replace-in-string/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/833.scala)|`Array.zip`, `Array(tuple).sortBy`, `Array.sorted`, `String.substring` (string slicing), `String.replaceFirst`, `Array.mkString`| 38 | |[825.Friends Of Appropriate Ages](https://leetcode.com/problems/friends-of-appropriate-ages/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/825.scala)|`Array.sorted`, `Array.reverse`, `Array.zipWithIndex`, `while loop`| 39 | |[841.Keys and Rooms](https://leetcode.com/problems/keys-and-rooms/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/841.scala)|`collection.mutable.ArrayBuffer`, `function/method`, Recursion, `distinct`, `contains`| 40 | |[844.Backspace String Compare](https://leetcode.com/problems/backspace-string-compare/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/844.scala)|`collection.mutable.ArrayBuffer`, `function/method`, `ArrayBuffer.remove`, make a string from a list of Characters, stack| 41 | |[806.Number of Lines To Write String](https://leetcode.com/problems/number-of-lines-to-write-string/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/806.scala)|`zip`, `Vector.toMap`| 42 | |[617.Merge Two Binary Trees](https://leetcode.com/problems/merge-two-binary-trees/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/617.scala)|recursion, binary tree| 43 | |[226.Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/226.scala)|pattern matching, recursion, binary tree| 44 | |[100.Same Tree](https://leetcode.com/problems/same-tree/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/100.scala)|recusion, binary tree| 45 | |[572.Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/572.scala)|recursion, binary tree| 46 | |[199.Binary Tree Right Side View](https://leetcode.com/problems/binary-tree-right-side-view/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/199.scala)|recursion, binary tree, `ArrayBuffer`, `groupBy`, `sortBy`, `List.last`| 47 | |[606.Construct String from Binary Tree](https://leetcode.com/problems/construct-string-from-binary-tree/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/606.scala)|recursion, if-else, String Interpolation (String Format)| 48 | |[101.Symmetric Tree](https://leetcode.com/problems/symmetric-tree/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/101.scala)|Methods with the same name for different arguments, Use `Option` to allow null values, recursion, `groupBy`, `Map.mapValues`, `forall`, `ArrayBuffer`| 49 | |[55.Jump Game](https://leetcode.com/problems/jump-game/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/55.scala)|`while`, `if-else`| 50 | |[744.Find Smallest Letter Greater Than Target](https://leetcode.com/problems/find-smallest-letter-greater-than-target/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/744.scala)|`collection.exists`, `collection.filter`, `collection.min`| 51 | |[26.Remove Duplicates from Sorted Array](https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/26.scala)|`two-pointer`| 52 | |[7.Reverse Integer](https://leetcode.com/problems/reverse-integer/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/7.scala)|`math.abs`, `collection.slice`, `collection.zipWithIndex`, `collection.find`, `Some(*).get`, `try-catch`, `String.reverse`| 53 | |[94.Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/94.scala)|recursion, `mutable.ArrayBuffer`, Binary Tree| 54 | |[230.Kth Smallest Element in a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/230.scala)|recursion, Binary Search Tree| 55 | |[669.Trim a Binary Search Tree](https://leetcode.com/problems/trim-a-binary-search-tree/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/669.scala)|recursion, Binary Search Tree, `if-else`| 56 | |[108.Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/108.scala)|Binary Search Tree, Recursion| 57 | |[538.Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/538.scala)|Binary Search Tree, Recursion| 58 | |[515.Find Largest Value in Each Tree Row](https://leetcode.com/problems/find-largest-value-in-each-tree-row/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/515.scala)|Tree, Recursion, `collection.sortBy`, `collection.mutable.HashMap`| 59 | |[697.Degree of an Array](https://leetcode.com/problems/degree-of-an-array/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/697.scala)|`ArrayBuffer`, `collection.mutable.HashMap`, `zipWithIndex`, `Map.contains()`, `collection.last`, `collection.head`, `collection.min` & `.max`| 60 | |[53.Maximum Subarray](https://leetcode.com/problems/maximum-subarray/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/53.scala)|| 61 | |[848.Shifting Letters](https://leetcode.com/problems/shifting-letters/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/848.scala)|Conversion between `Char` and `Int`| 62 | |[504.Base 7](https://leetcode.com/problems/base-7/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/504.scala)|`math.abs`, `Modulo operatio (%)`, `while`-loop, `if-else`, `List.reverse`| 63 | |[747.Largest Number At Least Twice of Others](https://leetcode.com/problems/largest-number-at-least-twice-of-others/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/747.scala)|`collection.sorted`, `collection.indexOf` (find the index of an element in a list)| 64 | |[733.Flood Fill](https://leetcode.com/problems/flood-fill/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/733.scala)|Recursion, format string| 65 | |[781.Rabbits in Forest](https://leetcode.com/problems/rabbits-in-forest/description/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/781.scala)|`collection.toSet`, `math.ceil`, `collection.count`| 66 | |[884.Uncommon Words from Two Sentences](https://leetcode.com/problems/uncommon-words-from-two-sentences/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/884.scala)|`Set Operations`, `Map`| 67 | |[941.Valid Mountain Array](https://leetcode.com/problems/valid-mountain-array/)|[solution](https://github.com/XD-DENG/leetcode-scala/blob/master/src/941.scala)|`if-else`| -------------------------------------------------------------------------------- /src/1.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def twoSum(nums: Array[Int], target: Int): Array[Int] = { 3 | 4 | val nums_map = scala.collection.mutable.HashMap[Int, Int]() 5 | 6 | var result: Array[Int] = Array(0,0) 7 | 8 | var i = 0 9 | 10 | while(result.sum == 0) { 11 | 12 | val complement = target - nums(i) 13 | 14 | if (nums_map.contains(complement)) { 15 | result(0) = i 16 | result(1) = nums_map(complement) 17 | } else { 18 | nums_map(nums(i)) = i 19 | } 20 | 21 | i += 1 22 | } 23 | 24 | result 25 | } 26 | } 27 | 28 | 29 | 30 | // Brute-force method, which takes more than two times of running time than the method above 31 | object Solution { 32 | def twoSum(nums: Array[Int], target: Int): Array[Int] = { 33 | 34 | val result = for {i <- 0 until (nums.length - 1); 35 | j <- (i+1) until nums.length 36 | if nums(i) + nums(j) == target} yield Array(i, j) 37 | 38 | result(0) 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /src/100.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | def isSameTree(p: TreeNode, q: TreeNode): Boolean = { 11 | 12 | // // method-1: a nested pattern matching (not really beatifully written) 13 | // p match { 14 | // case null => 15 | // { 16 | // q match { 17 | // case null => true 18 | // case _ => false 19 | // } 20 | // } 21 | // case _ => 22 | // { 23 | // q match { 24 | // case null => false 25 | // case _ => { 26 | // if (p.value == q.value) { 27 | // isSameTree(p.left, q.left) && isSameTree(p.right, q.right) 28 | // } else { 29 | // false 30 | // } 31 | // } 32 | // } 33 | // } 34 | // } 35 | 36 | 37 | 38 | // method-2: if-else. More straightforward for this case 39 | if (p == null && q == null) { 40 | true 41 | } else if (p != null && q == null) { 42 | false 43 | } else if (p == null && q != null) { 44 | false 45 | } else if (p.value == q.value) { 46 | isSameTree(p.left, q.left) && isSameTree(p.right, q.right) 47 | } else { 48 | false 49 | } 50 | 51 | 52 | } 53 | } -------------------------------------------------------------------------------- /src/101.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | 11 | def isSymmetric(l: List[Option[Int]]): Boolean = { 12 | // check if a List is symmetric. 13 | // Use Option here to allow null values 14 | if (l.length % 2 != 0) { 15 | false 16 | } else { 17 | val n = l.length 18 | if ((0 until n / 2).exists(v => l(v) != l(n - v - 1))) false else true 19 | } 20 | } 21 | 22 | 23 | def isSymmetric(root: TreeNode): Boolean = { 24 | if (root == null) { 25 | true 26 | } else { 27 | 28 | val result = collection.mutable.ArrayBuffer[Tuple2[Option[Int], Int]]() 29 | 30 | def FUN_check_branch(tree_branch: TreeNode, current_depth: Int): Unit = { 31 | if (tree_branch != null) { 32 | result += Tuple2(Some(tree_branch.value), current_depth) 33 | FUN_traverse(tree_branch, current_depth + 1) 34 | } else { 35 | result += Tuple2(null, current_depth) 36 | } 37 | } 38 | 39 | def FUN_traverse(tree_node: TreeNode, current_depth: Int): Unit = { 40 | // LEFT first, then RIGHT. This order can NOT be changed 41 | FUN_check_branch(tree_node.left, current_depth) 42 | FUN_check_branch(tree_node.right, current_depth) 43 | } 44 | 45 | FUN_traverse(root, 2) 46 | 47 | if (result.toList.groupBy(_._2).mapValues(v => v.map(_._1)).mapValues(isSymmetric(_)).values.forall(_ == true)) { 48 | true 49 | } else { 50 | false 51 | } 52 | 53 | } 54 | 55 | } 56 | } -------------------------------------------------------------------------------- /src/108.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | def sortedArrayToBST(nums: Array[Int]): TreeNode = { 11 | 12 | val n = nums.length 13 | 14 | if (n != 0) { 15 | val mid_index = n/2 16 | val node = TreeNode(nums(mid_index)) 17 | node.left = sortedArrayToBST(nums.take(mid_index)) 18 | node.right = sortedArrayToBST(nums.slice(mid_index + 1, n)) 19 | 20 | node 21 | } else { 22 | null 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/121.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def maxProfit(prices: Array[Int]): Int = { 3 | 4 | if (prices.length == 0){ 5 | return 0 6 | } 7 | 8 | var current_min = prices(0) 9 | var current_benefit = 0 10 | 11 | for (i <- 1 until prices.length){ 12 | if (prices(i) < current_min){ 13 | current_min = prices(i) 14 | } else { 15 | if(prices(i) - current_min > current_benefit){ 16 | current_benefit = prices(i) - current_min 17 | } 18 | } 19 | } 20 | 21 | current_benefit 22 | } 23 | } -------------------------------------------------------------------------------- /src/136.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def singleNumber(nums: Array[Int]): Int = { 3 | 4 | nums.distinct.filter(x => nums.filter(_ == x).length != 2)(0) 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /src/199.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | def rightSideView(root: TreeNode): List[Int] = { 11 | 12 | if (root == null) { 13 | List() 14 | } else { 15 | // A "stupid" idea: 16 | // we traverse the whole tree, use an ArrayBuffer of Tuple2(current depth, value) to describe the whole tree 17 | // then we group these tuples using their depth, and get the element at the most right side position 18 | import collection.mutable.ArrayBuffer 19 | val storage = ArrayBuffer[Tuple2[Int, Int]]() 20 | 21 | def FUN_traverse(tree: TreeNode, i: Int): Unit = { 22 | if (tree != null) { 23 | // the order of statements 1 to 4 can NOT be changed 24 | // later we use ".last" method to get the element at the most right side position. The order is important 25 | if (tree.left != null) storage += Tuple2(i, tree.left.value) // statement-1 26 | if (tree.right != null) storage += Tuple2(i, tree.right.value) // statement-2 27 | 28 | if (tree.left != null) FUN_traverse(tree.left, i+1) // statement-3 29 | if (tree.right != null) FUN_traverse(tree.right, i+1) // statement-4 30 | } 31 | } 32 | 33 | FUN_traverse(root, 1) 34 | 35 | List(root.value) ++ storage.groupBy(_._1).toList.sortBy(_._1) 36 | .map(x=>(x._1, x._2.last)) 37 | .map(x=>(x._1, x._2._2)) 38 | .map(_._2) 39 | } 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /src/202.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def isHappy(n: Int): Boolean = { 3 | 4 | var result: Int = n 5 | val historical_result_list = scala.collection.mutable.Set.empty[Int] 6 | 7 | while ((result != 1) && ((historical_result_list contains result) == false)) { 8 | historical_result_list.add(result) 9 | result = result.toString.map(x => scala.math.pow(x.toString.toInt,2)).sum.toInt 10 | } 11 | 12 | val to_return = if (result == 1) true else false 13 | 14 | to_return 15 | } 16 | } -------------------------------------------------------------------------------- /src/205.scala: -------------------------------------------------------------------------------- 1 | // Method 1 2 | 3 | object Solution { 4 | def isIsomorphic(s: String, t: String): Boolean = { 5 | 6 | val char_map = scala.collection.mutable.HashMap[Int, Int]() 7 | 8 | val result = for (i <- 0 until s.length) yield { 9 | if (char_map.contains(s(i))) { 10 | if (char_map(s(i)) == t(i)){ 11 | true 12 | } else { 13 | false 14 | } 15 | } else { 16 | if (char_map.values.toList.contains(t(i))) { 17 | false 18 | } else { 19 | char_map(s(i)) = t(i) 20 | true 21 | } 22 | } 23 | } 24 | 25 | result.filter(_ == false).length == 0 26 | 27 | } 28 | } 29 | 30 | 31 | // Method 2 32 | 33 | object Solution { 34 | def isIsomorphic(s: String, t: String): Boolean = { 35 | 36 | val n_distinct_combination = s.zip(t).map(x => x._1.toInt - x._2.toInt).zip(s).distinct.length 37 | 38 | (n_distinct_combination == s.distinct.length) && (n_distinct_combination == t.distinct.length) 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /src/226.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | def invertTree(root: TreeNode): TreeNode = { 11 | 12 | // // method-1: using if-else 13 | // if (root == null) { 14 | // null 15 | // } else { 16 | // val left = root.left 17 | // val right = root.right 18 | // root.left = invertTree(right) 19 | // root.right = invertTree(left) 20 | 21 | // root 22 | // } 23 | 24 | 25 | // method-2: using pattern matching 26 | root match { 27 | case null => 28 | null 29 | case _ => 30 | val left = root.left 31 | val right = root.right 32 | 33 | root.left = invertTree(right) 34 | root.right = invertTree(left) 35 | root 36 | } 37 | 38 | 39 | } 40 | } -------------------------------------------------------------------------------- /src/230.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | def kthSmallest(root: TreeNode, k: Int): Int = { 11 | 12 | var count = 0 13 | var result: Int = -1 // a "placeholder" to help store the result later 14 | 15 | // This function will help traverse the binary tree inorder (in left-root-right order) 16 | def FUN_traverse(node: TreeNode): Unit = { 17 | if (node != null) { 18 | FUN_traverse(node.left) 19 | 20 | count += 1 21 | if (count == k) { 22 | result = node.value 23 | } else { 24 | FUN_traverse(node.right) 25 | } 26 | } 27 | } 28 | 29 | FUN_traverse(root) 30 | result 31 | } 32 | } -------------------------------------------------------------------------------- /src/26.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def removeDuplicates(nums: Array[Int]): Int = { 3 | 4 | // Two-pointer idea 5 | 6 | if (nums.length == 0){ 7 | 0 8 | } else { 9 | // if the Array is not empty, we start from index 1 rather than 0 10 | // since the 1st element (at index 0) will be included for sure. 11 | // For the same reason, the initial value of `count` is 1 instead of 0 12 | 13 | var count = 1 14 | 15 | // NOTE: start from 1 rathr than 0 here 16 | for (i <- 1 until nums.length) { 17 | if (nums(i) != nums(count-1)) { 18 | nums(count) = nums(i) 19 | count += 1 20 | } 21 | } 22 | 23 | count 24 | } 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /src/268.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def missingNumber(nums: Array[Int]): Int = { 3 | 4 | (0 to nums.length).filter(x => !(nums contains x))(0) 5 | } 6 | } -------------------------------------------------------------------------------- /src/36.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def isValidSudoku(board: Array[Array[Char]]): Boolean = { 3 | 4 | 5 | import util.control.Breaks._ 6 | 7 | def check_a_single_array(l: Array[Char]): Boolean = { 8 | // input: Array of char, an Array of 9 elments to check using the three rules 9 | // return: Boolean, if the array given can pass the exam 10 | val temp = l.filter(_ != '.') 11 | if (temp.length != temp.distinct.length) { 12 | false 13 | } else { 14 | true 15 | } 16 | } 17 | 18 | 19 | var error_flag = 0 20 | 21 | breakable { 22 | 23 | // check rule-1 24 | for (i <- 0 until 9) { 25 | if (check_a_single_array(board(i)) == false) { 26 | error_flag += 1 27 | break 28 | } 29 | } 30 | 31 | // check rule-2 32 | for (i <- 0 until 9) { 33 | val temp_list = board.map(_(i)) 34 | 35 | if (check_a_single_array(temp_list) == false) { 36 | error_flag += 1 37 | break 38 | } 39 | } 40 | 41 | // check rule-3 42 | for (i <- 0 until 3; j <- 0 until 3) { 43 | // get each 3x3 sub-boxes and flatten it to a 9-length Array 44 | val temp_list = board.slice(i * 3, i * 3 + 3).flatMap(_.slice(j * 3, j*3 + 3)) 45 | 46 | if (check_a_single_array(temp_list) == false) { 47 | error_flag += 1 48 | break 49 | } 50 | } 51 | 52 | } 53 | 54 | 55 | if (error_flag > 0) false else true 56 | 57 | } 58 | } -------------------------------------------------------------------------------- /src/387.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def firstUniqChar(s: String): Int = { 3 | 4 | import scala.collection.mutable.ArrayBuffer 5 | 6 | var result_map = scala.collection.mutable.HashMap[Char, ArrayBuffer[Int]]() 7 | 8 | // Save (k, v) into a Map. 9 | // k is the unique Chars in input "s", while v is an Array (ArrayBuffer here) of all the corresponding index 10 | s.zipWithIndex.foreach { x => 11 | if (result_map contains x._1) { 12 | result_map(x._1) += x._2 13 | } else { 14 | result_map(x._1) = ArrayBuffer(x._2) 15 | } 16 | } 17 | 18 | // only keep the chars which appear for only once 19 | result_map.retain((k,v) => v.length == 1) 20 | 21 | if (result_map.toList.length == 0) { 22 | -1 23 | } else { 24 | result_map.values.map(_(0)).min 25 | } 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /src/389.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def findTheDifference(s: String, t: String): Char = { 3 | 4 | val result = if (s.distinct.length == t.distinct.length) // to handle cases like 'a' and 'aa' 5 | for (c <- s.distinct 6 | if (s.filter(x => x==c).length != t.filter(x => x==c).length) 7 | ) yield c 8 | else 9 | t.distinct.filter(x => ! (s.distinct contains x))(0) 10 | 11 | result.toString()(0) // to meet the type requirement, so toString() first and then use "(0)" to get the final result as Char 12 | } 13 | } -------------------------------------------------------------------------------- /src/412.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def fizzBuzz(n: Int): List[String] = { 3 | 4 | def temp(x: Int): String = { 5 | val condition_1 = (x % 3==0) 6 | val condition_2 = (x % 5==0) 7 | 8 | if (condition_1 & condition_2) { 9 | "FizzBuzz" 10 | } 11 | else if (condition_1) { 12 | "Fizz" 13 | } 14 | else if (condition_2) { 15 | "Buzz" 16 | } 17 | else { 18 | x.toString 19 | } 20 | } 21 | 22 | (1 to n).toList.map(x => temp(x)) 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /src/476.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def findComplement(num: Int): Int = { 3 | 4 | val num_bin = num.toBinaryString 5 | val num_bin_complement = num_bin.map(x=> if (x=='1') '0' else '1') 6 | 7 | Integer.parseInt(num_bin_complement, 2) 8 | } 9 | } -------------------------------------------------------------------------------- /src/49.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def groupAnagrams(strs: Array[String]): List[List[String]] = { 3 | 4 | import collection.mutable.HashMap 5 | import collection.mutable.ListBuffer 6 | 7 | val mapping = HashMap[String, ListBuffer[String]]() 8 | 9 | for (s <- strs) { 10 | if (mapping.contains(s.sorted)) { 11 | mapping(s.sorted) += s 12 | } else { 13 | mapping(s.sorted) = ListBuffer(s) 14 | } 15 | } 16 | 17 | 18 | mapping.values.map(_.toList).toList 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /src/504.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def convertToBase7(num: Int): String = { 3 | 4 | val result = collection.mutable.ArrayBuffer[Int]() // an ArrayBuffer for temporary storage 5 | var res = math.abs(num) // take absolute value of `num` to tackle situations in which num is negative 6 | 7 | while (res >= 7) { 8 | result += res % 7 9 | res = res / 7 10 | } 11 | result += res 12 | 13 | 14 | // Style-1 15 | // (num >= 0) match { 16 | // case true => result.toList.reverse.mkString 17 | // case false => "-" + result.toList.reverse.mkString 18 | // } 19 | 20 | // Style-2 21 | {if (num >=0) "" else "-"} + result.toList.reverse.mkString 22 | } 23 | } -------------------------------------------------------------------------------- /src/515.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | def largestValues(root: TreeNode): List[Int] = { 11 | 12 | // prepare a Map to store the max valu in each depth. Depth will be the key in this Map. 13 | val result = collection.mutable.HashMap[Int, Int]() 14 | 15 | def FUN_traverse(node: TreeNode, depth: Int): Unit = { 16 | if(node != null) { 17 | // order here does NOT matter 18 | FUN_traverse(node.left, depth + 1) 19 | FUN_traverse(node.right, depth + 1) 20 | if (result.contains(depth)) { 21 | if(result(depth) < node.value) result(depth) = node.value 22 | } else { 23 | result(depth) = node.value 24 | } 25 | } else { 26 | null 27 | } 28 | } 29 | 30 | // trigger the recursion 31 | FUN_traverse(root, 0) 32 | 33 | // order the result by depth and show the max value in each depth 34 | result.toList.sortBy(_._1).map(_._2) 35 | } 36 | } -------------------------------------------------------------------------------- /src/520.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def detectCapitalUse(word: String): Boolean = { 3 | 4 | if (word == word.toUpperCase | word == word.toLowerCase) { 5 | true 6 | } 7 | else if (word(0) == word(0).toUpper & word.drop(1) == word.drop(1).toLowerCase) { 8 | true 9 | } 10 | else { 11 | false 12 | } 13 | 14 | } 15 | } -------------------------------------------------------------------------------- /src/53.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def maxSubArray(nums: Array[Int]): Int = { 3 | 4 | // IDEA: 5 | // Go through the whole Array, 6 | // and change each element into the possible maximum sum of the subarray ENDING at its index 7 | 8 | // During each iteration, the element at i-th index will be updated into the possible maximum sum of subarray ENDING at i-th index 9 | // then for (i+1)th index, if updated i-th value is positive, it can be used to update (i+1)th value as well. 10 | 11 | for (i <- Range(1, nums.length)) { 12 | if (nums(i-1) > 0) { 13 | nums(i) += nums(i-1) 14 | } 15 | } 16 | 17 | nums.max 18 | } 19 | } -------------------------------------------------------------------------------- /src/538.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | 11 | def convertBST(root: TreeNode): TreeNode = { 12 | 13 | // maintain a glocal variable to help store the current total sum of the "right side" 14 | var temp_sum = 0 15 | 16 | // recursively traverse the tree FROM RIGHT TO LEFT. 17 | // This is based on the SORTED nature of the input (binary search tree) 18 | def FUN_traverse(root: TreeNode): TreeNode = { 19 | 20 | if (root == null) { 21 | null 22 | } else { 23 | FUN_traverse(root.right) 24 | temp_sum += root.value 25 | root.value = temp_sum 26 | FUN_traverse(root.left) 27 | 28 | root 29 | } 30 | } 31 | 32 | FUN_traverse(root) 33 | } 34 | } -------------------------------------------------------------------------------- /src/55.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def canJump(nums: Array[Int]): Boolean = { 3 | 4 | // We should look at this probelm in REVERSE ORDER: 5 | // The target is to check whether we can arrive at the last index, 6 | // then we should reversely check the elements, 7 | // meanwhile, update the smallest index that we must arrive (`target`) in order to arrive at the last index 8 | 9 | // For example, if the i-2 index index is 2, 10 | // we know we can make it as long as the earlier elements can send us to i-2 index. 11 | // My target should be updated to i-2 index rather than the last index. 12 | 13 | val n = nums.length 14 | 15 | var target = n-1 // the initial target 16 | var i = n - 2 17 | 18 | // update the target 19 | while (i > 0) { 20 | if (nums(i) + i >= target) { 21 | target = i 22 | } 23 | i -= 1 24 | } 25 | 26 | // check if the first element can trigger the "chain effect" 27 | if (nums(0) >= target) { 28 | true 29 | } else { 30 | false 31 | } 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /src/551.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def checkRecord(s: String): Boolean = { 3 | 4 | var sum_A = 0 5 | for (x <- s) { 6 | if (x=='A') sum_A += 1 7 | } 8 | val condition_1 = (sum_A <=1) 9 | 10 | 11 | val condition_2 = ("LLL".r.findFirstIn(s) == None) 12 | 13 | 14 | condition_1 & condition_2 15 | } 16 | } -------------------------------------------------------------------------------- /src/561.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def arrayPairSum(nums: Array[Int]): Int = { 3 | 4 | val sorted_nums = nums.sorted 5 | 6 | val values_to_keep = for (i <- (0 until nums.length by 2)) yield sorted_nums(i) 7 | 8 | values_to_keep.sum 9 | } 10 | } -------------------------------------------------------------------------------- /src/572.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | 11 | def isSameTree(p: TreeNode, q: TreeNode): Boolean = { 12 | if (p == null && q == null) { 13 | true 14 | } else if (p != null && q == null) { 15 | false 16 | } else if (p == null && q != null) { 17 | false 18 | } else if (p.value == q.value) { 19 | isSameTree(p.left, q.left) && isSameTree(p.right, q.right) 20 | } else { 21 | false 22 | } 23 | } 24 | 25 | 26 | def isSubtree(s: TreeNode, t: TreeNode): Boolean = { 27 | 28 | if (s == null) { 29 | if (t == null) { 30 | true 31 | } else { 32 | false 33 | } 34 | } else if (s.value == t.value) { 35 | if (isSameTree(s, t)) { 36 | true 37 | } else { 38 | isSubtree(s.left, t) || isSubtree(s.right, t) 39 | } 40 | } else { 41 | isSubtree(s.left, t) || isSubtree(s.right, t) 42 | } 43 | 44 | } 45 | } -------------------------------------------------------------------------------- /src/599.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def findRestaurant(list1: Array[String], list2: Array[String]): Array[String] = { 3 | 4 | // convert one of the two lists into immutable Map 5 | val map_1 = list1.zip((0 until list1.length)).toMap 6 | 7 | 8 | // iterate on another list, and save the results into a Map (like dict in Python) 9 | // the key in the map will be the sum of index, and the values will be list of the corresponding item(s) 10 | val result_map = scala.collection.mutable.HashMap[Int, Array[String]]() 11 | 12 | for (i <- 0 until list2.length) { 13 | if (map_1.contains(list2(i))) { 14 | val temp_index_sum = i + map_1(list2(i)) 15 | if (result_map contains temp_index_sum) { 16 | result_map(temp_index_sum) = result_map(temp_index_sum) ++ Array(list2(i)) 17 | } else { 18 | result_map(temp_index_sum) = Array(list2(i)) 19 | } 20 | 21 | } 22 | } 23 | 24 | 25 | result_map(result_map.keys.min) 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /src/606.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | def tree2str(t: TreeNode): String = { 11 | if (t == null) { 12 | "" 13 | } else if (t.left == null && t.right == null) { 14 | t.value.toString 15 | } else if (t.right == null){ 16 | s"${t.value.toString}(${tree2str(t.left)})" 17 | } else if (t.left == null) { 18 | s"${t.value.toString}()(${tree2str(t.right)})" 19 | } else { 20 | s"${t.value.toString}(${tree2str(t.left)})(${tree2str(t.right)})" 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/617.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | def mergeTrees(t1: TreeNode, t2: TreeNode): TreeNode = { 11 | 12 | if (t1 == null) { 13 | t2 14 | } else if (t2 == null) { 15 | t1 16 | } else { 17 | t1.value += t2.value 18 | t1.left = mergeTrees(t1.left, t2.left) 19 | t1.right = mergeTrees(t1.right, t2.right) 20 | t1 21 | } 22 | 23 | } 24 | } -------------------------------------------------------------------------------- /src/657.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def judgeCircle(moves: String): Boolean = { 3 | 4 | val pairs = List(('U', 'D'), ('L', 'R')) 5 | val result = pairs.map(p => moves.filter(_ == p._1).length == moves.filter(_ == p._2).length) 6 | 7 | result(0) & result(1) 8 | } 9 | } -------------------------------------------------------------------------------- /src/669.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | def trimBST(root: TreeNode, L: Int, R: Int): TreeNode = { 11 | 12 | if (root == null) { 13 | null 14 | } else if (root.value > R) { 15 | trimBST(root.left, L, R) 16 | } else if (root.value < L) { 17 | trimBST(root.right, L, R) 18 | } else { 19 | root.left = trimBST(root.left, L, R) 20 | root.right = trimBST(root.right, L, R) 21 | root 22 | } 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /src/697.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def findShortestSubArray(nums: Array[Int]): Int = { 3 | 4 | // [Example of `nums`]: [1, 2, 2, 3, 2, 3, 2, 3, 3] 5 | 6 | import collection.mutable.ArrayBuffer 7 | 8 | val map_locations_of_each_unique_element = collection.mutable.HashMap[Int, ArrayBuffer[Int]]() 9 | 10 | // traverse all the elements in `nums`, and record the indexes of each unique element 11 | for ((x, i) <- nums.zipWithIndex) { 12 | if (map_locations_of_each_unique_element.contains(x)) { 13 | map_locations_of_each_unique_element(x) += i 14 | } else { 15 | map_locations_of_each_unique_element(x) = ArrayBuffer(i) 16 | } 17 | } 18 | 19 | // println(map_locations_of_each_unique_element) 20 | // print result: Map(2 -> ArrayBuffer(1, 2, 4, 6), 1 -> ArrayBuffer(0), 3 -> ArrayBuffer(3, 5, 7, 8)) 21 | 22 | 23 | // We can calculate the degree based on the result from the last step 24 | val index_groups = map_locations_of_each_unique_element.values // Only keep `values`. The `key` doesn't matter anymore from here. 25 | val degree = index_groups.map(_.length).max 26 | 27 | // println(index_groups) 28 | // print result: HashMap(ArrayBuffer(1, 2, 4, 6), ArrayBuffer(0), ArrayBuffer(3, 5, 7, 8)) 29 | 30 | // println(degree) 31 | // print result: 4 32 | 33 | // Then, we can know the starting index and ending index of our target subarray quite easily. 34 | // In the example I gave, the target subarray either starts at index 1 and ends at index 6, or starts at index 3 and ends at index 8. 35 | index_groups.filter(_.length == degree).map(x => x.last - x.head + 1).min 36 | } 37 | } -------------------------------------------------------------------------------- /src/7.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def reverse(x: Int): Int = { 3 | 4 | // METHOD-1 5 | // if (x == 0) { 6 | // 0 7 | // } else { 8 | // val xx = math.abs(x).toString.reverse 9 | // var start_to_record = false 10 | // val temp = collection.mutable.ArrayBuffer[Char]() 11 | 12 | // for (x <- xx) { 13 | 14 | // if (start_to_record == false && x != '0') { 15 | // start_to_record = true 16 | // } 17 | 18 | // if (start_to_record) { 19 | // temp += x 20 | // } 21 | 22 | // } 23 | 24 | // try { 25 | // ({if (x >= 0) "" else "-"} + temp.mkString).toInt 26 | // } catch { 27 | // case e: java.lang.NumberFormatException => 0 28 | // } 29 | // } 30 | 31 | 32 | // METHOD-2 33 | if (x == 0) { 34 | 0 35 | } else { 36 | 37 | val xx = math.abs(x).toString.reverse 38 | 39 | // find the first element not equaling to 0 40 | // Here I used method `.find`. It finds and returns the first element of the list satisfying a predicate, if any. 41 | // `.find` returns Some(*), so need to use `.get` 42 | val intermediate_result = xx.slice(xx.zipWithIndex.find(_._1 != '0').get._2, xx.length) 43 | 44 | // 1. Use if-else to handle possible negative integers. 45 | // 2. use try-catch to handle cases like "1534236469" 46 | // which will cause exception java.lang.NumberFormatException: For input string: "9646324351" 47 | // due to Int.MaxValue is 2147483647 48 | try { 49 | ({if (x >= 0) "" else "-"} + intermediate_result).toInt 50 | } catch { 51 | case e: java.lang.NumberFormatException => 0 52 | } 53 | 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/733.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def floodFill(image: Array[Array[Int]], sr: Int, sc: Int, newColor: Int): Array[Array[Int]] = { 3 | 4 | val n_row = image.length 5 | val n_col = image(0).length 6 | val startColor = image(sr)(sc) 7 | 8 | if (startColor == newColor) { 9 | image 10 | } else { 11 | 12 | def FUN_update_pixel(r: Int, c: Int): Unit = { 13 | if (image(r)(c) == startColor) { 14 | image(r)(c) = newColor 15 | println(s"($r, $c)") 16 | 17 | // Check four directions one by one, and invoke RECURSION 18 | if (r - 1 >= 0) FUN_update_pixel(r-1, c) 19 | if (r + 1 < n_row) FUN_update_pixel(r+1, c) 20 | if (c - 1 >= 0) FUN_update_pixel(r, c-1) 21 | if (c + 1 < n_col) FUN_update_pixel(r, c+1) 22 | } 23 | } 24 | 25 | FUN_update_pixel(sr, sc) 26 | 27 | image 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/744.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def nextGreatestLetter(letters: Array[Char], target: Char): Char = { 3 | 4 | // Char can be compared just like comparing Integers. 5 | 6 | // Only for "wrapping around" cases (like target = 'z' and letters = ['a', 'b'], the answer is 'a'), 7 | // we need to convert Char into Integers and add/subtract 26. 8 | 9 | if (letters.exists(_ > target)) { 10 | letters.filter(_ > target).min 11 | } else { 12 | (letters.map(_.toInt).map(_.toInt + 26).filter(_ > target.toInt).min - 26).toChar 13 | } 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /src/747.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def dominantIndex(nums: Array[Int]): Int = { 3 | 4 | val n = nums.length 5 | 6 | if (n == 1) { 7 | 0 8 | } else { 9 | 10 | val sorted_nums = nums.sorted 11 | 12 | if (sorted_nums(n - 1) >= sorted_nums(n-2) * 2) { 13 | nums.indexOf(sorted_nums(n - 1)) 14 | } else { 15 | -1 16 | } 17 | 18 | } 19 | 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /src/781.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def numRabbits(answers: Array[Int]): Int = { 3 | 4 | answers.toSet.toArray.map{ 5 | x => math.ceil(answers.count(_ == x) / (x+1.0)) * (x+1) 6 | }.sum.toInt 7 | 8 | } 9 | } -------------------------------------------------------------------------------- /src/784.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def letterCasePermutation(S: String): List[String] = { 3 | 4 | val regex= "[0-9]".r 5 | 6 | def to_repeat(last_list: List[String], char_to_add: Char) = { 7 | if(regex.findFirstIn(char_to_add.toString) == None) { 8 | for (x <- last_list; y<-List(char_to_add.toString.toUpperCase, char_to_add.toString.toLowerCase)) yield x++y 9 | } else { 10 | for (x <- last_list) yield x++char_to_add.toString 11 | } 12 | } 13 | 14 | 15 | var result = List("") 16 | 17 | for (i <- 0 until S.length) { 18 | result = to_repeat(result, S(i)) 19 | } 20 | 21 | result 22 | } 23 | } -------------------------------------------------------------------------------- /src/804.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def uniqueMorseRepresentations(words: Array[String]): Int = { 3 | 4 | val mapping = ('a' to 'z').zip(List(".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..")).toMap 5 | 6 | val result = for (x <- words.map(x=>x.map(mapping.getOrElse(_, "!")))) yield { 7 | 8 | var temp = "" 9 | 10 | for (y <- x) { 11 | temp = temp.concat(y.toString) 12 | } 13 | 14 | temp 15 | } 16 | 17 | result.distinct.length 18 | } 19 | } -------------------------------------------------------------------------------- /src/806.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def numberOfLines(widths: Array[Int], S: String): Array[Int] = { 3 | 4 | val mapping = ('a' to 'z').zip(widths).toMap 5 | 6 | var current_line_width = 0 7 | var N_lines = 1 8 | 9 | for (i <- S) { 10 | 11 | if (current_line_width + mapping(i) > 100) { 12 | current_line_width = 0 13 | N_lines += 1 14 | 15 | current_line_width += mapping(i) 16 | 17 | } else { 18 | current_line_width += mapping(i) 19 | } 20 | 21 | } 22 | 23 | Array(N_lines, current_line_width) 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /src/811.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def subdomainVisits(cpdomains: Array[String]): List[String] = { 3 | 4 | val domain_tuples = for (i <- cpdomains.map(x => x.split(" ")); 5 | split_domains = i(1).split('.'); 6 | j <- (1 to split_domains.length).map(split_domains.takeRight(_).mkString("."))) 7 | yield (j, i(0)) 8 | 9 | var result = domain_tuples.groupBy(_._1).mapValues(group => group.map(_._2.toInt).sum) 10 | // Another way to sum by key 11 | // var result = for { (key, xs) <- domain_tuples.groupBy(_._1) 12 | // } yield (key, xs.map(_._2.toInt).sum) 13 | 14 | result.map(x => x._2.toString + " " + x._1).toList 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/819.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def mostCommonWord(paragraph: String, banned: Array[String]): String = { 3 | 4 | var paragraph_lowercase: String = paragraph.map(_.toLower) 5 | 6 | val regex = "[!?',;.]".r 7 | paragraph_lowercase = regex.replaceAllIn(paragraph_lowercase, "") 8 | 9 | 10 | var word_list = paragraph_lowercase.split(' ') 11 | 12 | for (i <- 0 until banned.length){ 13 | word_list = word_list.filter(_ != banned(i)) 14 | } 15 | 16 | word_list.groupBy(identity).maxBy(_._2.size)._1 17 | } 18 | } -------------------------------------------------------------------------------- /src/821.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def shortestToChar(S: String, C: Char): Array[Int] = { 3 | 4 | val locations_of_C = (0 until S.length).filter(i => S(i) == C) 5 | 6 | val result = (0 until S.length).map(i => (locations_of_C.map(_ - i).map(_.abs) ++ locations_of_C.map(i - _).map(_.abs)).min) 7 | 8 | result.toArray 9 | } 10 | } -------------------------------------------------------------------------------- /src/824.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def toGoatLatin(S: String): String = { 3 | 4 | val S_split = S.split(' ') 5 | 6 | var vowel: List[String] = List("a", "e", "i", "o", "u") 7 | vowel = vowel ++ vowel.map(_.toUpperCase) 8 | 9 | def process(x: String, i: Int): String = { 10 | if(vowel.exists(start_letter => x.startsWith(start_letter))) { 11 | val xx = x + "ma" + "a" * i 12 | xx 13 | } else { 14 | val x_0 = x(0) 15 | val xx = x.drop(1) + x_0 + "ma" + "a" * i 16 | xx 17 | } 18 | } 19 | 20 | S_split.zipWithIndex.map(x => process(x._1, x._2 + 1)).mkString(" ") 21 | } 22 | } -------------------------------------------------------------------------------- /src/825.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def numFriendRequests(ages: Array[Int]): Int = { 3 | 4 | //sort the "ages" first. This can help make better use of the second condition "age[B] > age[A]" 5 | val ages_sorted = ages.sorted.reverse 6 | val n = ages_sorted.length 7 | 8 | var count = 0 9 | 10 | for ((x, i) <- ages_sorted.slice(0, n - 1).zipWithIndex) { 11 | 12 | var j = i + 1 13 | 14 | while (j <= n - 1) { 15 | 16 | // use the age at current index to compare with the following age(s) 17 | if ((ages_sorted(j) > 0.5 * x + 7) & ((ages_sorted(j) <= 100) | (x >=100))) { 18 | count += 1 19 | } 20 | 21 | // if the following age is the same as the age at current index, should consider mutual request. 22 | if (ages_sorted(j) == x) { 23 | if ((x > 0.5 * ages_sorted(j) + 7) & (x <= 100) | ((ages_sorted(j) >=100))) { 24 | count += 1 25 | } 26 | } 27 | j += 1 28 | } 29 | } 30 | 31 | count 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /src/830.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def largeGroupPositions(S: String): List[List[Int]] = { 3 | 4 | var current_char = S(0) 5 | var current_group_length = 1 6 | var current_group_start_index = 0 7 | 8 | val result = collection.mutable.ListBuffer[List[Int]]() 9 | 10 | for (i <- 1 until S.length) { 11 | if (S(i) != current_char) { 12 | 13 | if (current_group_length >= 3) result += List(current_group_start_index, i - 1) 14 | 15 | current_char = S(i) 16 | current_group_start_index = i 17 | current_group_length = 1 18 | 19 | } else { 20 | current_group_length += 1 21 | } 22 | 23 | // examine for the LAST char of String "S" 24 | if (i == (S.length - 1) && current_group_length >= 3){ 25 | result += List(current_group_start_index, i) 26 | } 27 | 28 | } 29 | 30 | result.toList 31 | } 32 | } -------------------------------------------------------------------------------- /src/831.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def maskPII(S: String): String = { 3 | 4 | if (S.contains('@')) { 5 | // Case - 1: Email Address 6 | val S_lower: String = S.toLowerCase 7 | val SS = S_lower.split('@') 8 | SS(0)(0) + "*****" + SS(0)(SS(0).length - 1) + "@" + SS(1) 9 | } else { 10 | 11 | // if it's phone number, only keep digits inside for further processing 12 | val pattern = "[0-9]".r 13 | val numbers = pattern.findAllIn(S).toArray 14 | 15 | if (numbers.length == 10) { 16 | // Case - 2: Local Phone Number 17 | "***-***-" + numbers.slice(numbers.length - 4, numbers.length).mkString 18 | } else { 19 | // Case - 3: International Phone Number 20 | "+" + "*" * (numbers.length-10) + "-***-***-" + numbers.slice(numbers.length - 4, numbers.length).mkString 21 | } 22 | 23 | } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /src/832.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def flipAndInvertImage(A: Array[Array[Int]]): Array[Array[Int]] = { 3 | 4 | A.map(row => row.map(x => if (x==1) 0 else 1).reverse) 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /src/833.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def findReplaceString(S: String, indexes: Array[Int], sources: Array[String], targets: Array[String]): String = { 3 | 4 | // indexes doesn't have to be sorted, it may be something like [3,5,1] 5 | val sources_updated = sources.zip(indexes).sortBy(_._2).map(_._1) 6 | val targets_updated = targets.zip(indexes).sortBy(_._2).map(_._1) 7 | var indexes_updated = indexes.sorted ++ Array(S.length) 8 | 9 | val segments = (0 until (indexes.length)).map(i => S.substring(indexes_updated(i), indexes_updated(i+1)) ) 10 | 11 | val result = segments.zipWithIndex.map(x => if (x._1.take(sources_updated(x._2).length) == sources_updated(x._2)) x._1.replaceFirst(sources_updated(x._2), targets_updated(x._2)) else x._1) 12 | 13 | 14 | // the codes above can't handle the cases in which min value indexes is NOT 0. 15 | // so the final return statement needs to handle this. 16 | if (indexes_updated(0) == 0) { 17 | result.toArray.mkString 18 | } else { 19 | S.substring(0, indexes_updated(0)) + result.toArray.mkString 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/841.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def canVisitAllRooms(rooms: List[List[Int]]): Boolean = { 3 | 4 | 5 | // SOLUTION - 1: FAILED. not working for case like [[4],[3],[],[2,5,7],[1],[],[8,9],[],[],[6]] 6 | // val all_keys = rooms.zipWithIndex 7 | // .map(x => (x._1.filter(_ != x._2), x._2)) 8 | // .map(_._1) 9 | // .flatMap(x => x) 10 | 11 | // println(all_keys) 12 | // println((0 until rooms.length).filter(x => all_keys.contains(x))) 13 | 14 | // (1 until rooms.length).filter(x => all_keys.contains(x)).length == (rooms.length - 1) 15 | 16 | 17 | 18 | // SOLUTION - 2: a working solution using recursion idea 19 | import collection.mutable.ArrayBuffer 20 | 21 | val room_can_enter = ArrayBuffer[Int]() 22 | val n = rooms.length 23 | 24 | def FUN_traverse(keys: List[Int]): Unit = { 25 | 26 | val filtered_keys = keys.filter(room_can_enter.contains(_) == false) 27 | 28 | filtered_keys.foreach(room_can_enter += _) 29 | filtered_keys.foreach(x=> FUN_traverse(rooms(x)) ) 30 | 31 | } 32 | 33 | FUN_traverse(rooms(0)) 34 | 35 | room_can_enter -= 0 // room 0 is already opened 36 | room_can_enter.distinct.length == (n - 1) // room 0 is already opened so "n minus 1" 37 | 38 | } 39 | } -------------------------------------------------------------------------------- /src/844.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def backspaceCompare(S: String, T: String): Boolean = { 3 | 4 | import collection.mutable.ArrayBuffer 5 | 6 | def FUN_process(X: String): String = { 7 | // Use ArrayBuffer as a Stack 8 | val XX = ArrayBuffer[Char]() 9 | 10 | for (i <- X) { 11 | if (i == '#') { 12 | if (XX.length != 0) { 13 | XX.remove(XX.length - 1) 14 | } 15 | } else { 16 | XX += i 17 | } 18 | } 19 | 20 | XX.mkString 21 | } 22 | 23 | FUN_process(S) == FUN_process(T) 24 | } 25 | } -------------------------------------------------------------------------------- /src/848.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def shiftingLetters(S: String, shifts: Array[Int]): String = { 3 | 4 | val S_array = S.toArray 5 | 6 | val char_to_int_starting = 'a'.toInt 7 | 8 | // The current complexity is about O(n^2) 9 | // Should be able to make is O(n) 10 | 11 | for (i <- 0 until shifts.length) { 12 | for (j <- 0 to i) { 13 | S_array(j) = ((S_array(j) - char_to_int_starting + shifts(i)) % 26 + char_to_int_starting).toChar 14 | } 15 | } 16 | 17 | S_array.mkString 18 | } 19 | } -------------------------------------------------------------------------------- /src/884.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def uncommonFromSentences(A: String, B: String): Array[String] = { 3 | 4 | // Solution-1 5 | // val A_split = A.split(' ') 6 | // val B_split = B.split(' ') 7 | 8 | // val A_duplicates = A_split.filter(x => A_split.count(_ == x) > 1).toSet 9 | // val B_duplicates = B_split.filter(x => B_split.count(_ == x) > 1).toSet 10 | 11 | // val A_set = A_split.toSet 12 | // val B_set = B_split.toSet 13 | 14 | // val result = A_set.union(B_set) diff A_set.intersect(B_set) diff A_duplicates.union(B_duplicates) 15 | // result.toArray 16 | 17 | // Solution-2 18 | import scala.collection.mutable.Map 19 | 20 | val result = Map[String, Int]() 21 | val A_split = A.split(' ') 22 | val B_split = B.split(' ') 23 | 24 | val elements = A_split ++ B_split 25 | 26 | for (x <- elements){ 27 | if (result.contains(x)) { 28 | result(x) += 1 29 | } else { 30 | result(x) = 1 31 | } 32 | } 33 | 34 | result.filter(x => x._2 == 1).keys.toArray 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/94.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * class TreeNode(var _value: Int) { 4 | * var value: Int = _value 5 | * var left: TreeNode = null 6 | * var right: TreeNode = null 7 | * } 8 | */ 9 | object Solution { 10 | def inorderTraversal(root: TreeNode): List[Int] = { 11 | 12 | val result = collection.mutable.ArrayBuffer[Int]() 13 | 14 | def FUN_traverse(node: TreeNode): Unit = { 15 | if (node != null) { 16 | // 1st: LEFT 17 | FUN_traverse(node.left) 18 | // 2nd: current node value 19 | result += node.value 20 | // 3rd: RIGHT 21 | FUN_traverse(node.right) 22 | } 23 | } 24 | 25 | FUN_traverse(root) 26 | result.toList 27 | } 28 | } -------------------------------------------------------------------------------- /src/941.scala: -------------------------------------------------------------------------------- 1 | object Solution { 2 | def validMountainArray(A: Array[Int]): Boolean = { 3 | 4 | // Use || here to ensure `A(1) <= A(0)` will not be called if A.length < 3 5 | if (A.length < 3 || A(1) <= A(0)) { 6 | return false 7 | } 8 | 9 | var first_half_met = false 10 | 11 | for (i <- 1 until A.length) { 12 | if (A(i) == A(i-1)) { 13 | return false 14 | } 15 | 16 | if (first_half_met == false) { 17 | if (A(i) < A(i-1)) { 18 | first_half_met = true 19 | } 20 | } else { 21 | if (A(i) > A(i-1)) { 22 | return false 23 | } 24 | } 25 | } 26 | 27 | if (first_half_met == false) return false 28 | 29 | return true 30 | } 31 | } -------------------------------------------------------------------------------- /src/MyHashSet.scala: -------------------------------------------------------------------------------- 1 | class MyHashSet (var n_buckets: Int = 10) { 2 | 3 | private var container = Array(List[Int]()) 4 | 5 | for (i <- 1 until n_buckets) container :+= List[Int]() 6 | 7 | def add(key: Int): Unit = { 8 | val index = key % n_buckets 9 | if (container(index).contains(key) == false) container(index) = container(index) ::: List(key) 10 | } 11 | 12 | def remove(key: Int): Unit = { 13 | val index = key % n_buckets 14 | if (container(index).contains(key) == true) container(index) = container(index).filter(_ != key) 15 | } 16 | 17 | def contains(key: Int): Boolean = { 18 | val index = key % n_buckets 19 | if (container(index).contains(key) == true) true else false 20 | } 21 | 22 | } 23 | 24 | 25 | val set_1 = new MyHashSet(100) 26 | 27 | println(set_1.contains(10)) 28 | set_1.add(10) 29 | println(set_1.contains(10)) 30 | set_1.remove(10) 31 | println(set_1.contains(10)) --------------------------------------------------------------------------------