LeetCode-0728

SQL 基础 50

1193

dateFormat、和 count(IF()) ,需要注意的是,count IF 中判断条件失败需要设置为 null,sum(IF)条件失败是 0

select DATE_FORMAT(trans_date, '%Y-%m') as month,country,count(*) as trans_count,
count(IF(state="approved",1,null)) as approved_count,sum(amount) trans_total_amount,
sum(IF(state="approved",amount,0)) as approved_total_amount
from Transactions
group by DATE_FORMAT(trans_date, '%Y-%m'),country

1174

使用 where in子句,过滤第一层条件

select Round(count(IF(order_date=customer_pref_delivery_date,1,null))*100/count(*),2) immediate_percentage
from Delivery
where (customer_id,order_date)in (
    select customer_id,min(order_date)
    from Delivery
    group by customer_id
)

550

使用 where in子句,筛选出满足条件的,然后在进行统计计算

select round(count(distinct player_id)/
    (select count(distinct player_id) from Activity),2) fraction
from Activity
where (player_id,addDate(event_date,-1)) in(
    select player_id,min(event_date)
    from Activity
    group by player_id
)

动归基础 50

120.三角形最小路径和

思路:自底向上去计算

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {

        for(int i=triangle.size()-2;i>=0;i--){
            List<Integer> cur = triangle.get(i);
            List<Integer> down = triangle.get(i+1);
            for(int j = 0;j<cur.size();j++){
                cur.set(j,cur.get(j)+Math.min(down.get(j),down.get(j+1)));
            }
        }

        return triangle.get(0).get(0);
    }
}

931.下降路径最小和

思路:和上面类似

class Solution {
    public int minFallingPathSum(int[][] matrix) {

        int nan = 100001;
        int n = matrix.length;
        int m = matrix[0].length;

        for(int i=1;i<n;i++){
            for(int j=0;j<m;j++){
                matrix[i][j] += Math.min(matrix[i-1][j],Math.min(j-1<0?nan:matrix[i-1][j-1],j+1>=m?nan:matrix[i-1][j+1]));
            }
        }
        return Arrays.stream(matrix[n-1]).min().getAsInt();
    }
}

221 最大正方形

思路:关键在于想到边长为 1 的正方形如何推出边长为 2 的正方形,以当前点为正方形的右下角点进行推导,每次都是判断左上三个点。

class Solution {
    public int maximalSquare(char[][] matrix) {

        int n = matrix.length;
        int m = matrix[0].length;
        int max = 0;

        int dp[][] = new int[n][m];
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                dp[i][j] = matrix[i][j]-'0';
                max = Math.max(max,dp[i][j]);
            }
        }

        for(int i=1;i<n;i++){
            for(int j=1;j<m;j++){
                if(matrix[i][j]=='1'){
                    dp[i][j] = Math.min(dp[i-1][j-1],Math.min(dp[i-1][j],dp[i][j-1]))+1;
                }
                max = Math.max(max,dp[i][j]);
            }
        }

        return max*max;
    }
}

5.回文串

class Solution {
    public String longestPalindrome(String s) {

        int n = s.length();
        boolean dp[][] = new boolean[n][n];
        for(int i=0;i<n;i++)dp[i][i] = true;
        int max = 1;
        int start = 0;

        for(int l = 2;l<=n;l++){
            for(int i=0;i+l-1<n;i++){
                int j = i+l-1;
                if(l==2){
                    dp[i][j] = s.charAt(i)==s.charAt(j);
                }else{
                    dp[i][j] = (s.charAt(i)==s.charAt(j))&&dp[i+1][j-1];
                }
                if(dp[i][j]&&l>max){
                    max = l;
                    start = i;
                }
            }
        }
        return s.substring(start,start+max);
    }
}

139 单词拆分

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        
        int n = s.length();
        boolean dp[] = new boolean[n+1];
        dp[0] = true;

        for(int i=1;i<=n;i++){
            for(String word:wordDict){
                int l = word.length();
                if(i<l)continue;
                if(s.substring(i-l,i).equals(word))dp[i]=dp[i] || dp[i-l];
            }
        }
        return dp[n];
    }
}

516 回文子串

问题的关键在于:当两端的元素不相等时,如何转化,s[i] != s[j]时,dp[i][j] = max(dp[i+1][j],dp[i][j-1])

当整体不为回文时,转而去判断前后缀是否可以为回文传,获取其最长的

class Solution {
    public int longestPalindromeSubseq(String s) {

        int n = s.length();
        int dp[][] = new int[n][n];

        for(int i=0;i<n;i++)dp[i][i] = 1;

        for(int l=2;l<=n;l++){
            for(int i=0;i+l-1<n;i++){
                int j = i+l-1;
                if(s.charAt(i)==s.charAt(j)){
                    if(l==2)dp[i][j] = 2;
                    else dp[i][j] = dp[i+1][j-1]+2;
                }else{
                    dp[i][j] = Math.max(dp[i][j-1],dp[i+1][j]);
                }
            }
        }
        return dp[0][n-1];
    }
}

712.两个字符串的最小 ASCII 删除和

思路:要么都删除,要么删除一个去和前面 比,需要先初始化各个数组的 0 状态。

class Solution {
    public int minimumDeleteSum(String s1, String s2) {
        int n = s1.length();
        int m = s2.length();

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

        for(int i=1;i<=n;i++)dp[i][0] = dp[i-1][0] + (int)s1.charAt(i-1);
        for(int j=1;j<=m;j++)dp[0][j] = dp[0][j-1] + (int)s2.charAt(j-1);
        
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                int c1 = (int)s1.charAt(i-1);
                int c2 = (int)s2.charAt(j-1);
                if(c1==c2){
                    dp[i][j] = dp[i-1][j-1];
                }else{
                    dp[i][j] = Math.min(dp[i-1][j-1]+c1+c2,Math.min(dp[i-1][j]+c1,dp[i][j-1]+c2));
                }
            }
        }
        return dp[n][m];
    }
}

256.粉刷房子

class Solution {
    public int minCost(int[][] costs) {

        int n = costs.length;

        int dp[][] = new int[n][3];
        dp[0][0] = costs[0][0];
        dp[0][1] = costs[0][1];
        dp[0][2] = costs[0][2];

        for(int i=1;i<n;i++){
            dp[i][0] = Math.min(dp[i-1][1],dp[i-1][2])+costs[i][0];
            dp[i][1] = Math.min(dp[i-1][0],dp[i-1][2])+costs[i][1];
            dp[i][2] = Math.min(dp[i-1][0],dp[i-1][1])+costs[i][2];
        }

        return Arrays.stream(dp[n-1]).min().getAsInt();
    }
}

你可能感兴趣的:(LeetCode,leetcode,算法)