Thinking process I -- DP

The sequence doesn't need to be continuous.

  • which makes the question more difficult.

Then, where to start and where to end?

  • try to find the state that is independent from the next state
  • and the final result rely on the previous states

What is the longest increasing subsequence so far?

  • which means, nums[i] is the last number

Then, how states connect to each other?

  • for each state j < i, how to pass from it to state i?
  • This is possible when nums[j] < nums[i]

Mistakes

increasing!

  • no equal!

State function

if nums[j] <= nums[i]

dp[i] = Math.max(dp[i], dp[j] + 1)

Time Complexity

O(n^2)

public class Solution {
    public int lengthOfLIS(int[] nums) {
        if (nums == null) return -1;

        int[] dp = new int[nums.length];
        int ans = 0;

        for (int i = 0; i < nums.length; ++i) {
            dp[i] = 1;
        }

        for (int i = 0; i < nums.length; ++i) {
            for (int j = 0; j < i; ++j) {
                if (nums[j] < nums[i]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            ans = Math.max(dp[i], ans);
        }

        return ans;
    }
}

There are two possible ways? Which one is feasible?

  • iterate over the input array and find something using binary search
  • search by the range, and iterate over the input array

If it's the first one,

  • find the first element that is larger than nums[i] in dp array
  • initial values are Integer.MAX_VALUE

If it's the second one,

  • can't achieve it using linear time

So, following the first thought, but thinking about this corner cases

  • 1 6 8 5 9
  • the sequence in dp would be
1
1 6
1 6 8
1 5 8
1 5 8 9
  • 1 5 8 9 is not the answer, 1 6 8 9 is.
  • But this doesn't matter, because if we use a smaller number on the right replace one bigger number on the left, the len won' change at all.

Mistakes

the length of minLast array?

the initial values of each number in minLast?

after the loop in binary search function, return left or right?

  • [2, 2] => 1

Time Complexity

O (n log n)

public class Solution {
    public int lengthOfLIS(int[] nums) {
        if (nums == null) return -1;

        int[] minLast = new int[nums.length];//the smallest number that is bigger than current

        for (int i = 0; i < minLast.length; ++i) {
            minLast[i] = Integer.MAX_VALUE;
        }

        for (int i = 0; i < nums.length; ++i) {
            int index = find(minLast, nums[i]);
            minLast[index] = nums[i];
        }

        for (int i = minLast.length - 1; i >= 0; --i) {
            if (minLast[i] != Integer.MAX_VALUE) return i + 1;
        }

        return 0;

    }

    private int find(int[] minLast, int num) {
        int l = 0; 
        int r = minLast.length - 1;

        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (minLast[mid] > num) {
                r = mid;
            } else {
                l = mid;
            }
        }

        if (minLast[l] >= num) {
            return l;
        } 

        return r;
    }
}

results matching ""

    No results matching ""