-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
142 lines (127 loc) · 3.39 KB
/
main.cpp
File metadata and controls
142 lines (127 loc) · 3.39 KB
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Source: https://leetcode.com/problems/max-consecutive-ones-iii
// Title: Max Consecutive Ones III
// Difficulty: Medium
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Given a binary array `nums` and an integer `k`, return the maximum number of consecutive `1`'s in the array if you can flip at most `k` `0`'s.
//
// **Example 1:**
//
// ```
// Input: nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2
// Output: 6
// Explanation: [1,1,1,0,0,**1**,1,1,1,1,**1**]
// Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.```
//
// **Example 2:**
//
// ```
// Input: nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], k = 3
// Output: 10
// Explanation: [0,0,1,1,**1**,**1**,1,1,1,**1**,1,1,0,0,0,1,1,1,1]
// Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.
// ```
//
// **Constraints:**
//
// - `1 <= nums.length <= 10^5`
// - `nums[i]` is either `0` or `1`.
// - `0 <= k <= nums.length`
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <vector>
using namespace std;
// DP, TLE
//
// Let DP[j] be the max count with j flip.
//
// If nums[i] = 0:
// DP[0][i] = 0
// DP[j][i] = DP[j-1][i-1]+1
//
// If nums[i] = 1:
// DP[j][i] = DP[j][i-1]+1
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
auto counts = vector<int>(k + 1);
int maxCount = 0;
for (int num : nums) {
if (num == 0) {
for (int j = k; j > 0; --j) {
counts[j] = counts[j - 1] + 1;
}
counts[0] = 0;
} else {
for (int j = k; j >= 0; --j) {
++counts[j];
}
}
maxCount = max(maxCount, *max_element(counts.cbegin(), counts.cend()));
}
return maxCount;
}
};
// Sliding window
//
// Count the number of ones before each zero. Assuming there is a zero at the end.
// Use sliding on k+1 zeros.
class Solution2 {
public:
int longestOnes(const vector<int>& nums, int k) {
const int n = nums.size();
// Count ones before zeros
auto counts = vector<int>();
counts.reserve(n + 1);
{
int count = 0;
for (int num : nums) {
if (num == 0) {
counts.push_back(count + 1); // include this zero
count = 0;
} else {
++count;
}
}
counts.push_back(count + 1);
}
// Sliding window
const int m = counts.size();
int count = 0;
int maxCount = 0;
for (int i = 0; i < m; ++i) {
count += counts[i];
maxCount = max(maxCount, count - 1); // exclude last zero
if (i >= k) {
count -= counts[i - k];
}
}
return maxCount;
}
};
// Two pointer
//
// Loop through the array and count the zeros.
// When there is more than k zeros, move the left pointer.
class Solution3 {
public:
int longestOnes(const vector<int>& nums, int k) {
const int n = nums.size();
// Loop, range is (left, right]
int left = -1;
int zeros = 0;
int maxCount = 0;
for (int right = 0; right < n; ++right) {
// Update zero count
if (nums[right] == 0) ++zeros;
// Move left
while (zeros > k) {
if (nums[++left] == 0) --zeros;
}
// Update max length
maxCount = max(maxCount, right - left);
}
return maxCount;
}
};