Leetcode之第298场周赛小记

小记

本篇博客记录小黑第七次参加leetcode周赛(298场次)的情况,以及对题目的总结,以便鞭策自己不断前进 。

题目一:5242. 兼具大小写的最好英文字母

在这里插入图片描述

思路: 这道题为简单题。

1,遍历字符s,将出现的字母大小写存放在set集合中。(去除重复字母)

2,因为最好的英文字母在字母表中更后面出现,因此我们从后往前遍历字母表,如果该字母大小写都在set集合中,则返回该结果。

解决代码: 空间复杂度O(n)

public class que1 {
    public static void main(String[] args) {
        String s = "arRAzFif";
        String s1 = greatestLetter(s);
        System.out.println(s1);

    }
    public static String greatestLetter(String s) {
        int n = s.length();
        Set<Character>  set = new HashSet<>();
        for (int i = 0; i <n ; i++) {
            set.add(s.charAt(i));
        }
        for (int i = 25; i >=0 ; i--) {
            if (set.contains((char)('A'+i)) &&set.contains((char)('a'+i))){
                return String.valueOf((char)('A'+i));
            }
        }
        return "";
    }
}

题目二:5218. 个位数字为 K 的整数之和

在这里插入图片描述

思路: 这道题目可以利用数学运算来解决:

1,多重集中每个元素的个位都为k,则可以表示为10*x+k。

2,当num可以由n个元素求和得到,那么可以知道 n u m − n k num-nk numnk必是10的倍数。

推导:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Q5Ej7cp-1655649491004)(F:\博客\leetcode\PIC\278-2.jpg)]

3,从小到大枚举n,找到第一个满足2中条件的n。减枝:因为当n=1和n=11时,其结果是一样的,因此,n<=10。

4,执行过程中,可以发现num=0的情况需要单独讨论。

解决代码:

class Solution {
    public int minimumNumbers(int num, int k) {
        if(num==0) return 0;
        for(int i =1,j=num-k;i<=10 &&j>=0;i++,j-=k){
            if(j%10==0){
                return i ;
            }
        }
        return -1;

    }
}

题目三: 6099. 小于等于 K 的最长二进制子序列

在这里插入图片描述

思路: 本题考查贪心算法。

关注点: 首先我们需要确定一个小于等于k的最长子串。第二,这个字串的位置要尽量靠后,这样前面就可以加更多的0。

步骤:从后往前遍历二进制字符串,是0则添加到字串;是1则判断当前子串加上1是否满足小于等于k。当遇到1且判断大于等于k时,后续遍历则只添加0。

解决代码:

class Solution {
    public int longestSubsequence(String s, int k) {
        boolean f = false;
        int ans = 0;
        long sum = 0L;
        char[] arr =  s.toCharArray();
        for(int i = arr.length-1; i>=0 ; i--){
            if(arr[i] == '0')ans++;
            if(!f&&arr[i]=='1'){
                sum += (int)Math.pow(2,arr.length-1-i);
                ans++;
                if(sum>k){
                    ans--;
                    f = true;
                }
            }
        }
        return ans;
    }
}

题目四:5254. 卖木头块

在这里插入图片描述

思路: 本题利用动态规划的思路进行解题。

动态规划五部曲:

1,确定dp数组(dp table)以及下标的含义。

d p [ i ] [ j ] dp[i][j] dp[i][j]大小为(m+1)*(n+1),其表示切割高为i宽为j的木块,能得到的最多钱数。

2,确定递推公式。

当我们可以拿到一块高为i宽为j的木块时,处理有三种方式:

  • 直接卖掉,得到钱为 d p [ i ] [ j ] = p r i c e s [ i ] [ j ] dp[i][j]=prices[i][j] dp[i][j]=prices[i][j]
  • 垂直切,则 d p [ i ] [ j ] = m a x ( d p [ i ] [ k ] + d p [ i ] [ n − k ] ) dp[i][j] = max(dp[i][k]+dp[i][n-k]) dp[i][j]=max(dp[i][k]+dp[i][nk]),其中k=[1,n);当k=0或n时,就相当于直接卖掉。
  • 水平切,则 d p [ i ] [ j ] = m a x ( d p [ m − k ] [ j ] + d p [ k ] [ j ] ) dp[i][j] = max(dp[m-k][j]+dp[k][j]) dp[i][j]=max(dp[mk][j]+dp[k][j]),其中k=[1,m)。

3,dp数组初始化

本题可以将 d p [ i ] [ j ] dp[i][j] dp[i][j]直接卖得到的钱作为初始值。

需注意的是,本题价格表存放在二维数组中但是不好获取到价格。初始化时可以将其映射在n行2列(行列代表木块的宽高,值代表价格)的二维数组中,方便后续进行运算。

4,确定遍历顺序。

遍历顺序就是按照切割木板的顺序进行遍历。

5,举例推导。(见代码)

解决代码:

class Solution {

	public long sellingWood(int m, int n, int[][] prices) {
		long[][] map = new long[m + 1][n + 1], dp = new long[m + 1][n + 1];
		for (int[] price : prices) {
			map[price[0]][price[1]] = price[2];
		}
		for (int i = 1; i <= m; i++) {
			for (int j = 1; j <= n; j++) {
				dp[i][j] = map[i][j];
				for (int k = 1; k < i; k++) {
					dp[i][j] = Math.max(dp[i][j], dp[k][j] + dp[i - k][j]);
				}
				for (int k = 1; k < j; k++) {
					dp[i][j] = Math.max(dp[i][j], dp[i][k] + dp[i][j - k]);
				}
			}
		}
		return dp[m][n];
	}
}

总结:以上就是LeetCode第298场周赛题目,这次只做出了一道题;第二题我按照回溯的思路解决,但是花了很多时间没有ac,看到第三题有点思路但是没时间解答了。这次发挥非常不好。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王小二_Leon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值