904:水果成篮

java中通过Integer.MAX_VALUE取到Integer的最大值;

int result = Integer.MAX_VALUE;

这题的思想就是从字符串中找到最长的只包含两种数字的子串;

一开始提交的代码,也算是小暴力解法吧,附上代码:
 

class Solution {
    public int totalFruit(int[] fruits) {
        //这题的思想就是从字符串中找到最长的只包含两种数字的子串;
        int i=0;//表示子串的其实位置;
        int length = 0;//记录子串长度;
        int count = 0;//记录类型数;
        int[] nums = new int[100000];
        for(int j = 0; j < fruits.length; j++){
            nums[fruits[j]]++;
            if(nums[fruits[j]] == 1){//如果这个类型没有见过
                count++;//就在类型数上+1;
            }
            while(count > 2){//如果当前子串的类型数多余2个,这时就得挪动起始位置i;
                if(nums[fruits[i]] == 1){//如果i是最后一个类型的元素;
                    count--;//这里先让类型数-1;
                }
                nums[fruits[i]]--;
                i++;//挪动i的位置;
            }
            length = length >= (j - i + 1) ? length : (j - i + 1);
        }
        return length;
    }
}

写了上面找最长子串后,感觉这题的难点就在于子数组的类型统计上,我这里也用了双指针法,但是也算是一种小暴力的方法吧,我这里用了一个非常长的数组用于统计类型个数,但这里,我感觉使用一种set类型的map<类型,个数>就非常适合接这道题;
关于源码中的疑问解释:
getOrDefault()方法:
(1)getOrDefault(key, default)如果存在key, 则返回其对应的value, 否则返回给定的默认值
(2)key值相同, value值+1或者-1
如上述代码,map.put(s1.charAt(i), map.getOrDefault(s1.charAt(i), 0) + 1); 若没有s1中的字符就是0, 若有s1中的字符就是在原有值上+1;假如是map.put(s2.charAt(i), map.getOrDefault(s2.charAt(i), 0) - 1); 若没有s2中的字符就是0, 若有s2中的字符就是在原有值上-1;
下面是官方代码:
 

class Solution {
    public int totalFruit(int[] fruits) {
        int n = fruits.length;
        Map<Integer, Integer> cnt = new HashMap<Integer, Integer>();

        int left = 0, ans = 0;
        for (int right = 0; right < n; ++right) {
            cnt.put(fruits[right], cnt.getOrDefault(fruits[right], 0) + 1);
            while (cnt.size() > 2) {
                cnt.put(fruits[left], cnt.get(fruits[left]) - 1);
                if (cnt.get(fruits[left]) == 0) {
                    cnt.remove(fruits[left]);
                }
                ++left;
            }
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }
}

其中感觉官方代码并不好,这里用了hashMap倒把题目弄简单了;
还是来学习一下这前0.23%的大佬的解法吧:
 

class Solution {
    public int totalFruit(int[] fruits) {

        int type1 = fruits[0], type2 = -1;
        int n = fruits.length;
        int left = 0, right = 1, pre = 0;
        int ans = 0;

        while(right < n){
            int type = fruits[right];
            if(type != type1){
                if(type != type2  && type2 != -1){
                    ans = Math.max(ans, right - left);
                    left = pre;
                }
                
                type2 = type1;
                type1 = type;
                pre = right;
            }
            right++;
        }
        return Math.max(ans, right - left);        
    }
}

大佬不愧是大佬,这里它定义了两个type,用于记录当前子串的类型。其中没有用的篮子被记录为-1,不管是向右扩充子串,还是向右收缩子串,收缩或者扩充元素永远要与两个type类型相比较,同时type也应该和-1比较,判断是否为空;

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值