动态规划dp常考面试题(最长xxx)

连续子数组的最大和

class Solution {
    public int maxSubArray(int[] nums) {
        if(nums == null || nums.length == 0) {
            return -1;
        }
        int ret = nums[0];
        for(int i = 1; i < nums.length; i++) {
            nums[i] += Math.max(nums[i - 1], 0);
            ret = Math.max(ret, nums[i]);
        }
        return ret;
    }
}

连续子数组的最大乘积

import java.util.*;
public class Solution {
    public int maxProduct (int[] nums) {
        //max是以i结尾的最大乘积  min是以i结尾的最小乘积
        int max = nums[0];
        int min = nums[0];
        int ret =  nums[0];
        for (int i = 1; i < nums.length; i++) {
            int tmp = max;
            max = Math.max(nums[i], Math.max(max * nums[i], min * nums[i]));
            min = Math.min(nums[i], Math.min(tmp * nums[i], min * nums[i]));
            ret = Math.max(ret,max);
        }
        return ret;
    }
}

礼物的最大价值

class Solution {
    public int maxValue(int[][] arr) {
        int n = arr.length, m = arr[0].length;
        int[][] f = new int[n + 1][m + 1];
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]) + arr[i - 1][j - 1];

            }
        }
        return f[n][m];
    }
}

矩阵的最小路径(最小路径之和)

三角形最小路径和

题目链接:https://leetcode-cn.com/problems/triangle/

//自底向上
class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int n = triangle.size();
    if (triangle == null || n == 0){
            return 0;
        }
        // 加1可以不用初始化最后一层
        int[][] f = new int[n + 1][n + 1];

        for (int i = n-1; i>=0; i--){
            List<Integer> cur = triangle.get(i);
            for(int j = 0 ; j < cur.size(); j++){
                f[i][j] = Math.min(f[i+1][j], f[i+1][j+1]) + cur.get(j);
            }
        }
        return f[0][0];
    }
}

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int n = triangle.size();
        // dp[i][j] 表示从点 (i, j) 到底边的最小路径和。
        int[][] f = new int[n + 1][n + 1];
        // 从三角形的最后一行开始递推。
        for (int i = n - 1; i >= 0; i--) {
            for (int j = 0; j <= i; j++) {
                f[i][j] = Math.min(f[i + 1][j], f[i + 1][j + 1]) + triangle.get(i).get(j);
            }
        }
        return f[0][0];
    }
}

岛屿的数量

https://www.nowcoder.com/practice/0c9664d1554e466aa107d899418e814e?tpId=117&&tqId=37833&&companyId=139&rp=1&ru=/company/home/code/139&qru=/ta/job-code-high/question-ranking

import java.util.*;
public class Solution {
    public int solve (char[][] grid) {
        // write code here
         int count = 0;
        for(int i = 0; i < grid.length; i++) {
            for(int j = 0; j < grid[0].length; j++) {
                if(grid[i][j] == '1'){
                    dfs(grid, i, j);
                    count++;
                }
            }
        }
        return count;
    }
    private void dfs(char[][] grid, int i, int j){
        if(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == '0') return;
        grid[i][j] = '0';
        dfs(grid, i + 1, j);
        dfs(grid, i, j + 1);
        dfs(grid, i - 1, j);
        dfs(grid, i, j - 1);
    }
}

不同路径I

https://leetcode-cn.com/problems/unique-paths/

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] f = new int[m ][n];        
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (i == 0 || j == 0)
                    f[i][j] = 1;
                else {
                    f[i][j] = f[i - 1][j] + f[i][j - 1];
                }
            }
        }
        return f[m - 1][n - 1];   
    }
}

不同路径II(有障碍版)

https://leetcode-cn.com/problems/unique-paths-ii/

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        if (obstacleGrid == null || obstacleGrid.length == 0) {
            return 0;
        }
        
        // 定义 dp 数组并初始化第 1 行和第 1 列。
        int m = obstacleGrid.length, n = obstacleGrid[0].length;
        int[][] dp = new int[m][n];
        for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) {
            dp[i][0] = 1;
        }
        for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {
            dp[0][j] = 1;
        }

        // 根据状态转移方程 dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 进行递推。
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (obstacleGrid[i][j] == 0) {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                }
            }
        }
        return dp[m - 1][n - 1];
    }
}

最长公共前缀

