第 193 场力扣周赛题解

5436. 一维数组的动态和

思路:就是求一波前缀和。

class Solution {
    public int[] runningSum(int[] nums) {
    	
    	for(int i=1;i<nums.length;i++)
    		nums[i]+=nums[i-1];
    	
    	return nums;
    }
}

5437. 不同整数的最少数目

思路:简单贪心,我们每次去掉的数一定要是出现频率最小的,这样才能保证最后剩下的同样的数尽可能多。

class Solution {
    public int findLeastNumOfUniqueInts(int[] arr, int k) {
    	
    	Arrays.parallelSort(arr);
    	
    	List<Integer> list=new ArrayList<>();
    	
    	int num=1;
    	for(int i=1;i<arr.length;i++) {
    		if(arr[i]!=arr[i-1]) {
    			list.add(num);
    			num=1;
    		}
    		else
    			num++;
    	}
    	
    	list.add(num);
    	
    	int ans=list.size();
    	Collections.sort(list);
    	
    	for(int i=0;i<list.size() && k>0;i++) {
    		k-=list.get(i);
    		ans--;
    	}
    	
    	if(k<0) ans++;
    	
    	//System.out.println(k);
    	
    	return ans;
    }
}

5438. 制作 m 束花所需的最少天数

思路:二分答案,我们直接二分所需要的天数,根据当前天数能够知道哪些花是开放的,之后按照相邻的k个花为一个花束判断是否满足即可。

class Solution {
    public int minDays(int[] bloomDay, int m, int k) {

    	int n=bloomDay.length;
    	int ans=Integer.MAX_VALUE;
    	
    	int l=1,r=1000000000;
    	while(l<=r) {
    		int mid=(l+r)/2;
    		if(check(bloomDay,mid,m,k)) {
    			ans=mid;
    			r=mid-1;
    		}
    		else
    			l=mid+1;
    	}
    	
    	return ans==Integer.MAX_VALUE?-1:ans;
    }
    
    private boolean check(int[] a,int x,int m,int k) {
    	
    	int n=a.length;
    	int[] arr=new int[n];
    	
    	for(int i=0;i<n;i++)
    		if(a[i]<=x)
    			arr[i]=1;
    	
    	int num=0,sum=0;
    	for(int i=0;i<n;i++) {
    		if(arr[i]==0)
    			sum=0;
    		else
    			sum++;
    		if(sum>=k) {
    			num++;
    			sum=0;
    		}
    	}
    	
    	return num>=m;
    }
}

5188. 树节点的第 K 个祖先

思路:LCA的简化版本,我们可以考虑倍增算法查找第K个祖先。

不懂倍增算法的可以看我这篇博客

class TreeAncestor {
	
	private int n;
	private int[][] f;
	private int[] dep;
	private List<List<Integer>> list;
	
    public TreeAncestor(int n, int[] parent) {
    	
    	this.n=n;
    	f=new int[n][21];
    	dep=new int[n];
    	list=new ArrayList<>();
    	
    	for(int i=0;i<n;i++)
    		for(int j=0;j<=20;j++)
    			f[i][j]=-1;
    	
    	for(int i=0;i<n;i++)
    		list.add(new ArrayList<>());
    	
    	for(int i=1;i<n;i++) {
    		list.get(i).add(parent[i]);
    		list.get(parent[i]).add(i);
    	}
    	
    	dfs(0,-1);

    }
    
    private void dfs(int u,int father) {
    	
    	if(father!=-1)
    		dep[u]=dep[father]+1;
    	f[u][0]=father;
    	for(int i=1;i<=20;i++) {
    		if(f[u][i-1]!=-1)
    		f[u][i]=f[f[u][i-1]][i-1];
    	}
    	
    	for(int i=0;i<list.get(u).size();i++) {
    		int v=list.get(u).get(i);
    		if(v==father) continue;
    		dfs(v,u);
    	}
    }
    
    public int getKthAncestor(int node, int k) {
    	
    	return get_father(node,k);
    }
    
    private int get_father(int x,int k) {
    	
    	int t=dep[x]-k;
    	
    	for(int i=20;i>=0;i--)
    		if(f[x][i]!=-1 && dep[f[x][i]]>t)
    			x=f[x][i];
    	
    	return f[x][0];
    	
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值