Leetcode之第297场周赛小记

小记

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

在这里插入图片描述

下面主要是对题目进行分析总结,也是为之后面试做准备。

题目一:2303. 计算应缴税款总额

在这里插入图片描述

思路: 这道题简单。按照题目给的信息求出当前区间的纳税值和税率,然后相乘求和,需要注意的是对数据类型的判断

解决代码:

class Solution {
    public  double calculateTax(int[][] brackets, int income) {
        double result = 0;
        if (income>=brackets[0][0]){
            result+=(brackets[0][1]/100.0)*brackets[0][0];
        }else {
            return income*(brackets[0][1]/100.0);
        }
        System.out.println(result);
        for (int i = 1; i < brackets.length; i++) {
            if (income>=brackets[i][0]){
                result+=(brackets[i][0]-brackets[i-1][0])*(brackets[i][1]/100.0);
            }else {
                result+=(income-brackets[i-1][0])*(brackets[i][1]/100.0);
                break;
            }
        }
        return result;
    }
}

题目二:2304. 网格中的最小路径代价

在这里插入图片描述

思路: 这道题目是一道典型的动态规划。解题步骤为:

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

d p [ i ] [ j ] dp[i][j] dp[i][j]大小同矩阵grid矩阵一样,其表示到达单元格 g r i d [ i ] [ j ] grid[i][j] grid[i][j]使用的最小代价。

2,确定递推公式。

首先,我们可以知道 g r i d [ i ] [ j ] grid[i][j] grid[i][j]可以由 g r i d [ i − 1 ] [ j ] grid[i-1][j] grid[i1][j]中任意一点到达,所消耗代价为: d p [ i − 1 ] [ j ] dp[i-1][j] dp[i1][j] g r i d [ i ] [ j ] grid[i][j] grid[i][j]以及路径和。这里需要注意路径的选取: m o v e C o s t [ 上 一 行 中 的 单 元 格 g r i d [ i − 1 ] [ j ] 的 值 ] [ 列 数 ] moveCost[上一行中的单元格grid[i-1][j]的值][列数] moveCost[grid[i1][j]][],即可推出 d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ k ] + g r i d [ i ] [ j ] + m o v e C o s t [ g r i d [ i − 1 ] [ k ] ] [ j ] ) dp[i][j]=min(dp[i-1][k]+grid[i][j]+ moveCost[grid[i-1][k]][j]) dp[i][j]=min(dp[i1][k]+grid[i][j]+moveCost[grid[i1][k]][j])。(k=gird矩阵的列数)

3,dp数组初始化

d p [ i ] [ j ] dp[i][j] dp[i][j]中,当i=0时, d p [ i ] [ j ] = g r i d [ i ] [ j ] dp[i][j]=grid[i][j] dp[i][j]=grid[i][j]

4,确定遍历顺序。

遍历顺序就是按照 g r i d [ i ] [ j ] grid[i][j] grid[i][j]的顺序进行遍历。

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

解决代码:

class Solution {
    public int minPathCost(int[][] grid, int[][] moveCost) {
        int m =grid.length;
        int n = grid[0].length;
        int[][] dp =new int[m][n];
        //初始化
        for (int i = 0; i <n ; i++) {
            dp[0][i] =grid[0][i];
        }
        //状态转移
        for (int i = 1; i <m ; i++) {
            Arrays.fill(dp[i],Integer.MAX_VALUE);
            for (int j = 0; j <n ; j++) {
                for (int k = 0; k <n ; k++) {
                    dp[i][j] = Math.min(dp[i][j],dp[i-1][k]+grid[i][j]+moveCost[grid[i-1][k]][j]);
                }
            }
        }
        //最终结果
        int res =Integer.MAX_VALUE;
        for (int i = 0; i <n ; i++) {
            res =Math.min(res,dp[m-1][i]);
        }
        return res;

    }
}

题目三: 2305. 公平分发饼干

在这里插入图片描述

思路: 本题为一道经典的回溯算法题目。

//回溯算法三部曲模板
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

1,参数:index(遍历饼干索引), kids(表示孩子的数组), cookies(表示饼干的数组)

2,终止条件:饼干索引>=cookies的数量;存放结果:获取单个孩子在分发过程中能够获得饼干的最大总数。

3,遍历孩子的数组,分发饼干。

解决代码:

//参考:https://leetcode.cn/problems/fair-distribution-of-cookies/solution/by-shou-hu-zhe-t-i3ww/
class Solution {
    int ans = Integer.MAX_VALUE;
	public int distributeCookies(int[] cookies, int k) {
		int[] sum = new int[k];//sum[i]表示分完糖果后第i位小朋友的糖果数量
		dfs(0, sum, cookies);
		return ans;
	}
	/**
	 * @param index 现在分发第index贷糖果
	 * @param sum sum[i]表示分完糖果后第i位小朋友的糖果数量
	 * @param cookies 糖果数组
	 */
	private void dfs(int index, int[] sum, int[] cookies) {
		if (index >= cookies.length) {
			int max = sum[0];
			for (int i = 1; i < sum.length; i++) {
				max = Math.max(sum[i], max);//寻找现在分完糖果后获得最多糖果的小朋友的糖果数量
			}
			ans = Math.min(max, ans);
			return;
		}
		for (int i = 0; i < sum.length; i++) {
			sum[i] = sum[i] + cookies[index];
			dfs(index + 1, sum, cookies);//继续分发第index+1贷糖果
			sum[i] = sum[i] - cookies[index];// 回溯
		}
	}
}

题目四:2306. 公司命名

在这里插入图片描述

思路: 参考:ctysss

注意: t [ i ] [ j ] t[i][j] t[i][j]表示对于首字母为i的字符串,将i替换成j,使得这个字符串不在ideas中的个数。

1,首先将ideas中的公司名加入到set中,一是为了去重,二是为了之后判断首字母转化后,新公司名是否在ideas中。

2,遍历ideas中每一公司名:

  • 对公司名idea的首字母分别与26个字母进行交换,得到新的公司名,并判断新公司名是否在ideas中。
  • 如果新公司名不在,则 t [ i ( 原 公 司 名 的 首 字 母 ) ] [ j ( 交 换 的 首 字 母 ) ] + + t[i(原公司名的首字母)][j(交换的首字母)]++ t[i()][j()]++,所以如果idea中有该首字母开头的公司的话,那么有效的公司名ret=ret+该首字母开头的公司数,即为ret=ret+ t [ j ] [ i ] t[j][i] t[j][i]

3,如果我们能够通过字符串a,b得到一个合法的结果 a + " " + b a+" "+b a+""+b,那么 b + " " + a b+" "+a b+""+a也一定是一个合法的结果,所以最后结果ret*2。

解决代码:

class Solution {
    public long distinctNames(String[] ideas) {
        int len = ideas.length;
        Set<String> set = new HashSet<>();
        for(String s : ideas){
            set.add(s);
        }
        
        int[][] t = new int[26][26];
        long ret = 0;
        for(String s : ideas){
            int i = s.charAt(0) - 'a';
            for(int j = 0 ; j < 26 ; j++){
                String ns = (char)('a'+j)+(s.length() > 1 ? s.substring(1) : "");
                if(!set.contains(ns)){
                    t[i][j]++;
                    ret += t[j][i];
                }
            }
        }
        return ret*2;
    }
}

总结:以上就是LeetCode第297场周赛题目,感觉自己对回溯算法以及动态规划的题目还是不够熟练,可以判断出用什么方法,但是解题思路不够明确,需要多家练习。还是要继续努力,努力保二争三(四)。

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王小二_Leon

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

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

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

打赏作者

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

抵扣说明:

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

余额充值