动态规划总结及例题

1.确定数组维数,如果是一维数组行形式,千万不要复杂化问题;

2.注意思考问题无思路时,有限考虑倒数第二部并设为x;

3.子序列问题就想以每一个位置为结尾

4.最值问题不用思考逻辑,只要分类使用min,max就行

5.问题第一步是确定维度

6.二维动态规划明确i、j遍历顺序时,观察公式,进行逻辑演算推论

7.流程=几维变量=判断是什么型=推公式=演绎一个(判断先走x还是先走y,有些不影响可以随便写,有些有影响)=边界条件

8.坐标性dp-》坐标,以i结尾 /序列性dp-》前i个/划分型-》前i个,推得时候利用j满足条件/区间型f(i,j)从i到j/双序列型 ,两个字符串

9.博弈动态规划从第一步开始

10.背包问题中,数组大小和总承重有关


例题

###1左上角走到右下角有多少种走法o(n^2)

public  static  int findMIn(int m,int n){

    int[][] f = new int[m+1][n+1];

    f[0][0]=0;

    f[0][1]=1;

    f[1][0]=1;

    for(int i = 1;i<m+1;i++){

        for(int j =1;j<i;j++){

            f[i][j]= f[i-1][j]+f[i][j-1];

        }

    }

    return f[m][n];

}

###2青蛙跳问题,求是否能跳到o(n^2)

public static boolean findhow(int[] bu){

    int len =bu.length;

    boolean[] f = new boolean[len];

    f[0]=true;

    for(int i =1;i<len;i++){

        for(int j=0;j<i;j++){

            if(f[j]==true && i-j<bu[j]){

                f[i] = true;

            }

        }

    }

    return f[len-1];

}

###3扔鸡蛋问题 o(n^2*k)

public  static  int  eggs(int lou,int dan){

    int[][] f = new int[lou+1][dan+1];

    for(int a =1;a<=lou;a++){

        f[a][1] = a;

    }

    for(int b =1;b<=dan;b++){

        f[1][b] = 1;

    }

    for(int i = 2;i<=lou;i++){

        for(int j =2;j<=dan;j++){

            f[i][j] =Integer.MAX_VALUE;

            for(int k=1;k<i;k++){

                f[i][j] = Math.min(f[i][j],Math.max(f[k-1][j-1]+1,f[i-k][j]+1));

            }

        }

    }

    return f[lou][dan];

}

###4刷房子问题 o(n^2*k)

if(costs==null||costs.length==0||(costs.length==1&&costs[0].length==0)){

    return 0;

}

//costs = rever(costs);

int y = costs[0].length;

int x = costs.length;

int f[][] =new int[x][y];

for(int i=0;i<x;i++){

    f[i][0] = costs[i][0];

}

for(int j =1;j<y;j++){

    //看谁先,要是竖着填就是先遍历y,要是横着填就是先遍历x

    for(int i =0;i<x;i++){

        int res=Integer.MAX_VALUE;

        //二维情况下,如果还有一个变量需要控制则需要再加入k

        for(int k =0;k<x;k++){

            if(k!=i){

                res = Math.min(res,f[k][j-1]);

            }

        }

        f[i][j]=res+costs[i][j];

    }

}

int res =Integer.MAX_VALUE;

for(int i=0;i<x;i++){

    res=Math.min(f[i][y-1],res);

}

return res;

###5区间划分解码问题leetcode91  o(n)

public static int solve(String s){

    int n = s.length();

    //首先全0不行,0开头不行,30及以上结尾的不行

    if(s.charAt(0)-'0'==0){return 0;}

    if(n==1&&s.charAt(0)-'0'!=0){ return 1;}

    int[] f =new int[n];

    if(s.charAt(n-1)-'0'==0&&s.charAt(n-2)-'0'>2){return 0;}

    f[0]=1;

    if(s.charAt(0) - '0'>2&&s.charAt(1) - '0'==0){

        return 0;

    }else if(s.charAt(0)-'0'>2||s.charAt(1)-'0' ==0||s.charAt(0) - '0'==2&&s.charAt(1) - '0'>6) {

        f[1]=1;

    }else {

        f[1] =2;

    }

    for (int i = 0; i < n; i++) {

        if(i+1<n&&s.charAt(i)-'0'==0&&s.charAt(i+1)-'0'==0){

            return 0;

        }

    }

    for(int i = 2;i<n;i++){

//每日小技巧怎么把char转换成int数字,而不要对应的ASCII码

        if(s.charAt(i-1) - '0'>2&&s.charAt(i) - '0'==0){

            return 0;

        }

        if(s.charAt(i-1) - '0'>2||s.charAt(i-1)-'0'==0||s.charAt(i-1) - '0'==2&&s.charAt(i) - '0'>6){

            f[i] = f[i-1];

        }else if(s.charAt(i)-'0'==0) {

            f[i] = f[i-2];

        }else{

            f[i] = f[i-1]+f[i-2];

        }

    }

    return  f[n-1];

}

