• leetcode300


    本题使用回溯法,深度优先搜索。使用隐式条件来进行加速。

    public class Solution
        {
            int bestp = 0;
            int[] x;
            Dictionary<int, int> dic = new Dictionary<int, int>();
    
            void Backtrack(int[] nums, int t)
            {
                if (t >= nums.Length)
                {
                    var sum = 0;
                    for (int i = 0; i < nums.Length; i++)
                    {
                        if (x[i] == 1)
                        {
                            //Console.Write(nums[i]+"   ");
                            sum++;
                        }                    
                    }
                    //Console.WriteLine();
                    bestp = Math.Max(bestp, sum);
                    return;
                }
    
                if (dic.Count == 0 || dic.LastOrDefault().Value < nums[t])
                {
                    x[t] = 1;
                    dic.Add(t, nums[t]);
                    Backtrack(nums, t + 1);
                    dic.Remove(t);
                }
                if (dic.Count + nums.Length - (t + 1) > bestp)
                {
                    x[t] = 0;
                    Backtrack(nums, t + 1);
                }
            }
    
            public int LengthOfLIS(int[] nums)
            {
                if (nums.Length < 2)
                {
                    return nums.Length;
                }
                
                x = new int[nums.Length];
                Backtrack(nums, 0);
    
                return bestp;
            }
        }

     补充一个使用动态规划的方法,使用python实现,但是效率不是很高:

     1 class Solution:
     2     def lengthOfLIS(self, nums: 'List[int]') -> 'int':
     3         n = len(nums)
     4         if n==0:
     5             return 0
     6         maxnum = 0
     7         dp = [1] * n
     8         for i in range(n):
     9             for j in range(i):
    10                 if nums[i] > nums[j]:
    11                     dp[i] = max(dp[i],dp[j] + 1)
    12                     print(dp[i])
    13             maxnum = max(maxnum,dp[i])
    14         return maxnum

    思路分析:双层循环,时间复杂度是O(n^2)。

    dp[i]表示在nums中,以nums[i]为结尾的自增子序列的长度。

    第13行是在外层循环,每次循环结束的时候更新,全局的最长自增子序列的长度,也就是所求。

    内层循环,是从当前位置i,向前寻找[0,i-1]闭区间。如果在nums中,i前面有一个元素j,满足nums[i] > nums[j],则可以在以j为结尾的自增子序列上,增加1的长度,构成新的自增子序列,而dp[i]只保存这些可能构成的新自增子序列中最大的长度。 

    补充一个java的实现,使用二分查找加速查询,提升效率

     1 class Solution {
     2         public int lengthOfLIS(int[] nums) {
     3             int n = nums.length;
     4             int[] tails = new int[n];
     5             int len = 0;
     6             for (int num : nums) {
     7                 int index = binarySearch(tails, len, num);
     8                 tails[index] = num;
     9                 if (index == len) {
    10                     len++;
    11                 }
    12             }
    13             return len;
    14         }
    15 
    16         private int binarySearch(int[] tails, int len, int key) {
    17             int l = 0, h = len;
    18             while (l < h) {
    19                 int mid = l + (h - l) / 2;
    20                 if (tails[mid] == key) {
    21                     return mid;
    22                 } else if (tails[mid] > key) {
    23                     h = mid;
    24                 } else {
    25                     l = mid + 1;
    26                 }
    27             }
    28             return l;
    29         }
    30     }

  • 相关阅读:
    在 AutoLayout 和 Masonry 中使用动画
    在 AutoLayout 和 Masonry 中使用动画
    Linux shell基础(五)sed命令
    Linux shell基础(五)sed命令
    Linux shell基础(五)sed命令
    Linux shell基础(五)sed命令
    直击高考人机大战:技术、争议与人族胜利
    直击高考人机大战:技术、争议与人族胜利
    直击高考人机大战:技术、争议与人族胜利
    JAVA面试精选【Java基础第一部分】
  • 原文地址:https://www.cnblogs.com/asenyang/p/9743172.html
Copyright © 2020-2023  润新知