https://leetcode-cn.com/problems/longest-common-prefix/

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs == null || strs.length == 0) {
            return "";
        }
        String ret = strs[0];
        for(int i = 0; i < strs[0].length(); i++) {
            for(int j = 1; j < strs.length; j++) {
                if(i == strs[j].length() || strs[0].charAt(i) != strs[j].charAt(i)) {
                    return ret.substring(0, i);
                }
            }
        }
        return ret;
    }
}

最长无重复子数组

https://www.nowcoder.com/practice/b56799ebfd684fb394bd315e89324fb4?tpId=117&&tqId=37816&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

public class Solution {
    public int maxLength (int[] nums) {
        // write code here
        if(nums == null) {
            return -1;
        }
        int max = 0;
        int left = 0;
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++) {
            if(map.containsKey(nums[i])) {
                left = Math.max(left, map.get(nums[i]) + 1);
            }
               map.put(nums[i], i);
               max = Math.max(max, i - left + 1);   
        }
        return max;
    }
}

最长不重复子串

https://www.nowcoder.com/practice/b56799ebfd684fb394bd315e89324fb4?tpId=117&&tqId=37816&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

import java.util.*;
public class Solution {
    public int maxLength (int[] nums) {
        // write code here
        if(nums == null || nums.length == 0) {
            return 0;
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        int max = 0, left = 0;
        for(int i = 0; i < nums.length; i++) {
            if(map.containsKey(nums[i])) {
                left = Math.max(left, map.get(nums[i]) + 1);
            }
            map.put(nums[i], i);
            max = Math.max(max, i - left + 1);
        }
        return max;
    }
}


class Solution {
    public int lengthOfLongestSubstring(String s) {
        // 记录字符上一次出现的位置
        int[] last = new int[128];
        for(int i = 0; i < 128; i++) {
            last[i] = -1;
        }
        int n = s.length();

        int res = 0;
        int start = 0; // 窗口开始位置
        for(int i = 0; i < n; i++) {
            int index = s.charAt(i);
            start = Math.max(start, last[index] + 1);
            res   = Math.max(res, i - start + 1);
            last[index] = i;
        }
        return res;
    }
}

最长上升子序列(一)

https://www.nowcoder.com/questionTerminal/5164f38b67f846fb8699e9352695cd2f

import java.util.*;
public class Solution {
    public int LIS (int[] arr) {
        // write code here
        int n = arr.length;
        if(n == 0) return 0;
        int[] f = new int[n];     // dp[i]表示以arr[i]结尾时的最长递增子序列长度
        Arrays.fill(f, 1);
        int max = 1;
        for(int i = 1; i < n; i++){
            for(int j = i - 1; j >= 0; j--){
                if(arr[j] < arr[i]){
                    // arr[j] < arr[i],可以把arr[i]接在arr[j]后面,构成长度为dp[j]+1的递增子序列
                    f[i] = Math.max(f[i], f[j] + 1);     // 选择能构成更长递增子序列的arr[j]
                }
            }
            max = Math.max(max, f[i]);
        }
        return max;
    }
}

最长上升子序列(三)

https://www.nowcoder.com/practice/9cf027bf54714ad889d4f30ff0ae5481?tpId=117&&tqId=37796&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

import java.util.*;


public class Solution {
    /**
     * retrun the longest increasing subsequence
     * @param arr int整型一维数组 the array
     * @return int整型一维数组
     */
    public int[] LIS (int[] arr) {
        // write code here
        int n = arr.length;
        int[] tail = new int[n+1];
        tail[0] = Integer.MIN_VALUE;
        int[] dp = new int[n];
        int end = 0;
        for(int i = 0;i < arr.length; i++){
            int num = arr[i];
            if(num > tail[end]){
                end++;
                dp[i] = end;
                tail[end] = num;
            }else{
                int left = 1;
                int right = end;
                while(left < right){
                    int mid = (left + right) / 2;
                    if(tail[mid] >= num){
                        right = mid;
                    }else if(tail[mid] < num){
                        left = mid + 1;
                    }
                }
                tail[left] = num;
                dp[i] = left;
            }
        }
 
        int[] res = new int[end];
        int length = end;
        for(int i = n - 1;i >= 0; i--){
            if(dp[i] == length){
                res[length - 1] = arr[i];
                length--;
            }
        }
        return res;
    }
}

连续子数组的最大和

https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/

class Solution {
    public int maxSubArray(int[] nums) {
        if(nums == null || nums.length == 0) {
            return -1;
        }
        int ret = nums[0];
        for(int i = 1; i < nums.length; i++) {
            nums[i] += Math.max(nums[i - 1], 0);
            ret = Math.max(ret, nums[i]);
        }
        return ret;
    }
}

最长连续增长序列

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

class Solution {
    public int findLengthOfLCIS(int[] nums) {
         if(nums.length <= 1)
            return nums.length;
        int ret = 1;
        int count = 1;
        for(int i = 0; i < nums.length - 1; i++) {
            if(nums[i+1] > nums[i]) {
                count++;
            } else {  
                count = 1;
            }
            ret = Math.max(ret, count);
        }
        return ret;
    }
}

最长连续序列

https://leetcode-cn.com/problems/longest-consecutive-sequence/