###6最长上升子序列leetcode300  o(n^2)

public int lengthOfLIS(int[] nums) {

       int n =nums.length;

        if(n==0){

            return 0;

        }

        int[] f = new int[n];

        f[0] =1;

        for(int i= 1;i<n;i++){

            f[i] = 1;

            for(int j=0;j<i;j++){

                if(nums[i]>nums[j]){

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

                }

            }

        }

        int res =Integer.MIN_VALUE;

        for (int i = 0; i < n; i++) {

            res = Math.max(res,f[i]);

        }

        return res;

    }

###7求网格最小路径leetcode64 o(n^2)

public static int findpath(int[][] M){

    if(M==null){

        return  0;

    }

    int x = M.length;

    int y = M[0].length;

    int[][] f = new int[x][y];

    f[0][0] = M[0][0];

    for(int i = 1;i<x;i++){

        f[i][0] = M[i][0]+f[i-1][0];

    }

    for(int j =1;j<y;j++){

        f[0][j] = f[0][j-1]+M[0][j];

    }

    for (int i = 1; i < x; i++) {

        for(int j =1;j<y;j++){

            f[i][j] = Math.min(f[i-1][j],f[i][j-1])+M[i][j];

        }

    }

    return f[x-1][y-1];

}

###8给定数字n,求0~n所有数转成2进制中包含1的个数

//10to2:Integer.toBinaryString(int i)

//2to10:Integer.valueOf("0101",2)

public static void onebits(int N){

    int[] f = new int[N+1];

    f[0] = 0;

    f[1] = 1;

    for(int i =2;i<N+1;i++){

        String str = Integer.toBinaryString(i);

        int n = str.length();

if(str.charAt(n-1)=='0'){

            f[i] = f[Integer.valueOf(str.substring(0,n-1),2)];

        }else {

            f[i] = f[Integer.valueOf(str.substring(0,n-1),2)]+1;

        }

    }

    for (int i = 0; i < N+1; i++) {

        System.out.println(f[i]);

    }

}

    优化:

public static void onebits(int N){

    //10to2:Integer.toBinaryString(int i)

    //2to10:Integer.valueOf("0101",2)

    int[] f = new int[N+1];

    f[0] = 0;

    f[1] = 1;

    for(int i =2;i<N+1;i++){

 //右移等于除以二取下整,左移等于乘2

       f[i] = f[i>>1] +i&1;//imod2写成位操作的形式会快一点

    }

    for (int i = 0; i < N+1; i++) {

        System.out.println(f[i]);

    }

}

###求一个数二进制里1的个数

public static int numberOf1(int n){

        int count = 0;

        while(n!=0){

            if((n&1) != 0){

                ++count;

            }

            n = n >> 1;

        }

        return count;

    }

###9给定数组,求面积最大

public static int findmian(int[] height){

    int n =height.length;

    int index_1 = 0;

    int index_2 = n-1;

    int res = 0;

    while(index_1<index_2){

        res = Math.max((index_2-index_1)*Math.min(height[index_1],height[index_2]),res);

        if(height[index_1]<height[index_2]){

            index_1++;

        }else {

            index_2--;

        }

    }

    return res;

}

###10打家劫舍leetcode198

public static int dajia(int[] nums){

    if(nums.length==0||nums==null){

        return 0;

    }

    int n = nums.length;

    if(n==1){

        return nums[0];

    }

    int[] f= new int[n];

    f[0] =nums[0];

    f[1] =Math.max(nums[0],nums[1]);

    for (int i = 2; i < n; i++) {

        f[i] =Math.max(f[i-2]+nums[i],f[i-1]);

    }

    return f[n-1];

}

###11打家劫舍2 leetcode213

