2024.1.30力扣每日一题——使循环数组所有元素相等的最少秒数
2024.1.30
- 题目来源
- 我的题解
- 方法一 暴力+模拟(无法通过)
- 方法二 哈希表+数学
题目来源
力扣每日一题;题序:2808
我的题解
方法一 暴力+模拟(无法通过)
直接暴力枚举。记录每一个元素所在的位置,然后模拟光源扩散,每次扩散左右各一个索引。
时间复杂度:O(nmlogn)。其中n表示nums的大小,m表示nums中不同元素的个数
空间复杂度:O(n)。哈希表所需要的空间
public int minimumSeconds(List<Integer> nums) {
int n=nums.size();
Map<Integer,List<Integer>> map=new HashMap<>();
for(int i=0;i<n;i++){
int num=nums.get(i);
List<Integer> t=map.getOrDefault(num,new ArrayList<>());
t.add(i);
map.put(num,t);
}
int res=Integer.MAX_VALUE;
for(int key:map.keySet()){
res=Math.min(res,getTime(map.get(key),n));
}
return res;
}
public int getTime(List<Integer> list,int n){
int res=0;
int max_size=list.size();
Set<Integer> cand=new HashSet<>(list);
while(max_size!=n){
List<Integer> t=new ArrayList<>(cand);
for(int i:t){
int pre=((i-1)+n)%n;
int next=(i+1)%n;
if(!cand.contains(pre))
cand.add(pre);
if(!cand.contains(next))
cand.add(next);
}
res++;
max_size=cand.size();
}
return res;
}
方法二 哈希表+数学
参考:官方题解
对于getTime函数中为什么这么做,没怎么看懂。以下是评论区的大佬的解答:
可以理解成仅能双向发散的光源,在有限空间中完成扩散需要的时间(速度为每秒一个索引),对于多个光源(相同数),扩散完成的时间取决于相隔最远(水桶效应)的两个光源双向奔赴的时间(最大距离除以二)。用索引相减计算出的距离实际上比相隔元素数多一,所以最终花费时间还要向下取整,如果用相隔元素数量表示距离,那时间就是向上取整。
时间复杂度:O( n 2 n^2 n2)
空间复杂度:O(n)
public int minimumSeconds(List<Integer> nums) {
int n=nums.size();
Map<Integer,List<Integer>> map=new HashMap<>();
for(int i=0;i<n;i++){
int num=nums.get(i);
List<Integer> t=map.getOrDefault(num,new ArrayList<>());
t.add(i);
map.put(num,t);
}
int res=Integer.MAX_VALUE;
for(int key:map.keySet()){
res=Math.min(res,getTime(map.get(key),n));
}
return res;
}
public int getTime(List<Integer> list,int n){
int res=n;
int mx = list.get(0) + n - list.get(list.size() - 1);
for (int i = 1; i < list.size(); ++i) {
mx = Math.max(mx, list.get(i) - list.get(i - 1));
}
res = Math.min(res, mx / 2);
return res;
}
有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~