Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.
For example,
Given nums = [1,3,-1,-3,5,3,6,7]
, and k = 3.
Window position Max --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
Therefore, return the max sliding window as [3,3,5,5,6,7]
.
Note:
You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.
Follow up:
Could you solve it in linear time?
主要思路是:每次找出数组num中下标为i,i+1,i+2,...i+k-1中的最大数和次大数,并记录其下标。假设已经找到了i,i+1,i+2,...,i+k-1中的最大数max1和次大数max2,和其对应的下标。那么找i+1,i+2,....,i+k中的最大数和次大数,及其对应的下标时,只要将num[i+k]与max1和max2比较即可。当然最坏的情况下,还是要把i+1,i+2,...,i+k遍历一次。最坏的情况是,在数组num下标范围中i+1,i+2,...i+k,只有max1或max2的下标在该范围内。而num[i+k+1]又比max1或max2小。。。这种情况的数据所占的比例极小的,所以从概率上来说基本上是O(N)。
public class Solution239 {
/*暴力
public int[] maxSlidingWindow(int[] nums, int k) {
int maxx = Integer.MIN_VALUE;
int[] result = new int[(nums.length-k+1) > 0 ? (nums.length-k+1):1];
if (k >= nums.length) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] >= maxx) maxx = nums[i];
}
result[0] = maxx;
}else {
for (int i = k-1, cnt = 0; i < nums.length; i++, cnt++) {
int j = 0;
maxx = Integer.MIN_VALUE;
while (j < k) {
if(nums[i-j] >= maxx) {
maxx = nums[i-j];
}
j++;
}
result[cnt] = maxx;
}
}
return result;
}*/
public int[] findMax2AndIndex(int [] temp, int begin, int end, int index) {
int[] result = new int[2];
int maxx = Integer.MIN_VALUE, reIndex = -1;
System.out.println(begin+" "+end+" "+index);
for (int i = begin; i <= end; i++) {
if((temp[i] >= maxx)&&(i != index)) {
maxx = temp[i];
reIndex = i;
}
}
result[0] = maxx;
result[1] = reIndex;
return result;
}
public int[] maxSlidingWindow(int[] nums, int k) {
int maxx = Integer.MIN_VALUE;
int[] result = new int[(nums.length-k+1) > 0 ? (nums.length-k+1):1];
if(k <= 1) return nums;
if(k >= nums.length) {
for (int i = 0; i < nums.length; i++) {
maxx = nums[i] > maxx ? nums[i] : maxx;
}
result[0] = maxx;
} else {
int max2 = maxx, maxIndex = 0, max2Index = 0;
if(nums[1] >= nums[0]) {
maxx = nums[1];
maxIndex = 1;
max2 = nums[0];
max2Index = 0;
}else {
maxx = nums[0];
maxIndex = 0;
max2 = nums[1];
max2Index = 1;
}
for (int i = 2; i < k; i++) {
if(nums[i] >= maxx) {
max2 = maxx;
maxx = nums[i];
max2Index = maxIndex;
maxIndex = i;
} else if(nums[i] >= max2 && nums[i] < maxx) {
max2 = nums[i];
max2Index = i;
}
}
result[0] = maxx;
for (int i = k, cnt = 1; i < nums.length; i++, cnt++) {
if(maxIndex <= (i-k) || max2Index <= (i-k)) {
if(maxIndex == (i-k)) {
if(nums[i] >= max2) {
maxIndex = i;
maxx = nums[i];
} else {
maxx = max2;
maxIndex = max2Index;
int[] temp = new int[2];
temp = findMax2AndIndex(nums, i-k+1, i, maxIndex);
max2 = temp[0];
max2Index = temp[1];
}
}else if(max2Index == (i-k)) {
if(nums[i] >= maxx) {
max2 = maxx;
maxx = nums[i];
max2Index = maxIndex;
maxIndex = i;
}else {
int[] temp = new int[2];
temp = findMax2AndIndex(nums,i-k+1, i, maxIndex);
max2 = temp[0];
max2Index = temp[1];
}
}
}else {
if(nums[i] >= maxx) {
max2 = maxx;
max2Index = maxIndex;
maxx = nums[i];
maxIndex = i;
} else if(nums[i] >= max2){
max2 = nums[i];
max2Index = i;
}
}
//System.out.println("maxx="+maxx+" maxIndex="+maxIndex+" max2="+max2+" max2Index="+max2Index);
result[cnt] = maxx;
}
}
return result;
}
/*public int[] maxSlidingWindow(int[] nums, int k) {
int maxx = Integer.MIN_VALUE;
int[] result = new int[(nums.length-k+1) > 0 ? (nums.length-k+1):1];
if(k >= nums.length) {
for (int i = 0; i < nums.length; i++) {
maxx = nums[i] > maxx ? nums[i] : maxx;
}
result[0] = maxx;
} else {
Num max1 = new Num(), max2=new Num();
for (int i = 0; i < k; i++) {
}
}
return result;
}*/
public static void main(String[] args) {
int[] nums = {9,10,9,-7,-4,-8,2,-6};
int k = 5;
int[] result = new int[nums.length-k+1];
Solution239 ans = new Solution239();
result = ans.maxSlidingWindow(nums,k);
for (int i = 0; i < result.length; i++) {
System.out.printf("%d ", result[i]);
}
}
}