题解 | Java版本#设计LRU缓存结构#三种方法

最长上升子序列(一)

http://www.nowcoder.com/practice/5164f38b67f846fb8699e9352695cd2f

https://www.cnblogs.com/liujinhui/p/15870261.html
方法1:使用动态规划
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 给定数组的最长严格上升子序列的长度。
     * @param arr int整型一维数组 给定的数组
     * @return int整型
     */
    public int LIS (int[] arr) {
        //动态规划实现
        //最长子序列应当使用max值记录
        int n = arr.length;
        if(n == 0) {
            return 0;
        }
        int[] dp = new int[n];
        Arrays.fill(dp, 1);
        int maxLen = Integer.MIN_VALUE;
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < i; j++) {
                if(arr[j] < arr[i]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
                maxLen = Math.max(maxLen, dp[i]);
            }
        }
        return maxLen;
    }
}
方法2:使用贪心+二分
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 给定数组的最长严格上升子序列的长度。
     * @param arr int整型一维数组 给定的数组
     * @return int整型
     */
    public int LIS (int[] arr) {
        int len = 1, n = arr.length;
        if(n == 0) {
            return 0;
        }
        int[] lisArr = new int[n + 1];
        lisArr[len] = arr[0];
        for(int i = 1; i < n; i++) {
            //len代表lisArr中的最后一个元素
            if(lisArr[len] < arr[i]) {
                lisArr[++len] = arr[i];
            } else {
                //二分,在lisArr数组中找比arr[i]小的,最靠后的位置pos
                //未找到,即lisArr数组中所有元素均大于arr[i]
                //需要更新lisArr数组的位置,为何不设为1呢?
                int l = 1,r = len, pos = 0;
                while(l <= r) {
                    //int mid = l + (r - l) >> 1;是错误的,原因是优先级导致的
                    int mid = l + ((r - l) >> 1);//位运算是为了避免溢出
                    //int mid = (l + r) >> 1;
                    if(lisArr[mid] < arr[i]) {
                        //更新指针
                        l = mid + 1;
                        pos = mid;
                    } else {
                        r = mid - 1;
                    }
                }
                //循环结束,找到了pos
                lisArr[pos + 1] = arr[i];
                //pos是最后一个位置,len不变
                //pos是中间位置,len仍不变,元素继续往后填
                //所以没有必要更新len位置
            }
        }
        return len;
    }
}
方法3:使用库函数
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 给定数组的最长严格上升子序列的长度。
     * @param arr int整型一维数组 给定的数组
     * @return int整型
     */
    public int LIS (int[] arr) {
        //使用二分查找确定插入位置
        //贪心
        int n = arr.length, len = 1;
        if(n <= 1) {
            return n;
        }
        int[] lisArr = new int[n + 1];
        lisArr[len] = arr[0];
        for(int i = 1; i < n; i++) {
            if(lisArr[len] < arr[i]) {
                lisArr[++len] = arr[i];
            } else {
                //从1开始
                int res = Arrays.binarySearch(lisArr, 1, len + 1, arr[i]);
                if(res >= 0) { //表示找到了插入位置
                    //即存在相同元素时,跳过
                    continue;
                } else { //表示没有找到插入位置
                    //则res<0
                    //其值表示应插入位置的负数
                    int ins = -(res + 1);
                    lisArr[ins] = arr[i];
                }
            }
        }
        return len;
    }
}
参考:https://www.cnblogs.com/liujinhui/p/15870261.html
全部评论

相关推荐

一颗宏心:华为HR晚上过了十二点后还给我法消息。
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务