数组:滑动窗口,指针

18 篇文章 0 订阅
14 篇文章 0 订阅

1. 给定一个含有 n 个正整数的数组和一个正整数 target 。

        找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1,         numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

        收获:

                再看到题解思路之后,自己手动写了一遍,写的时候用if循环实现窗口移动,发现此时窗口的左边界不能移动,考虑到要使用while循环,但没理清思路。做题时,要先想出算法是具体如何实现的       

二刷:滑动窗口移动时,不仅是指针的移动,也是窗口内和的变化

左指针移动,窗口和减小,右指针移动窗口值增加

        思路:

        想把窗口值先设为1,之后先小窗在数组移动,移动应该是一个个移动,我程序设计的跳的,再挑调整发现,测试时,超过时间限制;若发现值大于等于目标值的,直接返回窗口值

结果值通过了12/19

滑动窗口示意图:

结论是:只要小于目标值左指针滑动,大于目标值右指针滑动;

https://camo.githubusercontent.com/dd84aee84237ebb78cf7ffde58803dc03350a4071d0981b8add65d9c59199ac4/68747470733a2f2f636f64652d7468696e6b696e672e63646e2e626365626f732e636f6d2f676966732f3230392e2545392539352542462545352542412541362545362539432538302545352542302538462545372539412538342545352541442539302545362539352542302545372542422538342e676966

测试只通过了12/19;有小伙伴可以帮我改改了

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //滑动窗口,窗口长度为i,从1开始递增,知道找到满足条件的值
        //窗口长度
        int len =1;
        while(len<=nums.length){
            //遍历数组
            for(int i = 0;i<nums.length;i+=len){
                //根据窗口长度求和
                int sum =0;
                for(int j=i;j<i+len;j++){
                    if(j > nums.length-1){
                         break;
                    }
                   sum +=nums[j];
                }
                if(target <= sum){
                    return len;
                }
            }
            len++;
        }
        return 0;
    }
}

正确答案:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //窗口滑动,l左窗口边界,r 右窗口边界
        //当[l,r]中的和,总数小于目标值时,r增加
        //当[l,r]中的和,总数大于目标值时,l增加
        //与之前记录的长度想比较,得出最小的值
        //for语句是r从0到数组长度
        int l = 0;
        int r = 0;
        int sum=0;
        int len =0;//记录相对最小长度
        for(r=0;r<nums.length;r++){
            sum+=nums[r];
            //这里缺了while循环,来缩小框的范围,不是用if语句
            // if(sum >= target){
            //     len = len ==0 ? r-l+1:Math.min(len,r-l+1);
            //     sum-=nums[l];
            //     l++;
             while(sum >= target){
                len = len ==0 ? r-l+1:Math.min(len,r-l+1);
                sum-=nums[l];
                l++;
             
            }

        }
        return len;
    }
}

2.请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

题目链接:力扣

class Solution {
    public int lengthOfLongestSubstring(String s) {
        //1.尝试第一种方法:发现当字符题目要求最长字符不能包含重复字符
        //所以此时需要map来储存字符,以及字符出现的最后一个位置;
        //r用来遍历整个字符,l用于跳转
        char[] c = s.toCharArray();
        //int r = 0;
        int l =-1;
        int res =0;
        Map<Character,Integer> map = new HashMap<>();
        for(int i=0;i<c.length;i++){
            if(map.containsKey(c[i])){
                l =Math.max(l,map.get(c[i]));//l的定位是靠c[i]最近的相同的字符
            }
            map.put(c[i],i);
            res = Math.max(res,i-l);
        }
        return res;
    }
}

3.反转单词顺序

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。

题目链接:力扣

class Solution {
    public String reverseWords(String s) {
        //删除字符两端空格
        s = s.trim();
        StringBuilder res = new StringBuilder();
        int i = s.length()-1,j=s.length()-1;
        while(i>=0){
            //倒着发现下一个空格
            while(i>=0 && s.charAt(i) != ' ') i--;
            //添加字符串到结果中
            res.append(s.substring(i+1,j+1)+" ");//这里写成字符串形式的空格
            //使i找到下一个不是空格的
            while(i>=0 && s.charAt(i) ==' ') i--;
            j=i;//j定位是一个字符的末尾,i是寻找下个字符,跟寻找最长的不重复数组的j的定义差不多
        }
        return res.toString().trim();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值