LEETCODE双指针 (无重复字符的最长字串,最短无序连续子数组,盛水最多的容器等等)

180 阅读1分钟

image.png 题解:最长字串是一个区间,那么可以通过双指针(滑动窗口)来实现 需要注意的是: 一. 当指针区间的子字符串出现重复时,第一个指针需要移动到重复的位置上 比如abcdc*****, abcd遇到c的时候前一个指针变重新指向第一个c的位置 二. 最后一个指针移到最后时,记得处理 三.subString[a,b)是左闭右开

    public int lengthOfLongestSubstring(String s) {
    	int prev = 0, max = 0;
    	for (int i=1; i< s.length();i++) {
    		String sub = s.substring(prev, i);
    		if (sub.indexOf(s.charAt(i)+"") !=-1) {
    			max = (max > i - prev) ? max : (i-prev);
    			int index = sub.indexOf(s.charAt(i)+"") + 1;
    			prev += index;
    		} else if (i==s.length()-1) {
    			max = (max > i - prev) ? max : (i-prev) + 1;
    		}
    	}
		return max == 0 ? s.length() : max;
    }

image.png 分析:题眼一个连续的子数组y,可以将其拆分为三个数组xyz,其中x和z是满足有序的,说明x最大值均小于yz,z最小值均大于xy。 如何确定y的边界,由于只要把y重排就是升序来说,一定存在y的右边界小于它前面的一个值,同理一定存在y的左边界大于后面的其中一个值,分别找到这样最靠右和最靠左的值相减即可,如题里面的【6,4】与【10,9】

class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int start = 0, end = -1, max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
        int length = nums.length;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] < max) {
                end = i;
            } else {
                max = Math.max(max, nums[i]);
            }
            if (nums[length-1-i] > min) {
                start = length-1-i;
            } else {
                min = Math.min(nums[length-1-i], min);
            }
        }
        return  end - start + 1;
    }
}