0
点赞
收藏
分享

微信扫一扫

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

zibianqu 2022-03-11 阅读 43

📖本文目录

🙊写在前面

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

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

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

题目

示例

在这里插入图片描述

示例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 个整数

题目

示例

示例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超内存 超时 该错的都罚了一遍 改了十次心态崩了 直接弃赛了

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

最后

每天进步点 每天收获点

愿诸君 事业有成 学有所获

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

举报

相关推荐

0 条评论