leetcode每周.周赛第283场周赛 安贤量化 ~ 模拟 + 数学计算 是真的罚麻了

本文介绍了在LeetCode第283场周赛中的两道题目:Excel范围单元格的模拟计算和数组追加整数的数学优化解法。第一题涉及Excel区域表示法,第二题挑战了动态添加最小和整数序列的技巧。

📖本篇内容:leetcode每周.周赛第283场周赛 安贤量化 ~ 模拟 + 数学计算

📑 文章专栏:leetcode周赛打卡《周周打卡》

📆 最近更新:2022年2月 27日 leetcode每周.周赛第282场周赛 葡萄城专场 ~简单模拟 + 哈希表的应用 + 排序二分缩小范围求最值

🙊个人简介:一只二本院校在读的大三程序猿,本着注重基础,打卡算法,分享技术作为个人的经验总结性的博文博主,虽然可能有时会犯懒,但是还是会坚持下去的,如果你很喜欢博文的话,建议看下面一行~(疯狂暗示QwQ)

🌇 点赞 👍 收藏 ⭐留言 📝 一键三连 关爱程序猿,从你我做起

🙊写在前面

🙊小付来喽,今天接着有更新周赛栏目了哦,今天的小付是在学校打的第一把周赛,属实状态也不好,自身也太菜。

📆第283场周赛——2022-03-06

📝T1.6016. Excel 表中某个范围内的单元格

题目

Excel 表中的一个单元格 (r, c) 会以字符串 “” 的形式进行表示,其中:

即单元格的列号 c 。用英文字母表中的 字母 标识。 例如,第 1 列用 'A' 表示,第 2 列用 'B' 表示,第 3 列用 'C' 表示,以此类推。 即单元格的行号 r 。第 r 行就用 整数 r 标识。 给你一个格式为 ":" 的字符串 s ,其中 表示 c1 列, 表示 r1 行, 表示 c2 列, 表示 r2 行,并满足 r1 <= r2 且 c1 <= c2 。

找出所有满足 r1 <= x <= r2 且 c1 <= y <= c2 的单元格,并以列表形式返回。单元格应该按前面描述的格式用 字符串 表示,并以 非递减 顺序排列(先按列排,再按行排)。

示例

在这里插入图片描述

示例1:

输入:s = "K1:L2"
输出:["K1","K2","L1","L2"]
解释:
上图显示了列表中应该出现的单元格。
红色箭头指示单元格的出现顺序。

在这里插入图片描述

示例2:

输入:s = "A1:F1"
输出:["A1","B1","C1","D1","E1","F1"]
解释:
上图显示了列表中应该出现的单元格。 
红色箭头指示单元格的出现顺序。

⭐思路 ⭐

本题思路以及考察点:

  • 小付认为今天的第一道题比往常的第一道题要稍微复杂了一丢丢,但是还是简单的模拟题,思路主要在于我们需要对给出的字符串进行拆分,获取起始的Excel表格位置,以及截至的Excel表格位置然后模拟每行每列对应的范围列的Excel表格就好了

代码实现

class Solution {
     public List<String> cellsInRange(String s) {
        List<String> res = new ArrayList<>();
        // 字符串拆分 分别进行获取起始表格位置 以及 截至表格位置 用来获取范围
        String[] params = s.split(":");
        // 获取对应起始列的字符
        char col1 = params[0].charAt(0);
        // 获取对应起始行的行数
        int row1 = Integer.parseInt(params[0].substring(1));
        // 获取对应截至列的字符
        char col2 = params[1].charAt(0);
        // 获取对应截至行的行数
        int row2 = Integer.parseInt(params[1].substring(1));
        // 模拟
        for (char c = col1 ;c <= col2;c++){
        	// 值得注意的是我们每次到达下一列时其对应的行又需要重新设置为起始行
            int j = row1;
            for (int i = j ; i<= row2;i++){
            	// 将结果添加到列表中
                StringBuilder tmp = new StringBuilder();
                tmp.append(c).append(j++);
                res.add(tmp.toString());
            }
        }
        return res;
    }
}

执行结果

在这里插入图片描述

📝T2.6017. 向数组中追加 K 个整数

题目