public static int dajia2(int[] nums) {

    if (nums.length == 0 || nums == null) {

        return 0;

    }

    int n = nums.length;

    if (n == 1) {

        return nums[0];

    }

    if (n == 2) {

        return Math.max(nums[0], nums[1]);

    }

    if (n == 3) {

        return Math.max(nums[0],Math.max(nums[1],nums[2]));

    }

    int[] f = new int[n];

    f[0] = nums[0];

    f[1] = Math.max(nums[0], nums[1]);

    for (int i = 2; i < n - 1; i++) {

        f[i] = Math.max(f[i - 2] + nums[i], f[i - 1]);

    }

    int f1 = f[n - 2];

    f[0] = 0;

    f[1] = nums[1];

    for (int i = 2; i < n; i++) {

        f[i] = Math.max(f[i - 2] + nums[i], f[i - 1]);

    }

    int f2 = f[n - 1];

    return Math.max(f1, f2);

}

###12背包问题leetcode1049 

给定一堆数组,要凑出最接近sum的最大值,weight维度为sum,value维度为数组长度。value与weight数组公用一个。

public static int stone2(int [] stones){

    if(stones.length==0||stones==null){

        return 0;

    }

    if(stones.length ==1){

        return stones[0];

    }

    int n = stones.length;

    int sum =0;

  for (int stone : stones) sum += stone;

    int weight = sum/2;

    int[][] f = new int[n][weight+1];

    f[0][0] = 0;

    for (int i = 0; i < n; i++) {

        f[i][0] = 0;

    }

    for (int i = 0; i <weight+1; i++) {

        if(i>=stones[0]){

            f[0][i] = stones[0];

        }else {

            f[0][i] = 0;

        }

    }

    for (int i = 1; i < n; i++) {

        for(int j =1;j<weight+1;j++){

            if(j>=stones[i]){

                f[i][j] = Math.max(f[i-1][j-stones[i]]+stones[i],f[i-1][j]);

            }else{

                f[i][j] = f[i-1][j];

            }

        }

    }

    int res = sum-2*f[n-1][weight];

    return res;

}

优秀代码

public int lastStoneWeightII(int[] stones) {

       int n = stones.length;

        int sum = 0;

        for (int stone : stones) sum += stone;

        int capacity = sum / 2;

        int[][] dp = new int[n + 1][capacity + 1]; // 多加一行方便边界处理

        for (int i = 1; i <= n; i++) { // 枚举石头

            for (int j = 1; j <= capacity; j++) { // 枚举容量

                if (stones[i - 1] > j) { // 当前石头重量大于背包容量放不下

                    dp[i][j] = dp[i - 1][j];

                } else { // 能放下的情况的尝试放和不放两种选择选最优

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

                }

            }

        }

        return sum - 2 * dp[n][capacity];

    }

学到的知识

public static int stone(int[] stones){

    Queue<Integer> stoneweight = new PriorityQueue<Integer>(idComparator);

}

//如何定义优先级队列的形式,其默认从小到大排,且先进先出

public static Comparator<Integer> idComparator=new Comparator<Integer>() {

    public int compare(Integer c1, Integer c2) {

        return (c2-c1);

    }

};

###13股票买卖时间leetcode63 

public static int gupiao(int[] prices){

    int n = prices.length;

    if(n==0||prices==null||n==1){

        return  0;

    }

    int[] f =new int[n];

    f[0] = 0;

    if(prices[0]>prices[1]){

        f[1] = 0;

    }else {

        f[1] = prices[1]-prices[0];

    }

    for (int i = 2; i < n; i++) {

        f[i] = f[i-1]+prices[i]-prices[i-1];

        if(f[i]<0){

            f[i] = 0;

        }

     }

    int max= 0;

    for (int i = 0; i < n; i++) {

        max = Math.max(max,f[i]);

    }

    return max;

}

###14股票买卖时间可以多次买卖leetcode122

public static int gupiaonum(int[] prices){

    int n = prices.length;

    if(n==0||prices==null||n==1){

        return  0;

    }

    int res =0;

    for (int i = 0; i <n-1 ; i++) {

        if(prices[i+1]>prices[i]){

            res+=prices[i+1]-prices[i];

        }

    }

    return res;

}

###15股票买卖时间 n^2(竟然nm没过,其他的看不懂了

