LeetCode-300.Longest Increasing Subsequence

https://leetcode.com/problems/longest-increasing-subsequence/

Given an unsorted array of integers, find the length of longest increasing subsequence.

For example,
Given [10, 9, 2, 5, 3, 7, 101, 18],
The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length.

Your algorithm should run in O(n2) complexity.

Follow up: Could you improve it to O(n log n) time complexity?

方法1 动态规划,复杂度O(n2

public int LengthOfLIS(int[] nums) 
    {
        int n = nums.Length,res=1;
        if (n == 0)
            return 0;
        int[] dp = new int[n];
        for (int i = 0; i < n; i++)
        {
            dp[i] = 1;
            for (int j = 0; j  nums[j])
                    dp[i] = Math.Max(dp[i], dp[j] + 1);
            }
            res = Math.Max(res, dp[i]);
        }
        return res;
    }


方法2 O(n log n) ,参考 https://segmentfault.com/a/1190000003819886

public class Solution 
{
    public int LengthOfLIS(int[] nums) 
    {
        int n = nums.Length;
        if (n == 0)
            return 0;
        // len表示当前最长的升序序列长度(为了方便操作tails我们减1)
        int len = 0;
        // tails[i]表示长度为i的升序序列其末尾的数字
        int[] tails = new int[n];
        tails[0] = nums[0];
        // 根据三种情况更新不同升序序列的集合
        for (int i = 1; i < n; i++)
        {
            if (nums[i] < tails[0])
                tails[0] = nums[i];
            else if (nums[i] > tails[len])
                tails[++len] = nums[i];
            else
                // 如果在中间,则二分搜索
                tails[binarySearch(tails, 0, len, nums[i])] = nums[i];
        }
        return len + 1;
    }
    
    private int binarySearch(int[] tails, int min, int max, int target)
    {
        while (min <= max)
        {
            int mid = (max + min) / 2;
            if (tails[mid] == target)
                return mid;
            if (tails[mid] < target)
                min = mid + 1;
            if (tails[mid] > target)
                max = mid - 1;
        }
        return min;
    }
}


方法3

将原数组排序后转化为LCS的问题(LCS算法的C++实现)

public int LengthOfLIS(int[] nums)
        {
            int n = nums.Length, count = 0;
            int[] nums2 = new int[n];
            Array.Copy(nums, nums2, n);
            Array.Sort(nums2);
            int[,] compare = new int[n + 1, n + 1];//记录是否相等
            int[,] direction = new int[n, n];//方向数组
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (nums[i] == nums2[j])
                    {
                        compare[i + 1, j + 1] = compare[i, j] + 1;
                        direction[i, j] = 2;
                    }
                    else
                    {
                        compare[i + 1, j + 1] = Math.Max(compare[i, j + 1], compare[i + 1, j]);
                        direction[i,j] = compare[i,j+1] >= compare[i+1,j] ? 1 : 0;
                    }
                }
            }
            int k = n - 1, m = n - 1;
            while (k>=0&&m>=0)
            {
                if (direction[k, m] == 0)
                    m--;
                else if (direction[k, m] == 1)
                    k--;
                else
                {
                    k--;
                    m--;
                    count++;
                }
            }
            return count;
        }

无法通过LeetCode测试,提示 Memory Limit Exceeded



你可能感兴趣的:(LeetCode,leetcode)