跟着代码随想录刷力扣(LeetCode)


前言

记录跟着“代码随想录”刷力扣的过程
链接: 代码随想录


数组部分(一)

三、移除元素

844.比较含退格的字符串

使用双指针法
注意点:当退格‘#’数量大于字母数量时,要注意控制 j 的边界

class Solution {
    public boolean backspaceCompare(String s, String t) {
        s=get(s);
        t=get(t);
        if(s.equals(t)) return true;
        else return false;
    }
    public String get(String s){
        int i=0,j=0;
        char[] nums=s.toCharArray();
        for(i=0;i<nums.length;i++){
            if(nums[i]!='#'){
                nums[j++]=nums[i];
            }
            else {
                if(j>0) j--;
            }
        }
        s=String.valueOf(nums,0,j);
        return s;
    }
}

977.有序数组的平方

使用双指针法
思路:因为数组按照非递减顺序排序,所以在任意情况下元素平方的最大值在数组的最左或最右。所以用左右两个指针,分别从数组的头尾开始,依次取出较大值。

class Solution {
    public int[] sortedSquares(int[] nums) {
        int left=0,right=nums.length-1,index=nums.length-1;
        int[] result = new int[nums.length];
        while(left<=right){
            if(Math.abs(nums[left]) < Math.abs(nums[right])){
                result[index--]=nums[right]*nums[right];
                right--;
            }else {
                result[index--]=nums[left]*nums[left];
                left++;
            }
        }
        return result;
    }
}

四、有序数组的平方

即上述977.有序数组的平方(不知道为啥重复了)

五、长度最小的子数组

209.长度最小的子数组

解法一:暴力解。i从0开始,每个循环往后移一位,直到数组末尾。每个循环中,j从i开始,记录从i开始使sum>=target需要的长度,并与之前的长度比较获取最小长度。

解法二:滑动窗口:右边界j一直右移,sum>=target后收缩左边界 i

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int i=0,j,sum=0,min=Integer.MAX_VALUE;
        for(j=0;j<nums.length;j++){
            sum+=nums[j];
            while(sum>=target){
                min=min>(j-i+1)?(j-i+1):min;
                sum-=nums[i];
                i++;
            }
        }
        return min==Integer.MAX_VALUE?0:min;
    }
}

904.水果成篮

滑动窗口
题目意思解释成:最多包含2个不同数字的最大窗口长度

思路:用一个Map记录数字值及其出现的次数,当记录到出现三个不同的数字时,收缩左边界,直至某一个数字在窗口中的出现次数减为0。记录此时的窗口大小。

class Solution {
    public int totalFruit(int[] fruits) {
        int left=0,right=0,num=0;
        HashMap<Integer, Integer> map = new HashMap<>();
        int i,j;
        for(right=0;right<fruits.length;right++){
           j=fruits[right];
           map.put(j,map.getOrDefault(j,0)+1);

           //收缩左边界
            while(map.size()>2){
                i=fruits[left];
                map.put(i,map.getOrDefault(i,0)-1);
                if(map.get(i)==0) map.remove(i);
                left++;
            }
            num=num>(right-left+1)?num:(right-left+1);
        }
        return num;
    }
}

76.最小覆盖子串

滑动窗口
注意点:
1、需要记录t中每个字母出现的次数
2、收缩左边界时,除了要剔除不属于t的字母,还要剔除冗余的字母,否则得不到最小子串

class Solution {
    public String minWindow(String s, String t) {
        if(s.equals("")||t.equals("")) return "";
        int l=0,r;// l为窗口左边界,r为窗口右边界
        String res=""; //目标子串
        char[] str= s.toCharArray(); //这一步可以省略
        //用一个HashMap记录t中各个字母及出现的次数
        //表示还需要匹配哪些字母及他们的个数
        HashMap<Character, Integer> map = new HashMap<>();
        for(int i=0;i<t.length();i++) {
            map.put(t.charAt(i),map.getOrDefault(t.charAt(i),0)+1);
        }
        
        int len=Integer.MAX_VALUE,match=0;//match为已匹配的个数
        for(r=0;r<s.length();r++){//右边界右移
            if(map.containsKey(str[r]))  {
                map.put(str[r],map.get(str[r])-1);
                if(map.get(str[r])>=0) match++;
                //如果str[r])<0 表示该字母冗余
            }
			//收缩左边界:当l指向的字母不属于t 或 冗余时,l++
            while(l<=r&&(!map.containsKey(str[l])||map.get(str[l])<0)) {
            	//将冗余字母从窗口中剔除
                if(map.containsKey(str[l])) map.put(str[l],map.get(str[l])+1);
                l++;
            }
            if(match==t.length()&&(r-l+1)<len){//完全匹配
                len=r-l+1;
                res=s.substring(l,r+1);
            }
        }
        return res;
    }
}

休息休息!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值