public static int gupiaolirun(int[] prices,int start,int end){

    int a = start;

    int b =0;

    int[] price1 =new int[end-start+1];

    while(b<end-start+1){

        price1[b++] = prices[a++];

    }

    int n = price1.length;

    if(n==0||price1==null||n==1){

        return  0;

    }

    int[] f =new int[n];

    f[0] = 0;

    if(price1[0]>price1[1]){

        f[1] = 0;

    }else {

        f[1] = price1[1]-price1[0];

    }

    for (int i = 2; i < n; i++) {

        f[i] = f[i-1]+price1[i]-price1[i-1];

        if(f[i]<0){

            f[i] = 0;

        }

    }

    int max= 0;

    for (int i = 0; i < n; i++) {

        max = Math.max(max,f[i]);

    }

    return max;

}

public static int gupiao(int[] prices){

    int n = prices.length;

    if(n==0||prices==null||n==1){

        return  0;

    }

    if(n==2){

        return Math.max(0,prices[1]-prices[0]);

    }

    int res =0;

    for(int k=1;k<n-1;k++){

        int left = gupiaolirun(prices,0,k);

        int right =gupiaolirun(prices,k,n-1);

        res =Math.max(res,left+right);

   }

   return res;

}

###16股票买卖时间4可以通解3、 leetcode188

学到的

ArrayList<Integer> price1 =new ArrayList<Integer>();

sum=price1.get(1);

解题

public static int gupiao4(int k,int[] prices) {

    int n = prices.length;

    if(n==0||prices==null||n==1||k==0){

        return 0;

    }

    if(n==2){

        return Math.max(0,prices[1]-prices[0]);

    }

  //k超过一半就是无限制次数

    if(k>n/2){

        int res =0;

        for (int i = 0; i <n-1 ; i++) {

            if(prices[i+1]>prices[i]){

                res+=prices[i+1]-prices[i];

            }

        }

        return res;

    }

\\横坐标是阶段数(在0-2k之间)

    int[][] f = new int[n][2 * k + 1];

    for (int i = 0; i < n; i++) {

        f[i][0] = 0;

    }

    for (int i = 0; i < 2 * k+1; i++) {

        f[0][i] = 0;

    }

    for (int i = 1; i < n; i++) {

        for (int j = 1; j < 2 * k+1; j++) {

            if ((j & 1) == 1) {

                f[i][j] = Math.max(f[i - 1][j] + prices[i] - prices[i - 1], f[i - 1][j - 1]);

            } else {

                f[i][j] = Math.max(f[i - 1][j], f[i - 1][j - 1] + prices[i] - prices[i - 1]);

            }

        }

    }

    int res = 0;

    for (int i = 0; i < n; i++) {

        for (int j = 0; j < 2 * k+1; j++) {

if ((j & 1) == 0){

                res = Math.max(res, f[i][j]);

            }

        }

    }

    return res;

}

###17俄罗斯套娃问题leetcode354,建议不要函数调用,dp条件很难改,容易陷入贪心怪局

public int maxEnvelopes(int[][] envelopes) {

        int n =envelopes.length;

        if(n==0||envelopes==null){

            return 0;

        }

        if(n==1){

            return 1;

        }

        Comparator<int[]>comp = new Comparator<int[]>() {

            @Override

            public int compare(int[] o1, int[] o2) {

                if(o1[0]==o2[0]){

                    return o1[1]-o2[1];

                }else {

                    return o1[0]-o2[0];

                }

            }

        };

        Arrays.sort(envelopes,comp);

        int[] dp = new int[n];

        dp[0] =1;

        int res =Integer.MIN_VALUE;

        for(int i= 1;i<n;i++){

            dp[i] = 1;

            for(int j=0;j<i;j++){

                if(envelopes[i][1]>envelopes[j][1]&& envelopes[i][0] > envelopes[j][0]){

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

                }

            }

            res = Math.max(res,dp[i]);

        }

        return res;

    }

###18求一个数可以最少写成几个完全平方数的和leetcode279 o(n√n)

public static int numSquare(int n){

    int[] f =new int[n+1];

    f[0] = 0;

    f[1] = 1;

    for (int i =2;i<=n;i++){

        f[i]  =Integer.MAX_VALUE;

        for (int j = 1; (j*j) <=i; j++) {

            f[i] = Math.min(f[i],f[i-j*j]+1);

        }

    }

    return f[n];

}

###19求一个字符串可以最少划分为多少个回文子串leetcode132

