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
使用 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
)
使用 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
)
思路:自底向上去计算
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);
}
}
思路:和上面类似
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();
}
}
思路:关键在于想到边长为 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;
}
}
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);
}
}
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];
}
}
问题的关键在于:当两端的元素不相等时,如何转化,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];
}
}
思路:要么都删除,要么删除一个去和前面 比,需要先初始化各个数组的 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];
}
}
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();
}
}