《LeetCode力扣练习》代码随想录——数组(长度最小的子数组---Java)

《LeetCode力扣练习》代码随想录——数组(长度最小的子数组—Java)



刷题思路来源于 代码随想录

在这里插入图片描述


209. 长度最小的子数组
  • 滑动窗口——O(n)
    class Solution {
        public int minSubArrayLen(int target, int[] nums) {
    
            if(nums.length==1){
                return nums[0]>=target?1:0;
            }
    
            int slow=0;
            int fast=0;
            int sum=0;
            int result=Integer.MAX_VALUE;
    
            for(;fast<nums.length;fast++){
    
                sum+=nums[fast];
    
                while(sum>=target){
    
                    int temp=fast-slow+1;
                    result=temp<result?temp:result;
                    sum-=nums[slow++];
    
                }
    
            }
    
            return result==Integer.MAX_VALUE?0:result;
    
        }
    }
    
  • 前缀和 + 二分查找——O(n log(n))
    class Solution {
        public int minSubArrayLen(int target, int[] nums) {
    
            if(nums.length==0){
                return 0;
            }
    
            int[] sum=new int[nums.length+1];
            int result=Integer.MAX_VALUE;
    
            for(int i=1;i<nums.length+1;i++){
                sum[i]=sum[i-1]+nums[i-1];
            }
    
            for(int i=1;i<nums.length+1;i++){
    
                int newTarget=target+sum[i-1];
    
                int location=binarySearch(newTarget,sum);
    
                if(location<0){
                    location=-(location+1);
                }
    
                int temp=location-(i-1);
    
                if(location<=nums.length){
                    result=result<temp?result:temp;
                }
    
            }
    
            return result==Integer.MAX_VALUE?0:result;
    
        }
    
        public int binarySearch(int target, int[] nums){
    
            if(nums.length==0){
                return -1;
            }
    
            int left=0;
            int right=nums.length-1;
    
            while(left<=right){
    
                int middle=(left+right)>>>1;
    
                if(nums[middle]>target){
                    right=middle-1;
                }else if(nums[middle]<target){
                    left=middle+1;
                }else{
                    return middle;
                }
    
            }
    
            return -left-1;
    
        }
    }
    
904. 水果成篮
  • 滑动窗口——O(n)
    class Solution {
        public int totalFruit(int[] fruits) {
    
            if(fruits.length==1){
                return 1;
            }
    
            int slow=0;
            int fast=0;
    
            int[] map=new int[fruits.length];
            int size=0;
            int result=Integer.MIN_VALUE;
    
            for(;fast<fruits.length;fast++){
    
                if(map[fruits[fast]]==0){
                    size++;
                }
    
                map[fruits[fast]]++;
    
                while(size>2){
    
                    map[fruits[slow]]--;
    
                    if(map[fruits[slow]]==0){
                        size--;
                    }
    
                    slow++;
    
                }
    
                int temp=fast-slow+1;
    
                result=result<temp?temp:result;
    
            }
    
            return result==Integer.MIN_VALUE?0:result;
    
        }
    }
    
76. 最小覆盖子串
  • 滑动窗口——O(n+m)
    正常的常规写法
    class Solution {
        public String minWindow(String s, String t) {
    
            if(s.length()==1&&t.length()==1){
                return s.equals(t)?s:"";
            }
    
            int size=0;
            int[] charS=new int[60];
            int[] charT=new int[60];
    
            for(int i=0;i<t.length();i++){
    
                if(charT[getLocation(t.charAt(i))]++==0){
                    size++;
                }
    
            }
    
            int slow=0;
            int fast=0;
            String result=s+'#';
    
            for(;fast<s.length();fast++){
    
                int locationFast=getLocation(s.charAt(fast));
    
                if(charT[locationFast]>0&++charS[locationFast]==charT[locationFast]){
                    size--;
                }
    
                while(size==0){
    
                    String temp=s.substring(slow,fast+1);
    
                    result=temp.length()<result.length()?temp:result;
    
                    int locationSlow=getLocation(s.charAt(slow));
    
                    if(charT[locationSlow]>0&charS[locationSlow]--==charT[locationSlow]){
                        size++;
                    }
    
                    slow++;
    
                }
    
            }
    
            return result.length()==s.length()+1?"":result;
    
        }
    
        public int getLocation(char ch){
    
            return ('A'<=ch&&ch<='Z')?(ch-'A'):(ch-'a'+26);
    
        }
    }
    
  • 滑动窗口——O(n+m)
    由于 substring 函数操作字符串比较费时,导致同样是滑动窗口,将更新结果值的操作拿到 while 循环外面可以大幅度地优化时间
    class Solution {
        public String minWindow(String s, String t) {
    
            if(s.length()==1&&t.length()==1){
                return s.equals(t)?s:"";
            }
    
            int size=0;
            int[] charS=new int[60];
            int[] charT=new int[60];
    
            for(int i=0;i<t.length();i++){
    
                if(charT[getLocation(t.charAt(i))]++==0){
                    size++;
                }
    
            }
    
            int slow=0;
            int fast=0;
            String result=s+'#';
    
            for(;fast<s.length();fast++){
    
                int locationFast=getLocation(s.charAt(fast));
    
                if(charT[locationFast]>0&++charS[locationFast]==charT[locationFast]){
                    size--;
                }
    
                int a=-1;
                int b=-1;
    
                while(size==0){
    
                    a=slow;
                    b=fast;
    
                    int locationSlow=getLocation(s.charAt(slow));
    
                    if(charT[locationSlow]>0&charS[locationSlow]--==charT[locationSlow]){
                        size++;
                    }
    
                    slow++;
    
                }
    
                if(a!=-1&&b!=-1){
                    String temp=s.substring(a,b+1);
                    result=temp.length()<result.length()?temp:result;
                }
    
            }
    
            return result.length()==s.length()+1?"":result;
    
        }
    
        public int getLocation(char ch){
    
            return ('A'<=ch&&ch<='Z')?(ch-'A'):(ch-'a'+26);
    
        }
    }
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值