给你一个整数数组 nums 和一个整数 k 。请你向 nums 中追加 k 个 未 出现在 nums 中的、互不相同 的 正 整数,并使结果数组的元素和 最小 。

返回追加到 nums 中的 k 个整数之和。

示例

示例1:

输入:nums = [1,4,25,10,25], k = 2
输出:5
解释:在该解法中,向数组中追加的两个互不相同且未出现的正整数是 2 和 3 。
nums 最终元素和为 1 + 4 + 25 + 10 + 25 + 2 + 3 = 70 ,这是所有情况中的最小值。
所以追加到数组中的两个整数之和是 2 + 3 = 5 ,所以返回 5 。

示例2:

输入:nums = [5,6], k = 6
输出:25
解释:在该解法中,向数组中追加的两个互不相同且未出现的正整数是 1 、2 、3 、4 、7 和 8 。
nums 最终元素和为 5 + 6 + 1 + 2 + 3 + 4 + 7 + 8 = 36 ,这是所有情况中的最小值。
所以追加到数组中的两个整数之和是 1 + 2 + 3 + 4 + 7 + 8 = 25 ,所以返回 25 。

提示

1 <= nums.length <= 105
1 <= nums[i], k <= 109

⭐思路 ⭐

本题思路以及考察点:

  • 这道题放在这个位置着实有点难为小付了,这道题给我破防了,一开始小付想的是通过哈希来解决,但是超内存了,然后小付又做出了改进,然后超时了,最后就又改进了,但是示例还是过不去,罚了七八次左右,心态裂了,直接今天就弃赛了。
  • 但是我吃午饭的时候在思考这道题,发现这是一道数学题。
  • 下面是参考了群里某位大佬的做法思路:
    1.我们首先需要对数组进行排序,这样有利于我们使得加上的非重复数值从小到大依次递增,这样才可以使得追加到数组中的整数之和最小
    2.做好排序之后, 我们就要来分类进行考虑了,如果排序数组中的第一个值都要大于k,那么我们很容易就知道,数组可以追加从1开始追加到k的k个数,这样一来追加的值就是1+2+3+...+k这不就是等差数列前n项和么公差为1的1-n的等差数列,那么其前n项和就是n*(n+1)/2
    3.那这种情况讨论完之后,我们就是模拟了,这个模拟需要在草稿纸上写一下,举个示例,就容易理解多了,我们需要设置一个当前需要可以进行加上的最小非重复数组中的一个数值我们设置这个初始值为k。如果当前我们遍历的这个数值要比需要加上的数值要小或者相等,这里就很好理解,因为不能出现与数组中相同的元素与之前加过的元素进行追加,所以需要使得当前需要进行追加的数字进行自增然后追加入其中,但是这里追加的数值不一定就是数组中不存在的我们需要遍历到不存在的那个数值他才是真正意义上的追加完毕,这里是贪心的思路

这里小付可能表达的不是很清楚,毕竟贪心思路不好讲出来,需要自己草稿纸上算一下就好了

代码实现

class Solution {
    public long minimalKSum(int[] nums, int k) {
		Arrays.sort(nums);
		// 计算前n项和
		long sum = (1L + k) * k / 2;
		// 记录当前需要追加的初始值大小
		long curAddNum = k;
		// 如果需要追加的数比第一个数还要小的话 就直接返回就好了 因为可以追加1-k数之和即可
		if (nums[0] > k)return sum; 
		// 模拟
		for (int i = 0 ; i< nums.length;i++){
			if (i > 0 && nums[i-1] == nums[i])continue;
			if (nums[i] <= curAddNum){
				curAddNum++;
				// 贪心 贪的是如果当前需要追加的值存在数组之中或者已经追加过的 就往后移
				sum = sum -  nums[i] + curAddNum; 
			}
		}
		return sum;
    }
}

执行结果

在这里插入图片描述

🙊写在最后

小付打卡的第8场单周赛 2022-03-06

尽可能把会做的题 都做好 就可以了

本次周赛 对了一道题

T2超内存 超时 该错的都罚了一遍 改了十次心态崩了 直接弃赛了

所以还是很不错的周赛体验

最后

每天进步点 每天收获点

愿诸君 事业有成 学有所获

如果觉得不错 别忘啦一键三连哦~

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Alascanfu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值