本文主要是介绍新手勇闯leetcode 390周赛,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
3090. 每个字符最多出现两次的最长子字符串
难度:885
给你一个字符串
s
,请找出满足每个字符最多出现两次的最长子字符串,并返回该子字符串
的 最大 长度。示例 1:
输入: s = "bcbbbcba"
输出: 4
解释:
以下子字符串长度为 4,并且每个字符最多出现两次:
"bcbbbcba"
。示例 2:
输入: s = "aaaa"
输出: 2
解释:
以下子字符串长度为 2,并且每个字符最多出现两次:
"aaaa"
。提示:
2 <= s.length <= 100
s
仅由小写英文字母组成。
状态:完成
思路:滑动窗口解决问题。用一个数组arr记录窗口中的数字,看看哪个数字出现了多过两次,如果这个数字多过两次则重新开始并记录是否该窗口长度大过最大的长度,字符串的指针移动到上一个开始的地方+1继续遍历。
class Solution {public int maximumLengthSubstring(String s) {int[] arr=new int[26];int sum=0;int max=0;int index=0;for(int i=0;i<s.length();i++){char temp=s.charAt(i);System.out.println(temp);if(sum==0) index=i;if(arr[temp-'a']>=2){max=sum>max?sum:max;i=index;arr=new int[26];sum=0;}else{arr[temp-'a']++;sum++;}}return sum>max?sum:max;}
}
3091. 执行操作使数据元素之和大于等于 K
难度:1413
给你一个正整数
k
。最初,你有一个数组nums = [1]
。你可以对数组执行以下 任意 操作 任意 次数(可能为零):
- 选择数组中的任何一个元素,然后将它的值 增加
1
。- 复制数组中的任何一个元素,然后将它附加到数组的末尾。
返回使得最终数组元素之 和 大于或等于
k
所需的 最少 操作次数。示例 1:
输入:k = 11
输出:5
解释:
可以对数组
nums = [1]
执行以下操作:
- 将元素的值增加
1
三次。结果数组为nums = [4]
。- 复制元素两次。结果数组为
nums = [4,4,4]
。最终数组的和为
4 + 4 + 4 = 12
,大于等于k = 11
。
执行的总操作次数为3 + 2 = 5
。示例 2:
输入:k = 1
输出:0
解释:
原始数组的和已经大于等于
1
,因此不需要执行操作。提示:
1 <= k <= 105
状态:完成
思路:这一题我通过找规律得到一个规律移动一次最大值增加的值(1,2,2,3,3,4,4......)这样子的规律增加下去的,所以可以得出下面的算法。
class Solution {public int minOperations(int k) {if(k==1) return 0;if(k==2) return 1;int nums=2;int max=2;int temp=0;int cishu=2;while(k>max){if(temp/2==0){temp++;max+=nums;}else{temp=1;nums++;max+=nums;}cishu++;System.out.println(max+" "+nums);}return cishu-1;}
}
3092. 最高频率的 ID
难度:1767
你需要在一个集合里动态记录 ID 的出现频率。给你两个长度都为
n
的整数数组nums
和freq
,nums
中每一个元素表示一个 ID ,对应的freq
中的元素表示这个 ID 在集合中此次操作后需要增加或者减少的数目。
- 增加 ID 的数目:如果
freq[i]
是正数,那么freq[i]
个 ID 为nums[i]
的元素在第i
步操作后会添加到集合中。- 减少 ID 的数目:如果
freq[i]
是负数,那么-freq[i]
个 ID 为nums[i]
的元素在第i
步操作后会从集合中删除。请你返回一个长度为
n
的数组ans
,其中ans[i]
表示第i
步操作后出现频率最高的 ID 数目 ,如果在某次操作后集合为空,那么ans[i]
为 0 。示例 1:
输入:nums = [2,3,2,1], freq = [3,2,-3,1]
输出:[3,3,2,2]
解释:
第 0 步操作后,有 3 个 ID 为 2 的元素,所以
ans[0] = 3
。
第 1 步操作后,有 3 个 ID 为 2 的元素和 2 个 ID 为 3 的元素,所以ans[1] = 3
。
第 2 步操作后,有 2 个 ID 为 3 的元素,所以ans[2] = 2
。
第 3 步操作后,有 2 个 ID 为 3 的元素和 1 个 ID 为 1 的元素,所以ans[3] = 2
。示例 2:
输入:nums = [5,5,3], freq = [2,-2,1]
输出:[2,0,1]
解释:
第 0 步操作后,有 2 个 ID 为 5 的元素,所以
ans[0] = 2
。
第 1 步操作后,集合中没有任何元素,所以ans[1] = 0
。
第 2 步操作后,有 1 个 ID 为 3 的元素,所以ans[2] = 1
。
状态:超时了,我一开始的做法是大顶堆(优先队列实现)+哈希表超时了
思路:用一个哈希表去存储每个数字的出现次数,用优先队列去实现得到出现次数最多的数字,再使用懒删除,就是只有堆顶的元素的值发生改变的时候才去弹栈的操作,减少了时间复杂度,我一开始实现的还要去查找每一次改变的字母再去删除,于是超时了。
超时做法 大顶堆(优先队列实现)+哈希表:
class Solution {public long[] mostFrequentIDs(int[] nums, int[] freq) {int n = nums.length; long[] ans = new long[n]; Map<Integer, Integer> idFrequency = new HashMap<>(); PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> {return idFrequency.get(b)-idFrequency.get(a);}); for (int i = 0; i < n; i++) { int num = nums[i]; int change = freq[i]; if(change==0) continue;idFrequency.put(num, idFrequency.getOrDefault(num, 0) + change);maxHeap.remove(num);maxHeap.add(num);if (!maxHeap.isEmpty()) { ans[i] = idFrequency.get(maxHeap.peek()); } else { ans[i] = 0; } } return ans; }
}
上面代码加上个懒删除就不超时了。
class Solution {public long[] mostFrequentIDs(int[] nums, int[] freq) {Map<Integer,Long> map=new HashMap<>();PriorityQueue<Pair<Long,Integer>> queue=new PriorityQueue<>((i,j)->Long.compare(j.getKey(),i.getKey()));int n=nums.length;long[] result=new long[n];for(int i=0;i<n;i++){int num=nums[i];long change=freq[i]+map.getOrDefault(num,0L);map.merge(num,change,(a,b)-> b); queue.add(new Pair(change,num));System.out.println(map.get(queue.peek().getValue())+" "+queue.peek().getKey());while((!queue.isEmpty())&&Long.compare(map.get(queue.peek().getValue()),queue.peek().getKey())!=0){System.out.println("1");queue.poll();}result[i]=queue.isEmpty()?0:queue.peek().getKey();}return result;}
}
这篇关于新手勇闯leetcode 390周赛的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!