  • set

class Solution {
    public int longestConsecutive(int[] nums) {
        HashSet<Integer> set = new HashSet<Integer>();
        for(int x : nums) {
            set.add(x);
        }   //放入hash表中
        int ret = 0;
        for(int x : set)
        {
            if(!set.contains(x-1))
            {
                int y = x;   //以当前数x向后枚举
                while(set.contains(y + 1))  {
                    y++;
                }
                ret = Math.max(ret, y - x + 1);  //更新答案
            }
        }
        return ret;
    }
}
  • hashset
class Solution {
    public int longestConsecutive(int[] nums) {
        // key表示num,value表示num最远到达的连续右边界
        Map<Integer, Integer> map = new HashMap<>();
        // 初始化每个num的右边界为自己
        for (int num : nums) {
            map.put(num, num);
        }

        int ret = 0;
        for (int num : nums) {
            if (!map.containsKey(num - 1)) {
                int right = map.get(num);
                // 遍历得到最远的右边界
                while (map.containsKey(right + 1)) {
                    right = map.get(right + 1);
                }
                // 更新右边界
                map.put(num, right);
                // 更新答案
                ret = Math.max(ret, right - num + 1);
            }
            
        }
        return ret;
    }
}

最长递增子序列

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

class Solution {
    public int lengthOfLIS(int[] nums) {
       if(nums == null || nums.length == 0) {
           return -1;
       }
       int n = nums.length;
       int[] f = new int[n + 1];
       int ret = 0;
       for(int i = 0; i < n; i++) {
           f[i] = 1;
           for(int j = 0; j < i; j++) {
               if(nums[j] < nums[i]) {
                   f[i] = Math.max(f[i], f[j] + 1);
               }
           }
       }
       for(int i = 0; i < n; i++) {
           ret = Math.max(ret, f[i]);
       }
       return ret;
    }
}

最长公共子串

https://www.nowcoder.com/practice/f33f5adc55f444baa0e0ca87ad8a6aac?tpId=117&&tqId=37799&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

  • 求长度
//最大值
 public static int func(String s1, String s2) {
        int n = s1.length(), m = s2.length();
        int[][] f = new int[n + 1][m + 1];
        int max = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(s1.charAt(i - 1) == s2.charAt(j - 1)) {
                    f[i][j] = Math.max(f[i - 1][j - 1] + 1, f[i][j]);
                    if(f[i][j] > max) {
                        max = f[i][j];
                    }
                }
            }
        }
        return max;
    }
    
  • 求字符串
//求结果
    public static String func2(String s1, String s2) {
        int n = s1.length(), m = s2.length();
        int[][] f = new int[n + 1][m + 1];
        int max = 0, end = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(s1.charAt(i - 1) == s2.charAt(j - 1)) {
                    f[i][j] = Math.max(f[i - 1][j - 1] + 1, f[i][j]);
                    if(f[i][j] > max) {
                        max = f[i][j];
                        end = i;
                    }
                }
            }
        }
        return s1.substring(end - max, end);
    }

最长公共子序列(一) 求长度

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
    int n = text1.length(), m = text2.length();
        int[][] f = new int[n + 1][m + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (text1.charAt(i - 1) != text2.charAt(j - 1)) {
                    f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
                }else {
                    f[i][j] = Math.max(f[i][j], f[i - 1][j - 1] + 1);
                }
            }
        }
        return f[n][m];
    }
}

最长公共子序列(二) 求字符串

