-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path_1Array.cpp
More file actions
444 lines (435 loc) · 16 KB
/
Copy path_1Array.cpp
File metadata and controls
444 lines (435 loc) · 16 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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
// 二分查找 704
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int middle = left + (left + right) / 2;
if (nums[middle] < target) { left = middle + 1; }
else if (nums[middle] > target) { right = middle - 1; }
else { return middle; }
}
return -1;
}
class solution_serch {
public:
// 左闭右闭区间
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int middle = left + (left + right) / 2;
if (nums[middle] > target)
right = middle - 1;
else if (nums[middle] < target)
left = middle + 1;
else
return middle;
}
return -1;
}
// 左闭右开区间
int search2(vector<int>& nums, int target) {
int left = 0, right = nums.size(), middle;
while (left < right) {
middle = (left + right) / 2;
if (nums[middle] > target)
right = middle;
else if (nums[middle] < target)
left = middle + 1;
else
return middle;
}
return -1;
}
};
// 移除元素 27
class solution_removeElement {
public:
// 暴力遍历,时间复杂度O(n^2) 空间复杂度O(1)
int removeElement1(vector<int>& nums, int val) {
int size = nums.size();
for (int ii = 0; ii < size; ii++) {
if (nums[ii] == val) {
for (int jj = ii + 1; jj < size; jj++) nums[jj - 1] = nums[jj];
ii--;
size--;
}
}
return size;
}
// 双指针法,时间复杂度O(n) 空间复杂度O(1)
int removeElement2(vector<int>& nums, int val) {
int slow = 0;
for (int fast = 0; fast < nums.size(); fast++) {
if (nums[fast] != val) {
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
// 相向双指针法,基于元素顺序可以改变的题目描述改变了元素相对位置,确保了移动最少元素
int removeElement3(vector<int>& nums, int val) {
int leftIndex = 0;
int rightIndex = nums.size() - 1;
while (leftIndex <= rightIndex) {
// 找左边等于val的元素
while (leftIndex <= rightIndex && nums[leftIndex] != val) { ++leftIndex; }
// 找右边不等于val的元素
while (leftIndex <= rightIndex && nums[rightIndex] == val) { --rightIndex; }
// 将右边不等于val的元素覆盖左边等于val的元素
if (leftIndex < rightIndex) { nums[leftIndex++] = nums[rightIndex--]; }
}
return leftIndex; // leftIndex一定指向了最终数组末尾的下一个元素
}
};
// 有序数组的平方
class solution_nums2 {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1;
vector<int> res(k + 1, 0);
for (int left = 0, right = k; left <= right;) {
int squareLeft = nums[left] * nums[left];
int squareRight = nums[right] * nums[right];
if (squareLeft < squareRight) {
res[k--] = squareRight;
right--;
}
else {
res[k--] = squareLeft;
left++;
}
}
return res;
}
};
class solution_minSubArrayLen {
public:
// 暴力遍历
int minSubArrayLen0(int s, vector<int>& nums) {
int res = INT32_MAX;
int subSum = 0; // 子序列和
int subLen = 0; // 子序列长度
for (int i = 0; i < nums.size(); i++) {
subSum = 0;
for (int j = i; j < nums.size(); j++) {
subSum += nums[j];
if (subSum > s) {
subLen = j - i + 1;
res = subLen < res ? subLen : res;
break;
}
}
}
return res == INT32_MAX ? 0 : res;
}
// 滑动窗口
int minSubArrayLen(int s, vector<int>& nums) {
int res = INT32_MAX;
int subSum = 0; // 子序列和
int subLen = 0; // 子序列长度
int l = 0; // 滑动窗口起始位置
for (int r = 0; r < nums.size(); r++) {
subSum += nums[r];
while (subSum >= s) {
subLen = r - l + 1;
res = res < subLen ? res : subLen;
subSum -= nums[l++]; // 精华所在
}
}
return res == INT32_MAX ? 0 : res;
}
// 找子串和小于s的最大长度
int maxSubArrayLen(int s, vector<int>& nums) {
int res = 0;
int subSum = 0;
int subLen = 0;
int left = 0;
int right = 0;
while (right <= nums.size()) {
subSum += nums[right];
while (subSum > s) { subSum -= nums[left++]; }
subLen = right - left + 1;
res = res > subLen ? res : subLen;
right++;
}
return res == 0 ? 0 : res;
}
};
class solution_Matrix {
public:
vector<vector<int>> generateMatrix(int n) {
// 左闭右闭区间
vector<vector<int>> res(n, vector<int>(n, 0));
int left = 0, right = n - 1, top = 0, bottom = n - 1, num = 1;
while (left <= right && top <= bottom) {
// 从左到右
for (int i = left; i <= right; i++) res[top][i] = num++;
top++;
// 从上到下
for (int i = top; i <= bottom; i++) res[i][right] = num++;
right--;
// 从右到左
for (int i = right; i >= left; i--) res[bottom][i] = num++;
bottom--;
// 从下到上
for (int i = bottom; i >= top; i--) res[i][left] = num++;
left++;
}
return res;
}
vector<vector<int>> generateMatrix2(int n) {
// 左闭右开区间
vector<vector<int>> res(n, vector<int>(n, 0));
int left = 0, right = n - 1, top = 0, bottom = n - 1, num = 1;
while (left < right && top < bottom) {
// 从左到右
for (int i = left; i < right; i++) res[top][i] = num++;
top++;
// 从上到下
for (int i = top; i < bottom; i++) res[i][right] = num++;
right--;
// 从右到左
for (int i = right; i > left; i--) res[bottom][i] = num++;
bottom--;
// 从下到上
for (int i = bottom; i > top; i--) res[i][left] = num++;
left++;
}
return res;
}
vector<vector<int>> generateMatrix3(int n) {
vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
int loop =
n /
2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
int mid =
n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
int count = 1; // 用来给矩阵中每一个空格赋值
int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
int i, j;
while (loop--) {
i = startx;
j = starty;
// 下面开始的四个for就是模拟转了一圈
// 模拟填充上行从左到右(左闭右开)
for (j = starty; j < n - offset; j++) { res[startx][j] = count++; }
// 模拟填充右列从上到下(左闭右开)
for (i = startx; i < n - offset; i++) { res[i][j] = count++; }
// 模拟填充下行从右到左(左闭右开)
for (; j > starty; j--) { res[i][j] = count++; }
// 模拟填充左列从下到上(左闭右开)
for (; i > startx; i--) { res[i][j] = count++; }
// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0,
// 0),第二圈起始位置是(1, 1)
startx++;
starty++;
// offset 控制每一圈里每一条边遍历的长度
offset += 1;
}
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
if (n % 2) { res[mid][mid] = count; }
return res;
}
// 54
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
vector<int> res;
int left = 0, right = n - 1, top = 0, bottom = m - 1;
while (left <= right && top <= bottom) {
// 从左到右
for (int i = left; i <= right; i++) res.push_back(matrix[top][i]);
top++;
// 从上到下
for (int i = top; i <= bottom; i++) res.push_back(matrix[i][right]);
right--;
// 从右到左
if (top <= bottom) { // 这个和下面的判断在m!=n时是必须的
for (int i = right; i >= left; i--) res.push_back(matrix[bottom][i]);
bottom--;
}
// 从下到上
if (left <= right) {
for (int i = bottom; i >= top; i--) res.push_back(matrix[i][left]);
left++;
}
}
return res;
}
};
class solution_leetcode34 { // 在排序数组中查找元素的第一个和最后一个位置
public:
vector<int> searchRange(vector<int>& nums, int target) {
int first = serachFirst(nums, target);
int last = serachLast(nums, target);
return {first, last};
}
private:
int serachFirst(vector<int>& nums, int target) {
int left = 0, right = nums.size();
while (left <= right) {
int mid = left + (right - left) / 2;
if (target == nums[mid]) {
if (mid > 0 && nums[mid - 1] == nums[mid]) { right = mid - 1; }
else
return mid;
}
else if (target < nums[mid]) { right = mid - 1; }
else { left = mid + 1; }
}
return -1;
}
int serachLast(vector<int>& nums, int target) {
int left = 0, right = nums.size();
while (left <= right) {
int mid = left + (right - left) / 2;
if (target == nums[mid]) {
if (mid != nums.size() - 1 && nums[mid + 1] == nums[mid]) { left = mid + 1; }
else
return mid;
}
else if (target < nums[mid]) { right = mid - 1; }
else { left = mid + 1; }
}
return -1;
}
};
class s367 {
// 给你一个正整数 num 。如果 num 是一个完全平方数,则返回 true ,否则返回 false 。
// 完全平方数 是一个可以写成某个整数的平方的整数。换句话说,它可以写成某个整数和自身的乘积。
// 不能使用任何内置的库函数,如 sqrt 。
public:
bool isPerfectSquare(int num) {
if (num == 1) return 1;
int left = 1, right = num - 1;
int mid;
while (left <= right) {
mid = left + ((right - left) >> 1);
if (num / mid == mid)
break;
else if (num / mid > mid)
left = mid + 1;
else if (num / mid < mid)
right = mid - 1;
}
return mid * mid == num;
}
};
class s26
// 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次
// ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致然后返回 nums 中唯一元素的个数。
// 考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:
// 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums
// 的其余元素与 nums 的大小不重要。 返回 k 。
{
public:
int removeDuplicates(vector<int>& nums) {
int slow = 1, fast = 1, k = nums.size();
for (; fast < nums.size(); fast++) {
if (nums[fast] != nums[fast - 1]) { nums[slow++] = nums[fast]; }
else
k--;
}
return k;
}
};
class s27
// 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
{
public:
void moveZeroes(vector<int>& nums) {
for (int slow, fast = 0; fast < nums.size(); fast++)
if (nums[fast]) swap(nums[fast], nums[slow++]);
}
};
class s844 {
public:
// 给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。
// # 代表退格字符。注意:如果对空文本输入退格字符,文本继续为空。
bool backspaceCompare(string& s, string& t) {
stringDeal(s);
stringDeal(t);
return s == t;
}
private:
void stringDeal(string& s) {
int slow = 0, fast = 0, size_s = s.size(), k = s.size();
for (; fast < k; fast++) {
size_s = size_s < 0 ? 0 : size_s;
slow = slow < 0 ? 0 : slow;
{
if (s[fast] != '#')
s[slow++] = s[fast];
else if (slow > 0) {
slow--;
size_s--;
size_s--;
}
else
size_s--;
}
}
s.resize(size_s);
}
};
class s904_fruitBasket {
// 找至多包含两种元素的最长子串,返回其长度
public:
int totalFruit(vector<int>& fruits) {
int left = 0, right = 0, res = 0;
unordered_map<int, int> species;
while (right < fruits.size()) {
++species[fruits[right]];
while (species.size() > 2) {
int currentFruit = fruits[left];
--species[currentFruit];
if (species[currentFruit] == 0) species.erase(currentFruit);
left++;
}
res = res > (right - left + 1) ? res : (right - left + 1);
right++;
}
return res;
}
};
class s76_myFirstHard {
public:
string minWindow(string s, string t) {
unordered_map<int, int> res, need;
for (auto& i : t) { ++need[i]; }
// count为res满足数量要求的数量
int left = 0, right = 0, count = 0, len = INT32_MAX, start = 0;
while (right < s.size()) {
// 判断是否满足条件
if (need.find(s[right]) != need.end()) {
// 应将窗口扩充
++res[s[right]];
if (res[s[right]] == need[s[right]]) count++;
}
while (count == need.size()) {
// 更新结果
if (len > right - left + 1) {
start = left;
len = right - left + 1;
}
// 最大程度地压缩left
// 如果s left恰好在窗口内,那么需要处理结果哈希表
if (need.find(s[left]) != need.end()) {
if (res[s[left]] == need[s[left]]) --count;
--res[s[left]];
}
left++;
}
++right;
}
return len == INT32_MAX ? "" : s.substr(start, len);
}
};
int main() {
string s = "sadsafback", t = "ack";
string a = s76_myFirstHard().minWindow(s, t);
}