leetcode简单入门

第二天

数组篇

/**
* 长度最小的子数组
* 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
*
* 示例:
*
* 输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。
*
* 提示:
*
* 1 <= target <= 10^9
* 1 <= nums.length <= 10^5
* 1 <= nums[i] <= 10^5
*/

 /**
     * 滑动窗口
     * 时间复杂度:O(n)
     * 空间复杂度:O(1)
     * @param arr
     * @param s
     */
    private static void mostMinChildArr2(int[] arr,int s){
        int result = arr.length;
        int i = 0;
        int sum = 0;
        int length;
        for(int j=0;j<arr.length;j++){
            sum += arr[j];
            while (sum>=s){
                length = j - i + 1;
                result = result>length ? length:result;
                sum -= arr[i++];
            }
            if(j==arr.length-1&&sum<s){
                result = 0;
            }
        }
        System.out.println(result);
    }

同类型例题
/
*
* 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
*
*
*
* 注意:
*
* 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
* 如果 s 中存在这样的子串,我们保证它是唯一的答案。
*
*
* 示例 1:
*
* 输入:s = “ADOBECODEBANC”, t = “ABC”
* 输出:“BANC”
* 解释:最小覆盖子串 “BANC” 包含来自字符串 t 的 ‘A’、‘B’ 和 ‘C’。
* 示例 2:
*
* 输入:s = “a”, t = “a”
* 输出:“a”
* 解释:整个字符串 s 是最小覆盖子串。
* 示例 3:
*
* 输入: s = “a”, t = “aa”
* 输出: “”
* 解释: t 中两个字符 ‘a’ 均应包含在 s 的子串中,
* 因此没有符合条件的子字符串,返回空字符串。
*
*
* 提示:
*
* m == s.length
* n == t.length
* 1 <= m, n <= 105
* s 和 t 由英文字母组成
*
*
* 进阶:你能设计一个在 o(m+n) 时间内解决此问题的算法吗?
*/

/**
     * 滑动窗口
     * @param s
     * @param t
     * i头指针,j尾指针
     */
    private static void mostMinChildStr(String s,String t){
        int i = 0;
        int flag = 0;
        Map targetMap = new HashMap();
        //暂存j,用于头指针向右移动时保持j不变
        int temp = 0;
        //判断是否是头指针向右移动的情景下
        boolean temp2 = true;
        //头指针和尾指针初始位置:指向主串的第一个和最后一个字母
        int first = 0,last = s.length()-1;

        //特殊情况:t的长度大于s的长度或一样长的情况
        // start
        if(s.length()<t.length()){
            System.out.println("不存在");
            return ;
        } else if(s.length()==t.length()){
            if (s.equals(t)){
                for(int k=first;k<=last;k++){
                    System.out.println(s.charAt(k));
                }
            } else {
                System.out.println("不存在");
            }
            return;
        }
        // end

        //键值对存放t字符串,方便后期比较
        for(int j=0;j<t.length();j++){
            targetMap.put(t.charAt(j),0);
        }
        for(int j=0;j<s.length();j++){
            //判断是否有对应值并且值为0
            if(targetMap.containsKey(s.charAt(j))&&targetMap.get(s.charAt(j)).equals(0)){
                targetMap.put(s.charAt(j),1);
                flag++;
            } else if(targetMap.containsKey(s.charAt(j))&&temp2){
                targetMap.put(s.charAt(j),(int)targetMap.get(s.charAt(j))+1);
            }
            temp2 = true;
            temp = j;
            //flag==t.length()用来判断头尾指针截取的子串是否满条件,为真满足
            while(flag==t.length()){
                //temp2为假是头指针向右移动情况下的,此时j比实际小1,所以实际满足条件的截取尾指针得加一
                if((j-i+2<last-first+1)&&temp2==false){
                    first = i;
                    last = j+1;
                } else if((j-i+1<last-first+1)&&temp2==true){
                    first = i;
                    last = j;
                }
                if(targetMap.containsKey(s.charAt(i))&&(int)targetMap.get(s.charAt(i))>1){
                    targetMap.put(s.charAt(i),(int)targetMap.get(s.charAt(i))-1);
                } else if(targetMap.containsKey(s.charAt(i))&&(int)targetMap.get(s.charAt(i))==1){
                    targetMap.put(s.charAt(i),0);
                    flag--;
                }
                //根据滑动窗口原理,满足条件下 头指针往右移,即i++,j=temp-1则为for循环里在i右移的情况下保持j不变
                i++;
                j=temp-1;
                //temp2=false 判断当前情况是i右移,j不变的情况下
                temp2 = false;
            }
        }
        for(int k=first;k<=last;k++){
            System.out.println(s.charAt(k));
        }
    }

个人感觉:有思路归有思路(因为和第一题思路一样),但是细节之处却是不同,实际上手写出来还遇到很多坑,各种问题需要处理,总之,不能眼高手低0.o
参考链接:代码随想路
ps:希望大佬们能给出进阶解法,学习学习。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值