import java.util.*;
public class Solution {
    public String LCS (String s1, String s2) {
        // write code here
        int n = s1.length();
        int m = s2.length();
        int [][] f = new int[n + 1][m + 1];
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                if(s1.charAt(i - 1) == s2.charAt(j - 1)){
                    f[i][j] = f[i - 1][j - 1] + 1;
                }else{
                    f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
                }
            }
        }
        if(f[n][m] == 0)return "-1";
        StringBuilder ret = new StringBuilder();
        while(n > 0 && m > 0){
            if(s1.charAt(n - 1) == s2.charAt(m - 1)){
                ret.append(s1.charAt(n - 1));
                n--;
                m--;
            }else{
                if(f[n - 1][m] > f[n][m - 1]){
                    n--;
                }else{
                    m--;
                }
            }
        }
        return ret.reverse().toString();
    }
}

最长回文串(给字母,自己构造最长的回文串)

https://leetcode-cn.com/problems/longest-palindrome/

  • 题解:

在这里插入图片描述

class Solution {
    public int longestPalindrome(String s) {
        int[] letters = new int[128];
        char[] arr = s.toCharArray();
        for(char c : arr) letters[c]++;

        int res = 0;
        for(int i : letters) res += i - (i % 2);

        return res == arr.length ? res : res + 1;
    }
}

最长回文子串I(求长度)

  • 普通版
    public static boolean isHuiWen(String s) {
        if(s == null ||s.length() == 0) {
            return false;
        }
        int i = 0, j = s.length() - 1;
        while(i < j) {
            if(s.charAt(i) != s.charAt(j)) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }
    //最长回文长度(普通版)
    public static int func(String s) {
        // write code here
        int n = s.length();
        int ret = 0;
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j <= n; j++) {
                if(isHuiWen(s.substring(i, j))) {
                    if(ret < j - i) {
                        ret  = j - i;
                    }
                }
            }
        }
        return ret;
    }
    
  • dp版
 //最长回文长度(dp版)
import java.util.*;
public class Solution {
    public int getLongestPalindrome (String s) {
       //定义一个表示字符长度
        int len = s.length();
        //如果字符小于2,直接返回
        if(len < 2){
            return 1;
        }
        //定义一个表示回文字符数量的变量
        int maxlen = 1;
        //定义一个存储所有可能的结果,一个二维数组
        boolean[][] dp = new boolean[len][len];
        //单个字符本身就是回文串
        for(int i = 0; i < len; i++){
            dp[i][i] = true;
        }
        //递归遍历,二维数组的对角线上方的所有元素
        for(int j = 1; j < len; j++){
            for(int i = 0; i < len - 1 && i < j; i++){
                //如果两个字符相等,就说明不是回文串
                if(s.charAt(i) != s.charAt(j)){
                    dp[i][j] = false;
                }else{
                    //当是回文串时,字符个数小于等于3个,就是回文串
                    if(j - i < 3){
                        dp[i][j] =  true; 
                    }else{
                        //递归判断当边界两边的字符相等时,继续判断内层的字符是否相等
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                }
                //对比所有的回文串,取出长度最大的,回文串的起始位置
                if(dp[i][j] && j - i + 1 > maxlen){
                    maxlen = j - i + 1;
                   
                }
            }
        }
        //字符串的切割
        return maxlen;
    }
}
     

最长回文子串II(求字符串)

  • 普通版
	//最长回文的字符串
	  public static boolean isHuiWen(String s) {
        if(s == null ||s.length() == 0) {
            return false;
        }
        int i = 0, j = s.length() - 1;
        while(i < j) {
            if(s.charAt(i) != s.charAt(j)) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }
    
    public static String func2(String s) {
        // write code here
        int n = s.length();
        int max = 0, end = 0;
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j <= n; j++) {
                if(isHuiWen(s.substring(i, j))) {
                    if(max < j - i) {
                        max  = j - i;
                        end = j;
                    }
                }
            }
        }
        return s.substring(end - max, end);
    }
  • dp版
