leetcode300---最长上升子序列

leetcode300—最长上升子序列原题链接
题意简述

输入: nums []int;
操作: 找出nums中的最长序列长度,满足i>j&&nums[i]>nums[j];
输出: max int,最长上升子序列的长度

解法分析
  • 1.1动态规划
dp[i]:以nums[i]结尾的上升子序列的最大长度;
动态转移方程很容易分析出:
	dp[i]=max(dp[i],dp[j]+1),其中0<=j<i.
  • 1.2复杂度分析

时间复杂度: O(n2);
空间复杂度: O(n);

  • 1.3代码
    java版
class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp = new int[nums.length];
        int max = 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[i] > nums[j]) {
                    dp[i] = Math.max(dp[i],dp[j] + 1);
                }
            }
            max = Math.max(max,dp[i]);
        }
        return max;
    }
}
  • 2.1贪心法
维护一个数组s,当nums[i]比数组末尾元素小的时候,则在s[0]中使用二分法
找到第一个比nums[i]大的元素,然后替换它;如果nums[i]比数组末尾元素大,
则加入数组末尾.
  • 2.2复杂度分析

时间复杂度: O(nlogn)
空间复杂度: O(n)

  • 2.3代码
    JAVA版
class Solution {
    public int lengthOfLIS(int[] nums) {
        if(nums.length == 0) return 0;
        int[] s = new int[nums.length];
        int top = 0;
        s[0] = nums[0];
        for(int i = 1; i < nums.length; i++) {
            if(nums[i] > s[top]) {
                s[++top] = nums[i];
            } else if(nums[i] == s[top]) {
                continue;
            } else {
                int idx = binarySearch(top,s,nums[i]);
                s[idx] = nums[i];
            }
        }
        return top + 1;
    }
    public int binarySearch(int high, int[] nums, int target) {
        int low = 0;
        int top = high;
        while(top > low) {
            int mid = (low + top) >> 1;
            if(nums[mid] >= target) {
                top = mid;
            } else {
                low = mid + 1;
            }
        }
        return top;
    }
}
  • go
func lengthOfLIS(nums []int) int {
	length := len(nums)
	if length == 0 {
		return 0
	}
	var s [100000]int
	top := 0
	s[top] = nums[0]
	for i := 1; i < length; i++ {
		if nums[i] > s[top] {
			top++
			s[top] = nums[i]
		} else if nums[i] == s[top] {
			continue
		} else {
			idx := binarySearch(s[0:(top+1)],nums[i])
			s[idx] = nums[i]
		}
	}
	return top + 1
}

func binarySearch(nums []int, target int) int {
	low := 0
	top := len(nums)
	for top > low {
		mid := (low + top) >> 1
		if nums[mid] >= target {
			top = mid
		} else {
			low = mid + 1
		}
	}
	return top
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值