! a2 k& W* i X ^那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。1 [0 D) o m( c2 T1 u8 \$ v; b
) E6 m3 O0 U% U2 J$ {/ P# c
此时可以考虑双指针法了,2 K. j. h# M& j- u C9 K& r ~9 P
. p o& L7 [# G5 k( }2 M ?' O) Z, Gi指向起始位置(负数),j指向终止位置(正数)。6 A% \- `+ H4 d% }; ^; B0 a y+ x
# d; z5 J, H( p7 C( ?9 I1 y' @: N
定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。 ( b! {3 F# [! u8 j9 U/ s) ~8 O, E9 ?' v/ I$ A; u9 l
如果A * A < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。 3 g; k8 x! o( X0 e X6 z" i$ A4 M* y' ~ ? W
如果A * A >= A[j] * A[j] 那么result[k--] = A * A; ; ^7 \. w5 W4 Q2 `- n5 S6 ], s r S5 K9 @) f, ~2 r
class Solution {" \- B" g8 z1 Y/ U8 U# k" g* t
public: 5 W( {6 ` ~, M! E! c vector<int> sortedSquares(vector<int>& A) { ; T! B2 B1 @$ `, j( ], w" V% T2 E, l int k=A.size()-1;- K/ i/ X; k# q% a! a6 ^, w
vector<int> result(A.size(),0);$ N9 p3 [( U5 z: c; Z2 g
for(int i=0,j=A.size()-1;i<=j;) R r4 B8 O9 X& T8 J
{! g. `9 A1 f6 Z: U
//遍历一遍 ' m. H5 V$ n- r ?; _ h0 @$ B8 t if(A*A<A[j]*A[j]) # b9 ]/ Z, |3 h* q' l$ u; \ { 6 p; ^+ W- X H0 F: M result[k--]=A[j]*A[j];* U, |: ?3 b! [6 ~- X- K: P, a5 D
j--; ) Y8 J; J" x5 `) b) a# ? } l: @ v9 R& M: ^9 P$ G else4 v# w' F/ m/ T9 Y8 ]
{4 N) Q4 B, r$ Y3 h
result[k--]=A*A;, w, ?* f5 u; L$ g& L
i++;3 |8 r7 |" |3 N/ E( [9 K
}* S A9 {! N% g/ }/ p% u
} 6 {7 i9 C7 ^# I return result; " L i: d8 D$ e4 N( v% [ ( W8 K8 D; S9 w! ]8 k } 6 d. |. q9 X5 o1 z}; ! r) u" ^& Z9 [5 E3 [6 D' n G5 t" m5 Y6 b; p
4.长度最小的子数组8 }7 ?, H# r \( q+ |+ b9 h, A
给定一个含有 n 个正整数的数组和一个正整数 target 。 ! x' N/ F9 Z' `1 ]+ @0 Z2 l$ d' E# ?6 m% d7 i
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。 * j1 n+ F1 |9 ^4 a+ e% I7 l6 ?2 R. f+ h/ _& c) o5 Z, `) g0 \
方法:滑动窗口法7 _1 w" X/ a+ s( T. v; ^- T3 H
8 w; m- f2 F" B. O/ D- g就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。. K* J D# o6 N c" ?3 i3 b
) G% N! O* @+ `
三点重要: 5 Z; U, Y- c" m) ~( u4 j' ?9 Y8 D5 s" c- {
窗口内是什么?3 N$ s. M: a- ?
窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。 8 m; j4 y8 ~7 }# l& B% j如何移动窗口的起始位置? " y" p* y( Y: t; O5 v# m3 N. Q窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了 $ M; w) a& k& ]1 S' ?: b+ o如何移动窗口的结束位置?- t) Z8 [) l7 J+ S
窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。 " p j5 d( R! |4 f' V* ]7 D, n% K3 k* `$ v& b9 ~# o8 |5 K
代码如下 / N5 q# T# R6 g+ ] & J- f. ?; r8 L2 S- C0 Cclass Solution { 0 R0 u1 T4 f6 \- t/ S9 Opublic: " T: [3 {& O3 e int minSubArrayLen(int s, vector<int>& nums) {. {) T+ ^2 P$ d. I5 @# J! r
int result = INT32_MAX;# n4 |" ?* H# Q+ k) K5 y
int sum = 0; // 滑动窗口数值之和 - m9 |4 Y9 q2 b) k- { e$ Q int i = 0; // 滑动窗口起始位置* Q/ j$ F8 V! V! S @5 q: `4 \
int subLength = 0; // 滑动窗口的长度1 `! |& C7 x- Z6 ], d
for (int j = 0; j < nums.size(); j++) {& l+ E" F* k1 M, ^1 ^( z
sum += nums[j];/ Q$ E. A" r% `4 K% y& s' C# y
// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件 # T( I4 r* t3 V( Z while (sum >= s) { ; d/ x5 d) f8 T t! n" A$ D7 w subLength = (j - i + 1); // 取子序列的长度# j! Z b3 k# |) V
result = result < subLength ? result : subLength;//一定会赋值 " l. R3 a- V0 C7 ? sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置) 6 C& b& Q V- a# f } - F" z3 U% I* m* X0 ^4 z3 S } 4 f( ?2 `1 N$ L7 F0 B // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列 6 s1 e3 `8 e) t: Y7 x7 s+ I+ C return result == INT32_MAX ? 0 : result; # n5 A, j. s5 a9 Q! W" `" E } ' e. y: B& S p' E. f6 ^, y}; ?" L7 w! s2 s, ~4 E