//dp版
class Solution {
    public String longestPalindrome(String s) {
        //定义一个表示字符长度
        int len = s.length();
        //如果字符小于2,直接返回
        if(len < 2){
            return s;
        }
        //定义一个表示回文字符数量的变量
        int maxlen = 1;
        //回文字串的开始索引
        int begin = 0;
        //定义一个存储所有可能的结果,一个二维数组
        boolean[][] dp = new boolean[len][len];
        //单个字符本身就是回文串
        for(int i = 0; i < len; i++){
            dp[i][i] = true;
        }
        //递归遍历,二维数组的对角线上方的所有元素
        for(int j = 1; j < len; j++){
            for(int i = 0; i < len - 1 && i < j; i++){
                //如果两个字符相等,就说明不是回文串
                if(s.charAt(i) != s.charAt(j)){
                    dp[i][j] = false;
                }else{
                    //当是回文串时,字符个数小于等于3个,就是回文串
                    if(j - i < 3){
                        dp[i][j] =  true; 
                    }else{
                        //递归判断当边界两边的字符相等时,继续判断内层的字符是否相等
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                }
                //对比所有的回文串,取出长度最大的,回文串的起始位置
                if(dp[i][j] && j - i + 1 > maxlen){
                    maxlen = j - i + 1;
                    begin = i;
                }
            }
        }
        //字符串的切割
        return s.substring(begin, begin + maxlen);
    }
}

最长回文序列

public static int func3(String s) {
        if(s == null || s.length() == 0) {
            return 0;
        }
        int n = s.length();
        int[][] f = new int[n + 1][n + 1];
        for(int i = 1; i <= n; i++) {
            for(int j =1; j <= n; j++) {
                if(s.charAt(i - 1) != s.charAt(n - j)) {
                    f[i][j] = Math.max(f[i - 1][j], f[i][j -1]);
                }else {
                    f[i][j] = Math.max(f[i - 1][j - 1] + 1, f[i][j]);
                }
            }
        }
        return f[n][n];
    }

最长括号子串

https://www.nowcoder.com/practice/45fd68024a4c4e97a8d6c45fc61dc6ad?tpId=117&&tqId=37745&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

import java.util.*;
public class Solution {
    public int longestValidParentheses (String s) {
        // write code here
        if (s == null || s.length() < 2) {
            return 0;
        }
        int[] f = new int[s.length()];
        if (s.charAt(0) == '(' && s.charAt(1) == ')') {
            f[1] = 2;
        }
        int ret = Math.max(f[1], 0);
        for (int i = 2; i < s.length(); i++) {
            if (s.charAt(i) == ')') {
                if (s.charAt(i - 1) == '(') {
                    f[i] = 2 + f[i - 2];
                } else {
                    int index = i - f[i - 1] - 1;
                    if (index >= 0 && s.charAt(index) == '(') {
                        f[i] = 2 + f[i - 1];
                        if (index - 1 >= 0) {
                            f[i] += f[index - 1];
                    }
                }
            }
        }
        ret = Math.max(ret, f[i]);
    }
    return ret;
    }
}

编辑距离

题目连接:https://leetcode-cn.com/problems/edit-distance/
核心思路:
在这里插入图片描述

class Solution {
    public int minDistance(String s1, String s2) {
        int n = s1.length();
        int m = s2.length();
        int[][] f = new int[n + 1][m + 1];
        for (int i = 0; i <= n; i++) f[i][0] = i;
        for (int j = 0; j <= m; j++) f[0][j] = j;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                f[i][j] = Math.min(f[i - 1][j] + 1, f[i][j - 1] + 1);
                if (s1.charAt(i - 1) == s2.charAt(j - 1)) f[i][j] = Math.min(f[i][j], f[i - 1][j - 1]);
                else f[i][j] = Math.min(f[i][j], f[i - 1][j - 1] + 1);
            } 
        }    
            return f[n][m];  
    }
}
    

变态跳台阶

问题链接:https://www.nowcoder.com/practice/22243d016f6b47f2a6928b4313c85387?tpId=13&tags=&title=&difficulty=0&judgeStatus=0&rp=1
核心思路:
在这里插入图片描述

public class Solution {
    public int jumpFloorII(int target) {
        if(target < 2) {
            return 1;
        }
        int[] arr = new int[target + 1];
        arr[1] = 1;
        for(int i = 2; i <= target; i++) {
            arr[i] = 2 * arr[i - 1];
        }
        return arr[target];
    }
}

矩阵覆盖

核心思路

递归实现

public class Solution {
    public int rectCover(int target) {
        if(target < 1) {
            return 0;
        }else if(target <= 2) {
            return target;
        }else {
            return rectCover(target - 1) + rectCover(target - 2);
        }
    }
}

迭代实现

