题目描述:
爱丽丝有一手(hand)由整数数组给定的牌。
现在她想把牌重新排列成组,使得每个组的大小都是 W,且由 W 张连续的牌组成。
如果她可以完成分组就返回 true,否则返回 false。
示例 1:
输入:hand = [1,2,3,6,2,3,4,7,8], W = 3
输出:true
解释:爱丽丝的手牌可以被重新排列为 [1,2,3],[2,3,4],[6,7,8]。
示例 2:
输入:hand = [1,2,3,4,5], W = 4
输出:false
解释:爱丽丝的手牌无法被重新排列成几个大小为 4 的组。
提示:
1 <= hand.length <= 10000
0 <= hand[i] <= 10^9
1 <= W <= hand.length.
——传送门
题意就是给你一串数字hand,判断能否分成若干串子数列,每列子数列都满足为连续的W个数字,首先得想法就是从这串数字中取数列,判断能否按照我们的意愿取完。
很典型的贪心题目,一开始可以先判断一下这串数字能否均分成每串长度都是W的子数列,之后因为数列需要连续,所以一定要排序,我采用的TreeMap存储(按照key的大小排序),map的key表示hand中的数字,value表示这个数字出现的次数,便于之后的取用,最后就开始从map中不断的取数字,先取到map的第一个key,然后以这个key为开头,一直取W个递增的数字,每取一个数字就更新这个map,如果取不出来就直接返回false,否则一直从map中取,直到map中数字个数小于W,这时候判断map中是否已经没有数字了,如果没有就说明已经按照我们的意愿把数字都取完了,返回true,如果没有取完,返回false。
public boolean isNStraightHand(int[] hand, int W) {
if (hand.length % W != 0){
return false;
}
//Arrays.sort(hand);
Map<Integer,Integer> map = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
for (int i = 0; i < hand.length; i ++){
if (map.containsKey(hand[i])){
map.put(hand[i],map.get(hand[i])+1);
}else{
map.put(hand[i],1);
}
}
while(map.size() >= W){
int first = -1;
for (Map.Entry<Integer,Integer> entry : map.entrySet()) {
first = entry.getKey();
//System.out.println(first);
break;
}
for(int i =0; i < W; i ++){
map.put(first,map.get(first)-1);
if(map.get(first) == null){
return false;
}
if(map.get(first)==0){
map.remove(first);
}
first ++;
// System.out.println(map.get(first));
}
}
for (Map.Entry<Integer,Integer> entry : map.entrySet()) {
System.out.println(entry.getKey()+" "+entry.getValue());
}
return map.size() == 0?true:false;
}
由于使用了map排序,不断查找更新map,所以执行时间为80ms
之后在网上看到另一种解法,思路和我一样,只不过他很巧妙的使用了一个vis数组来标记访问过的数字,然后一只取没有访问过的并且符合条件的数字,执行时间缩短到了28ms。
public boolean isNStraightHand(int[] hand, int W) {
int n=hand.length;
if(n%W!=0){
return false;
}
Arrays.sort(hand);
int[] vis=new int[n];
for(int i=0;i<n;i++){
if(vis[i]==0){
int cnt=1;
vis[i]=1;
int pre=hand[i];
int j=i+1;
while(cnt<W){
if(j>=n){
break;
}
if(vis[j]==0 && hand[j]==pre+1){
cnt++;
vis[j]=1;
pre=hand[j];
}
j++;
}
if(cnt!=W){
return false;
}
}
}
return true;
}
}