forked from fishercoder1534/Leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
_581.java
88 lines (82 loc) · 3.02 KB
/
_581.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package com.fishercoder.solutions;
import java.util.Arrays;
public class _581 {
public static class Solution1 {
/**
* credit: https://discuss.leetcode.com/topic/89282/java-o-n-time-o-1-space
* Use start and end to keep track of the minimum subarray nums[start...end] which must be sorted for the entire array nums.
* If start < end < 0 at the end of the for loop, then the array is already fully sorted.
* <p>
* Time: O(n)
* Space: O(1)
*/
public int findUnsortedSubarray(int[] nums) {
int n = nums.length;
int start = -1;
int end = -2;
int min = nums[n - 1];
int max = nums[0];
for (int i = 1; i < n; i++) {
max = Math.max(max, nums[i]);
min = Math.min(min, nums[n - 1 - i]);
if (nums[i] < max) {
end = i;
}
if (nums[n - 1 - i] > min) {
start = n - 1 - i;
}
}
return end - start + 1;
}
}
public static class Solution2 {
/**
* Time: O(n)
* Space: O(1)
* <p>
* This is just an alternative way of writing Solution1, credit: https://leetcode.com/problems/shortest-unsorted-continuous-subarray/discuss/103057/Java-O(n)-Time-O(1)-Space/106306
*
* But still, initializing end to be -2 is an art to take care of the corner case as in Solution1.
*/
public int findUnsortedSubarray(int[] nums) {
int end = -2;
int max = Integer.MIN_VALUE;
//go from left to right, find the number that is smaller than the max number on its left side, that should be the end index because it needs to be sorted
for (int i = 0; i < nums.length; i++) {
max = Math.max(max, nums[i]);
if (nums[i] < max) {
end = i;
}
}
int start = -1;
int min = Integer.MAX_VALUE;
//go from right to left, find the number that is bigger than the min number on its right, that should be the beginning index
for (int i = nums.length - 1; i >= 0; i--) {
min = Math.min(min, nums[i]);
if (nums[i] > min) {
start = i;
}
}
return end - start + 1;
}
}
public static class Solution3 {
/**
* Time: O(nlogn)
* Space: O(n)
*/
public int findUnsortedSubarray(int[] nums) {
int[] clones = nums.clone();
Arrays.sort(clones);
int start = nums.length;
int end = 0;
for (int i = 0; i < nums.length; i++) {
if (clones[i] != nums[i]) {
start = Math.min(start, i);
end = Math.max(end, i);
}
}
return (end - start > 0) ? end - start + 1 : 0;
}
}
}