This repository for the following:
- practice data structures and algorithm
 - with multiple languages: java, scala, kotlin, python, c++, javascript
 - and programming paradigms: functional, declarative, imperative, object-oriented
 
This part will be moved to scala directory
- features: immutability, tail recursion, highorder function, pattern match, lazy evaluation
 
Longest Increasing Subsequence (leetcode)
- functional and declarative style with scala
- highorder function: foldLeft, map, filter etc..
 - immutable data structures: list, which is also persistent.
 
 
  /*
     DP solution
   */
  def lengthOfLIS(nums: List[Int]): Int = {
    // List[(Int, Int)] -> List[(maxLength, maxValue)]
    nums.foldLeft(List[(Int, Int)]()) {
      case (acc, e) => (acc.filter(_._2 < e).map(_._1).maxOption.getOrElse(0) + 1, e) :: acc
    }
      .map(_._1).max
  }- imperative style with java
 
    /*
       DP solution
       - f(i) represent the length of LIS ending at index i such that arr[i] is the last element of the LIS.
       - f(i) = 1 + max( f(j) ) where 0 < j < i and arr[j] < arr[i] or L(i) = 1, if no such j exists
     */
    public int lengthOfLIS(int[] nums) {
        if (nums == null | nums.length == 0)
            return 0;
        final int N = nums.length;
        final int[] f = new int[nums.length];
        for (int i = 0; i < N; i++) {
            int maxValue = 0;
            for (int j = i -1; j >= 0; j--) {
                if (nums[i] > nums[j]) maxValue = Math.max(maxValue, f[j]);
            }
            f[i] = maxValue + 1;
        }
        // return max of f
        int res = 1;
        for (int i = 1; i < N; i++) res = Math.max(res, f[i]);
        return res;
    }Of course, the solution can be improved with binary search. Let's focus on comparing programming styles.
Maximum Subarray (leetcode)
- tail recursion, pattern match
 
  /*
        - f(i) represents max sum of contiguous subarray ending at index i
        - f(i) <- max (f(i - 1) + arr(i), arr(i))
        return max of f
   */
  def maxSubArray(nums: List[Int]): Int = {
    @annotation.tailrec
    def loop(xs: List[Int], acc: Int, m: Int): Int =
      xs match {
        case Nil => m
        case h :: t =>
          val lm = h max (acc + h)
          loop(t, lm, m max lm)
      }
    loop(nums, 0, Int.MinValue)
  }We can solve it with foldLeft as well.