public int minCut(String s) {

        int n = s.length();

        if(n==0||n==1||s==null){

            return 0;

        }

        int[] f =new int[n];

        f[0] = 0;

        for (int i = 1; i <n ; i++) {

            f[i]  =Integer.MAX_VALUE;

            for (int j = 0; j <=i; j++) {

                if(huiwenfou(s.substring(j,i+1))){

                    if(j-1<0){

                        f[i] = 0;

                    }else {

                        f[i] = Math.min(f[i],f[j-1]+1);

                    }

                }

            }

        }

        return f[n-1];

    }

    public  boolean huiwenfou(String s){

        String reverse = new StringBuffer(s).reverse().toString();

        if(s.equals(reverse)){

            return true;

        }

        return false;

    }

###20最长回文子串leetcode05 

public static String longestPalindrome(String s) {

    if (s == null || s.length() == 0) {

        return "";

    }

    int n = s.length();

    boolean[][] f = new boolean[n][n];

    f[0][0] = true;

    for(int j=1;j<n;j++){

        for(int i =0;i<=j;i++){

            if(i==j){

                f[i][j]=true;

            }else if(i+1==j){

                if (s.charAt(i)==s.charAt(j)){

                    f[i][j] =true;

                }else {

                    f[i][j] = false;

                }

            }else if(i+1<=j-1){

                if(f[i+1][j-1]==true&&s.charAt(i)==s.charAt(j)){

                    f[i][j] = true;

                }else {

                    f[i][j] = false;

                }

            }

        }

    }

    int max =Integer.MIN_VALUE;

    String aa = "";

    for (int i = 0; i < n; i++) {

        for (int j = i; j < n; j++) {

            if(f[i][j]==true){

                max =Math.max(max,j-i+1);

                if(j-i+1==max){

                    aa = s.substring(i,j+1);

                }

            }

        }

    }

    return aa;

}

###21求一个字符串中有多少个回文子串leetcode647

class Solution {

    public int countSubstrings(String s) {

         if (s == null || s.length() == 0) {

            return 0;

        }

        int n = s.length();

        boolean[][] f = new boolean[n][n];

        f[0][0] = true;

        for(int j=1;j<n;j++){

            for(int i =0;i<=j;i++){

                if(i==j){

                    f[i][j]=true;

                }else if(i+1==j){

                    if (s.charAt(i)==s.charAt(j)){

                        f[i][j] =true;

                    }else {

                        f[i][j] = false;

                    }

                }else if(i+1<=j-1){

                    if(f[i+1][j-1]==true&&s.charAt(i)==s.charAt(j)){

                        f[i][j] = true;

                    }else {

                        f[i][j] = false;

                    }

                }

            }

        }

        int num = 0;

        for (int i = 0; i < n; i++) {

            for (int j = i; j < n; j++) {

                if(f[i][j]==true){

                   num++;

                }

            }

        }

       return num;

    }

}

###22博弈论从一边拿石子可以拿一个两个 --必胜即有一种情况让对方必败

public static boolean boyi(int n){

    if(n==0){

        return  false;

    }

    boolean[] f =new boolean[n+1];

    f[0] = false;

    f[1] = true;

    f[2] = true;

    for(int i =3;i<n+1;i++){

        if(f[i-1]==true&&f[i-2]==true){

            f[i] = false;

        }else {

            f[i] =true;

        }

    }

    return f[n];

}

###23零钱兑换凑成总金额所需的最少的硬币个数leetcode332

public static int coinChange(int[] coins, int amount){

    int n =coins.length;

    if(amount==0){

        return 0;

    }

    if(n==0||coins==null||amount==0){

        return -1;

    }

    Arrays.sort(coins);

    int[] f =new int[amount+1];

    f[0] = 0;

    for (int i = 1; i < amount+1; i++) {

        f[i] =0x3f3f3f3f;

        for (int j = 0; j < n; j++) {

            if(i>=coins[j]){

                f[i] = Math.min(f[i-coins[j]]+1,f[i]);

            }

        }

    }

    return f[amount] == 0x3f3f3f3f ? -1 : f[amount];

}

###24给定数组,N求不超过N能凑成的最大数量0-1背包1维解法

public static int stonexin(int[]ss,int n){

    int m =ss.length;

    boolean[] f =new boolean[n+1];

    f[0] = true;

    for (int i = 0; i <n+1 ; i++) {

        for (int j = 0; j < m; j++) {

            if(i>=ss[j]){

                f[i] = f[i]||f[i-ss[j]];

            }

        }

    }

    int max =Integer.MIN_VALUE;

    for (int i = 0; i < n+1; i++) {

        if(f[i]==true){

            max =Math.max(max,i);

        }

    }

    return max;

}

