【数据结构与算法】leetcode刷题记录(分割数组为连续自序列)---->桶排序+hashMap

分割数组为连续自序列

给你一个按升序排序的整数数组 num(可能包含重复数字),请你将它们分割成一个或多个子序列,其中每个子序列都由连续整数组成且长度至少为 3 。

如果可以完成上述分割,则返回 true ;否则,返回 false 。

示例 1:
        输入: [1,2,3,3,4,5]
        输出: True
        解释:
        你可以分割出这样两个连续子序列 : 
        1, 2, 3
        3, 4, 5
示例 2:
        输入: [1,2,3,3,4,4,5,5]
        输出: True
        解释:
        你可以分割出这样两个连续子序列 : 
        1, 2, 3, 4, 5
        3, 4, 5
示例 3:
        输入: [1,2,3,4,4,5]
        输出: False

java

贪心思想:

先统计每个数组出现的频数, 存放在一个hashmap中, (例: 1 2 3 3 4 4 5)

则现在map = {1:1,2:1,3:2,4:2,5:1}

HashMap<Integer,Integer> mmp = new HashMap<>();
for(int i : nums) {
    if (!mmp.containsKey(i)) {
        mmp.put(i, 1);
    } else {
        mmp.put(i, mmp.get(i) + 1);
    }
}

根据贪心思想, 每次取一个连续数字, 如果数字不联系, 则跳出循环, 产生一个子序列, 但是根据上面的例子, 12345都连续,到底取到哪一个数字停呢,

根据贪心思想,虽然取刀不能连续, 但也要保证后面出现频率较少的数字跟着下一轮遍历 , 这样就可以保证最优化的子序列:

if(!mmp.containsKey(key+1)||mmp.get(key+1)<=mmp.get(key)){
    break;
}

第一次取得 1 2 3 4 . 而不是 12345, map中剩余元素{ 3: 1, 4: 1 , 5: 1};

下一次循环则将map遍历完成.

while (mmp.size()>0){
    //int key = nums[0];
    int key = minKey(mmp);
    int lennow = 0;
    while (mmp.containsKey(key)){
        mmp.put(key,mmp.get(key)-1);
        lennow++;
        if(!mmp.containsKey(key+1)||mmp.get(key+1)<=mmp.get(key)){
            break;
        }
        key++;
    }
    if (lennow<3)return false;
    deleteValueIsZero(mmp);
}

中间需要用到两个自己写方法:

minKey(): 获取mmp中的最小的key

public static int minKey(HashMap<Integer,Integer> mmp){
    int min = Integer.MAX_VALUE;
    for(int item: mmp.keySet()){
        if(item<min){
            min = item;
        }
    }
    return min;
}

maxKey(): 获取mmp中最大的key

public static int maxKey(HashMap<Integer,Integer> mmp){
    int max = Integer.MIN_VALUE;
    for(int item: mmp.keySet()){
        if(item>max){
            max = item;
        }
    }
    return max;
}

deleteValueIsZero():删除map中值为0的key

public static void deleteValueIsZero(HashMap<Integer,Integer> mmp){
    int len = mmp.size();
    int i = minKey(mmp);
    while (i<maxKey(mmp)+1){
        if(mmp.containsKey(i)){
            if(mmp.get(i)==0){
                mmp.remove(i);
            }
        }
        i++;
    }
}

完整代码

class Solution {
    public boolean isPossible(int[] nums) {
        if (nums.length<3)return false;
        HashMap<Integer,Integer> mmp = new HashMap<>();
        for(int i : nums) {
            if (!mmp.containsKey(i)) {
                mmp.put(i, 1);
            } else {
                mmp.put(i, mmp.get(i) + 1);
            }
        }
        if(mmp.size()<3)return false;
        while (mmp.size()>0){
            //int key = nums[0];
            int key = minKey(mmp);
            int lennow = 0;
            while (mmp.containsKey(key)){
                mmp.put(key,mmp.get(key)-1);
                lennow++;
                if(!mmp.containsKey(key+1)||mmp.get(key+1)<=mmp.get(key)){
                    break;
                }
                key++;
            }
            if (lennow<3)return false;
            deleteValueIsZero(mmp);
        }
        return true;
    }
    public static int minKey(HashMap<Integer,Integer> mmp){
        int min = Integer.MAX_VALUE;
        for(int item: mmp.keySet()){
            if(item<min){
                min = item;
            }
        }
        return min;
    }
    public static int maxKey(HashMap<Integer,Integer> mmp){
        int max = Integer.MIN_VALUE;
        for(int item: mmp.keySet()){
            if(item>max){
                max = item;
            }
        }
        return max;
    }
    public static void deleteValueIsZero(HashMap<Integer,Integer> mmp){
        int len = mmp.size();
        int i = minKey(mmp);
        while (i<maxKey(mmp)+1){
            if(mmp.containsKey(i)){
                if(mmp.get(i)==0){
                    mmp.remove(i);
                }
            }
            i++;
        }
    }
}

python

贪心算法:

因为统计再python中可以使用collections.Counter, 这个包中也有最大元素,最小元素的方法,所以很简单

class Solution:
    def isPossible(self, nums: List[int]) -> bool:
        if len(nums) < 3:
            return False
        if len(set(nums)) < 3:
            return False
	   #统计		
        mmp = collections.Counter(nums) 
        while mmp:
            key, lengths = min(mmp.keys()), 0
            while (key in mmp): #依次检查是否有连续数字
                mmp[key] -= 1
                lengths += 1
                #当后面的数字频数小于前面的数字时,则退出循环
                if mmp[key+1] <= mmp[key]: 
                    break
                key += 1
            if lengths < 3: return False
            mmp += collections.Counter() 
        return True
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值