public class Solution {
    public int rectCover(int target) {
        if(target < 1) {
            return 0;
        }else if(target <= 2) {
            return target;
        }
        int f1 = 1;
        int f2 = 2;
        int f3 = 0;
        for(int i = 3; i <= target; i++){
            //f3先更新
            f3 = f1 + f2;
            f1 = f2;
            f2 = f3;
            
            
        }
        return f3;
    }
}

动态规划实现

public class Solution {
    public int rectCover(int target) {
        if(target < 1) {
            return 0;
        }else if(target <= 2) {
            return target;
        }
        int[] arr = new int[target + 1];
        arr[0] = 1;
        arr[1] = 1;
//         int ret = 0;
        for(int i = 2; i <= target; i++) {
            arr[i] = arr[i - 1] + arr[i - 2];
        }
        return arr[target];
    }
}

买卖股票的最佳时机I

https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/submissions/

class Solution {
    public int maxProfit(int[] prices) {
        if(prices == null || prices.length == 0) {
            return 0;
        }
        int ret = 0, min = prices[0];
        for(int i = 1; i < prices.length; i++) {
            if(min > prices[i]) {
                min = prices[i];
            }
            ret = Math.max(ret, prices[i] - min);
        }
        return ret;
    }
}

买卖股票的最佳时机II

https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/

class Solution {
    public int maxProfit(int[] prices) {
        if(prices == null || prices.length == 0) {
            return 0;
        }
       int ret = 0;
       for(int i = 1; i < prices.length; i++) {
           if(prices[i] > prices[i - 1]) {
               ret += prices[i] - prices[i - 1];
           }
       }
       return ret;
    }
}

兑换零钱(一)

https://www.nowcoder.com/practice/3911a20b3f8743058214ceaa099eeb45?tpId=117&&tqId=37795&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

import java.util.*;
public class Solution {
    public int minMoney (int[] arr, int aim) {
        // write code here
        //dp[i] 换得金额i能用的最少硬币数
        int[] dp = new int[aim + 1];
        //后面要比较最小值 所以每个dp的初始值都是aim+1 , 考虑硬币额度全为1用aim枚能换aim额度 aim+1必然是越界值了
        Arrays.fill(dp, aim + 1);
        dp[0] = 0; //因为要给dp[1-1]做铺垫 所以dp[0]必须是0
        for (int i = 1; i < aim + 1; i++) {
            for (int j = 0; j < arr.length; j++) {
                //别越界 && 至少能换出来才换 && 能换的话 看看我用这枚硬币好 还是不用好 
                // && 如果能用硬币你不用的话(或者压根换不出来) 那代价可是MAX值 逼着你尽可能换
                if (i - arr[j] >= 0)  {
                    dp[i] = Math.min(dp[i], dp[i - arr[j]] + 1);
                }
            }
        }
        //要是流程走下来 dp值是非法值 说明换不出来
        return dp[aim]==aim+1?-1:dp[aim];
    }
}

打家劫舍I

https://leetcode-cn.com/problems/house-robber/

class Solution {
    public int rob(int[] nums) {
        if(nums == null || nums.length == 0) {
            return 0;
        }
        int n = nums.length;
        int[] f = new int[n + 1];
        f[0] = 0;
        f[1] = nums[0];
        for(int i = 2; i <= n; i++) {
            f[i] = Math.max(f[i - 1], f[i - 2] + nums[i - 1]);
        }
        return f[n];
    }
}

打家劫舍II

https://leetcode-cn.com/problems/house-robber-ii/

class Solution {
    public int rob(int[] nums) {
        if(nums == null || nums.length == 0) {
            return -1;
        }
        if(nums.length == 1){
            return nums[0];
        }
        int[] dp1 = new int[nums.length];
        int[] dp2 = new int[nums.length];
        dp1[0] = 0;//不抢第一个
        dp1[1] = nums[1];
        dp2[dp1.length - 1] = 0;//不抢最后一个
        dp2[dp1.length - 2] = nums[nums.length - 2];
        for(int i = 2; i < nums.length; i++){
            dp1[i] = Math.max(dp1[i - 2] + nums[i], dp1[i - 1]);
        }
        for(int i = dp2.length-3; i >= 0; i--){
            dp2[i] = Math.max(dp2[i + 2] + nums[i], dp2[i + 1]);
        }
        return Math.max(dp2[0], dp1[dp1.length - 1]);
    }
}

持续更新中。。。。。。。。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值