LetCode:239。滑动窗口。

1. 求一个字符串最大的子字符串。
1.1 查找某个字符串的最大子字符串。
子字符串:任意取出N个字符,即为字符串的字串(不一定是连续的)。
1.2 比较规则
两个字串比较,先从字符串第一个位置的字符,比较,哪个大,该字符串,大,如果相同,则比较下一个。直到比较出大小。如果一个字符串的长度用尽,仍未比较出大小,则长度长的字符串更大。
举例如下:
字符串: abecd
“ed” 和“bcd”:ed大;
“ecd”和“ec” 相比,ecd 大。

思路如下:如果知道,前k个元素的最大子字符串,那么,k+1个元素的最大子字符串,怎么得到?
第k+1个元素跟,子串的最后一个元素做比较,如果大于,则当前子串最后一个子串去掉,继续与下一个比较。
直到为空,或者是,小于当前子串的最后一个元素,则子串拼接,第k+1个 元素,即为当前最大的子字符串。

建立一个栈,栈里保存的是字符串的索引。最大的子字符串。

在这里插入图片描述

[1]如果一个字符串的最取值

public static String maxSubStr(String  str){
		if(str ==null || str.length() <=1){
			return str;
		}
		Stack<Integer> stack =new Stack<>();
		int length = str.length();
		int index  = 0;
		while (index<length){
			if(stack.isEmpty() || str.charAt(stack.peek())>=str.charAt(index)){
				stack.push(index);
				index++;
			}else{
				stack.pop();
			}
		}
		String result = new String();
		while (!stack.isEmpty()){
			result  = str.charAt(stack.pop())+result;
		}
		return result;
	}

2 求最大的子字符串
2.0 最开始的思路。
维护一个最大的堆,但是复杂度并不低。

2.1
假设第一个窗口的,如果已经知道,前一个窗口的最大子数组,那么当前窗口的最大子数组也可以求出来。
在这里插入图片描述
(1)如果前一个窗口的最大子数组,第一个元素,是前窗口的第一个元素不相同。那么前一个窗口的最大子数组,就是,当前窗口前 k-1个元素的最大子数组。
(2)如果前一个窗口的最大子数组,第一个元素,和前窗口的第一个元素相同。那么当前窗口前k—1 元素的最大子数组,就是一个窗口的最大子数组。
综上所述,当前窗口K-1个元素的最大子数组。如果第(1)中情况,当前k-1个元素窗口的最大子数组就是前一个窗口的最大子数组。第二种情况,则去掉前一个窗口最大子数组的第一个元素。
那么当前窗口的最大子数组,就会把前k个元素。
2. 2 保存所有可能的K个元素。肯
   可能:有成为某个窗口内,最大元素的取值。

        public static int [] solution(int [] nums,int k){
        		//合法性的校验
        		if(nums == null || k<1 || nums.length <k){
        			return ERROR_PARRAM_RESULT;
        		}
        		int length = nums.length;
        		int [] result = new int[length-k+1];
        		Deque<Integer> queue = new ArrayDeque();
        		int index = 0;
        		for(int i=0;i<length;i++){
        			while(!queue.isEmpty() && i-queue.peek()>k-1){
        				queue.poll();
        			}
        			while(!queue.isEmpty()&& nums[i]>nums[queue.peekLast()]){
        				queue.pollLast();
        			}
        			queue.offer(i);
        			if(i>=k-1){
        				result[index++] =  nums[queue.peek()];
        			}
        		}
        		return result;
        	}

3 课后习题,求右边第一个比他的元素
给定一个数组,求每一个元素,比它最大的元素。

  与第一个问题,思路相同,弹出的元素,即为,当前元素右边,第一个元素。
  public Character[] findMaxRightWithStack(Character[] array) {
     if(array == null) {
          return array;
      }
     Character size = array.length;
     Character[] result = new Character[size];
     Stack<Integer> stack = new Stack<>();
     stack.push(0);
     Character index = 1;
     while(index < size) {
     if(!stack.isEmpty() && array[index] > array[stack.peek()]) {
          result[stack.pop()] = array[index];
     } else {
          stack.push(index);
          index++;
     }
     }
     if(!stack.isEmpty()) {
     result[stack.pop()] = -1;
     }
     return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值