背包问题通解

f【i】[w] =f[i-1][w] or f[i-1][w-A[i]]

###25书硬币2leetcode518 二维写法

class Solution {

    public int change(int amount, int[] coins) {

        int n =coins.length;

        if(amount==0){

            return 1;

        }

        if(n==0||coins==null){

            return 0;

        }

        int[][] f =new int[n][amount+1];

        for (int i = 0; i < n; i++) {

            f[i][0] =1;

        }

        for (int j = 1; j < amount+1; j++) {

            for (int i = 0; i < n; i++) {

                if(i==0){

                    if(j%coins[i]==0){

                        f[i][j] =1;

                    }

                }else {

                    if(j>=coins[i]){

                        f[i][j] = f[i-1][j]+f[i][j-coins[i]];

                    }else {

                        f[i][j] = f[i-1][j];

                    }

                }

            }

        }

        return f[n-1][amount];

    }

}

一维写法

public static int coins(int amount,int[] coins){

    int n =coins.length;

    if(amount==0){

        return 1;

    }

    if(n==0||coins==null){

        return 0;

    }

    int[] f =new int[amount+1];

    f[0] =1;

    for (int j = 0; j < n; j++) {

        for (int i = coins[j]; i <amount+1 ; i++) {

            f[i] += f[i-coins[j]];

        }

    }

    return f[amount];

}

###26最长回文子序列

public static int huiwenzixulie(String s){

    int n = s.length();

    if(n==1){

        return 1;

    }

    int[][] f =new int[n][n];

    int max =0;

    f[0][0] =1;

    for (int j = 1; j < n; j++) {

        for (int i = 0; i < j; i++) {

            f[j][j] = 1;

            if(s.charAt(i)==s.charAt(j)){

                f[i][j] = f[i+1][j-1]+2;

            }else {

                f[i][j] = Math.max(f[i+1][j],f[i][j-1]);

            }

            max = Math.max(f[i][j],max);

        }

    }

    return max;

}

###27博弈论左右拿石子(f数组-从i到j能拿到的最大分数)

public static boolean stoneGameII(int[] piles){

    int n = piles.length;

    if(n==0||piles==null){

        return true;

    }

    int[][] f = new int[n][n];

    f[0][0] = piles[0];

    int sum = piles[0];

    for (int j = 1; j < n; j++) {

        sum += piles[j];

        f[j][j] = piles[j];

        for (int i = 0; i < j; i++) {

f[i][j] = Math.max(piles[i] - f[i+1][j],piles[j] - f[i][j-1]);

        }

    }

    if(f[0][n-1] > 0){

        return true;

    }

    return false;

}

###28二分法

public static int search(int[] nums, int target) {

    int n = nums.length;

    int left = 0;

    int right = n-1;

    while(left<right){

        int mid =left+((right-left)>>1);

if(nums[mid]<target){

 left = mid+1;

        }else {

            right = mid;

        }

    }

    return left;

}

###35切绳子

public int cuttingRope(int n) {

        if(n==2)return 1;

        if(n==3)return 2;

        int[] f = new int[n+1];

        f[0] = 0;

        f[1] = 1;

        f[2] = 2;

        for (int i = 3; i < f.length; i++) {

            f[i] = i;

            for (int j = 1; j < i; j++) {

                f[i] = Math.max((i-j)*f[j],f[i]);

            }

        }

        return f[f.length-1];

    }

###二分变种

public boolean search(int[] nums, int target) {

        int l =0,r=nums.length-1;

        while(l<=r){

            int mid = l+(r-l)/2;

            if(nums[mid]==target)return true;

            else if(nums[l]<nums[mid]){

                if(nums[l]<=target && target<nums[mid])r=mid-1;

                else l=mid+1;

            }

            else if(nums[l]>nums[mid]){

                if(nums[r]>=target && target>nums[mid])l=mid+1;

                else r=mid-1;

            }

            else l++;

        }

        return false;

    }

###贪心求最小区间个数

public int findMinArrowShots(int[][] points) {

        if(points.length < 1) return 0;

       Arrays.sort(points, (Comparator.comparingInt(o -> o[1])));

        int count = 1;

        int axis = points[0][1];

        for(int i = 1; i < points.length; ++i) {

            if(axis < points[i][0]) {

                count++;

                axis = points[i][1];

            }

        }

        return count;

    }

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容