- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565641 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174915
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
数据结构之数组练习
" E0 H, E( q% V1.leetcode704
/ Q& @+ a- Z) B3 D4 x: z( d1 Y/ h给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。, d/ q2 U5 U- \ e, H' [
$ P$ L# E3 A1 s$ U& g/ j2 o2 v. {题解:升序 数组
) f0 y6 G4 V4 K C4 \9 P
/ v( S+ P7 @6 E: k) u) V7 i/ d% [方法: 二分法
- ?; K! {9 H" d5 L" r3 M/ R; G# P; v$ d, N
思想:定义查找范围[left,right],初始查找范围为mid((left+right)/2)
& S+ o, \. {/ ~8 v) c) I5 M3 `8 V- g' u9 d, z# e6 y* b, g
比较nums[mid]和target的值:6 K2 C) s: C$ ~! o, ]+ Z+ z
1 U" V, u- q6 }3 D' X8 a如果nums=target,则下标i即为要寻找的下标;
, l' n- S+ C9 q/ Z0 N* `8 H) T3 ?: v; z- A: B' }
如果nums[列]> target,则target 只可能在下标i的左侧;3 b% I* g' Y1 F8 K! X7 G- j
5 N7 f3 [/ e9 ]4 U2 Lclass Solution {
% N! W2 C& r) {" g' [. c# Opublic:8 h. L( {* Q8 O+ |
int search(vector<int>& nums, int target) {
6 t) a" P+ O$ r //区间[left rigth]; ^9 N+ m$ `8 V1 a8 r2 t
int left=0;
: i, u0 S0 D9 T5 Z) S5 Y' q int right=nums.size()-1;6 K( d( w. \1 \5 g) s
//结束条件 left>rigth' e7 W0 [7 y+ a$ T$ |/ Q7 C
while(left<=right)
9 N* c( w3 c* E4 J$ {9 \; A {* T& `; i$ }3 j& |1 ~
int middle=left+((right-left)/2);//始终保证 有变量 [left,middle]或[middle rigth]- s% T8 w3 d, P: p/ J
//[middle+1 right]
1 J) ? M% p2 @9 ]* E1 w# `1 S# Z if(nums[middle]<target)
. { s, O% K: a; i% j# u {2 \8 b M" p% {8 v/ G
left=middle+1;
/ A1 |# E8 C( a `- k. b# Q }
& M9 _7 Z( U( R //[left middle-1]
! I+ }+ c1 F. t* E) p3 C1 C8 Y else if(nums[middle]>target)' F, z r2 f4 c( O9 h, n
{
+ O# `1 T w. R. e% i# R right=middle-1;
3 K9 G; G8 S2 {8 f; P: U5 K. A }
8 y) D! P) K1 R% v5 S; ? else{
. a' ^% g) k. f2 ~! ?1 s1 B5 Q return middle;
0 O3 J% E) x2 G' w4 _ }
0 o. {: M3 P/ F0 Y5 u" ^( | l& @
$ P1 L3 ]0 a8 B) u+ o }
# {9 O( ]( E$ i. V. g+ O return -1;: n) p, } |# a7 M5 G
' i, U) n# c! f4 J }
0 e1 k" L' s2 X4 y& h};( [# k5 L0 D5 _6 k$ r6 ~
! Y% B1 Q: h* J4 S
注意:3 f9 i6 R% g" B- L, T
$ |) J4 B* H/ x" c7 x0 O" T0 h
(1)设立区间为[left, right],终止条件为left>rigth3 r; W- m1 }& l' r* K
(2) (left + right)/2==int middle = left + ((right - left) / 2)8 m0 f& d9 V) F5 Z" k! E
(3) 通过改变区间的左右值;复杂度logn! G1 Z- s8 a: N' C! `8 |0 r
3 x% w) e. J% Y1 \& {' Y B6 @
2.leetcode 27移除元素
* g/ S3 m/ j7 Q7 q( d" s6 @给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。5 x% U& w' T I' ^) q
2 a+ _/ a, C" f& ?" d7 @( D
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
; F' y, e# a6 c" t3 f' F) `0 J/ k# o4 I5 M- P% i
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
* z" M* B: v6 i5 W) u. {* \% @" z
) v& C6 u3 K0 y$ G; j示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。! H" T& C9 H* l' z5 V! e
/ p+ ^# N, \% {% T; c0 j" \示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
; I+ \; b# @- K5 w+ ? @6 g! m# o3 E# H6 [
思路:要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。. J- _* e G3 y. k! z) J
/ ~8 u& G; j7 c1 e! G# Q& l$ L
方法:双指针
; V& ^. Y5 ~ D8 J3 g, R
9 E4 p& M' d9 N% ]* L6 M( V% V4 `' jclass Solution {% C; j+ L U0 w- Q9 E; p8 O
public:1 k+ V: o: D A" ]# Q
int removeElement(vector<int>& nums, int val) {0 E$ j$ |; T3 B2 O. P2 C
int solwIndex=0;" Y+ K# F7 c0 M( ?1 w2 {
for(int fastIndex=0;fastIndex!=nums.size();fastIndex++)
" B3 Z7 m2 M* V8 p6 j; w0 S {
0 G& d" {" a }$ P if(nums[fastIndex]!=val)! V8 G) U2 L, S* A4 O5 }+ L7 p
{
) |; e4 ?9 |9 ? nums[solwIndex++]=nums[fastIndex];4 y( o* W, y: c: ]& a7 m. v+ H1 H
}
6 f% k* ^) C4 `0 y }7 ^% j5 A4 D5 \3 |) f
return solwIndex;& Z1 o% t6 Z3 D' g k, S
}
" z4 {0 X& U5 ]};# U: a. J/ T4 x
solwindex:用来覆盖) {4 h7 Q, S4 c! k
) k4 U# w, j9 S: K' D9 g- Vfastindex:来找删除元素++
! M. B7 q7 B6 z6 Y+ \" @8 c+ J+ J$ L# D+ [. s# ^5 w
3.有序数组的平方$ D. E0 ]7 S$ r# L% Z4 B- @
给你一个按 非递减顺序 排序的整数数组 A,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
( m' }/ _8 c) G' V- M* z& k, x+ U7 o% e* [7 ^5 G I- ?
数组其实是有序的, 只不过负数平方之后可能成为最大数了。- l" A" l# q# N8 V8 C
& \3 ~' c6 O7 j
那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。% r$ n$ G4 Z8 O9 {( y# r# u( [- O
/ p; R7 ]6 S! V r$ N
此时可以考虑双指针法了,- Z: }- m r2 q1 V8 \ c
1 a0 f5 z Y7 C" ~# @) Z9 ki指向起始位置(负数),j指向终止位置(正数)。
m0 s" [3 }7 p& `3 p6 a0 L y
- w/ F3 R0 ~) [" l# C. `定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。5 }7 h {2 f9 [8 L4 g0 Z; X
+ v P! y8 z/ o" S9 p- d如果A * A < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。
$ y o+ z5 G) u0 @& ?2 C3 @6 A9 |3 {
如果A * A >= A[j] * A[j] 那么result[k--] = A * A;
; L, n" C; p4 d& J3 Z
9 T1 L4 A6 ^) V. M. v7 Fclass Solution {
% S' \0 G/ W+ m/ c4 y0 f& mpublic:" V5 Y! Q7 U/ l4 H, ] J/ t
vector<int> sortedSquares(vector<int>& A) {
! |# q. x" T5 ~/ W5 D int k=A.size()-1;
' J. d! ^- @2 u# L( G vector<int> result(A.size(),0);& C1 [$ M9 t1 ?
for(int i=0,j=A.size()-1;i<=j;)9 _# ?4 O |6 l' K
{7 o9 p6 a+ H+ a
//遍历一遍
8 p! K1 {. P" R1 o if(A*A<A[j]*A[j])
& N: Z0 X/ N9 L+ D {5 W1 ~' d" l6 w6 v7 W1 d$ F+ D/ K
result[k--]=A[j]*A[j];
& x& V+ e( `: I; y j--;+ ?( a/ p2 ]/ q" F5 ^
}
- \! x6 ~" |$ ~ else
: {$ B& K _+ N& E& k) [) c {
4 f+ ?% H d+ r2 e result[k--]=A*A;
9 }/ ^% P, m/ k6 j- c, A7 N i++;
* F# b& T0 e% j5 _" `' {% ~; e }
' A- R0 z; o4 p }
/ F- w$ z5 H, T' s- e return result;' N. d! l/ S. \& x- ~% L
+ K& G: L/ f" R- @+ y
}
; a6 V3 n* l3 w3 t};* T$ U' J( o: J( l
; y I! H- p% z# Y
4.长度最小的子数组
- k) H% Z9 y0 z' h, V+ P给定一个含有 n 个正整数的数组和一个正整数 target 。: h' d& W. A- s% i
% K2 d) |# F/ ^5 d, f9 Q' r; z @: s找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。1 S4 j) D3 j) m6 x
% H: j5 O, _2 p M* N, x方法:滑动窗口法
3 s; D5 @6 \4 M6 o9 Q# e
0 b" V- y* x6 P就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。* N& v7 y" a; p. o- n. R
$ x* f/ y5 P$ H- _6 B三点重要:
9 F! r/ Q) Z( P0 F$ {4 j( s
1 H9 H- k, {: z# J; y9 D窗口内是什么?
* o4 f8 m* D/ } L, Q窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
O- n! y8 a+ n4 F' k, D如何移动窗口的起始位置?; H: a. G+ W7 O2 Q/ F0 n" i
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了$ W& _; D: r3 o: t, s% t
如何移动窗口的结束位置?
8 d; t- ~/ S+ U/ H) v; G窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
( A6 H9 O6 k6 D9 o% y9 y7 s& I/ r' o8 C
代码如下$ f$ D: b8 c" V" W+ W/ e
4 W5 T& {8 z2 T- G* |& wclass Solution {
- V& F8 G0 h8 O( p& R m# ~public:7 {) Z. w* e- w" u" J
int minSubArrayLen(int s, vector<int>& nums) {
1 g5 k1 w2 e# H int result = INT32_MAX;4 P" p5 X. a1 k8 O" M6 G
int sum = 0; // 滑动窗口数值之和 N) U7 J8 z5 T! j
int i = 0; // 滑动窗口起始位置2 R! \! e# N, ]9 k' t6 u5 `
int subLength = 0; // 滑动窗口的长度. P5 h* ~( D, i3 L1 M
for (int j = 0; j < nums.size(); j++) {
* x v) K1 U. d+ T) n sum += nums[j];1 p/ m7 H; {0 X/ E1 Q& ^
// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件' ^0 }8 ~4 n7 b: I' N& d
while (sum >= s) {
( I$ N1 O: g0 C6 j. s4 { |, d subLength = (j - i + 1); // 取子序列的长度
/ Z( E0 k/ C7 c( u+ Z5 X# a result = result < subLength ? result : subLength;//一定会赋值
" [+ q# v' F4 `3 }- D% u sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)) R: ]% E3 E3 v* {, ?
}
; N4 ?1 d2 t k D% h }
( `/ O! B% T4 U( {9 j9 T X5 _/ s/ _ // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列: Z* f5 A1 D9 g( z& k' @) Q- \$ S
return result == INT32_MAX ? 0 : result;
1 A4 B( D L* ]& N. s$ p }( e6 N" s8 R2 ~5 D Y
};
& l% M3 _4 W! w' @8 r& |1 d0 r
0 M! |! M! G7 y3 A% @) A( C8 K4 Z# A一旦大于,就减去左区间的值
5 k: h- v2 e, k; u) ]0 |: @' C1 P% @- g# ]# Y. h, M2 Q) u' ]9 `
5.最难题螺旋矩阵||; `1 H/ [) t K( D' S/ F
模拟顺时针画矩阵的过程:- i9 U, M( n0 Z# S/ Y8 F ^8 d
$ P. u0 v- ` x o _. x填充上行从左到右4 s4 v! d- x, H# G7 V* F& I
填充右列从上到下8 B# r/ ]: N+ J4 Y
填充下行从右到左
" k0 n3 C H0 [( {) C填充左列从下到上
# U# k7 u7 c' F, l由外向内一圈一圈这么画下去。
I; @4 d" y& A% D9 T1 Y' y8 F8 B4 ^ Z# n* I+ y! D
这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。: ?! e4 T1 h. _0 t7 p
8 U3 c6 \1 O! Y0 Z
# N9 z. j+ W g: j
0 G6 o2 I1 h7 N+ V" B' u$ [1 |( [8 o7 q& k* Z2 }( A5 f7 S
J5 g3 A3 d% P d
class Solution {
# H8 {# Y' o! |4 M! W' E) a& Xpublic:; A5 H$ B# A/ v2 Y& l$ f
vector<vector<int>> generateMatrix(int n) {
; M0 e/ X: K2 j1 k4 B- ] vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组. L; H$ {# ?( i, k9 v; v( H D
int startx = 0, starty = 0; // 定义每循环一个圈的起始位置: j9 U, _9 H( k; P$ P
int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理0 [: e; ^1 x8 Q3 @
int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)# ~ e* B C% z# n
int count = 1; // 用来给矩阵中每一个空格赋值- i" u0 N! J2 B$ T: u% x# @
int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
5 i8 }4 } A" q X( R/ x# V- H int i,j;) _7 f: m$ p# _) r" A6 @
while (loop --) {; k' h: X, l) X6 @ n
i = startx;6 u ~5 \* a) {( K3 @2 X
j = starty;
: Y/ E+ x" h. J0 G f$ n( w" S; K4 `* v. C) d! j; W
// 下面开始的四个for就是模拟转了一圈
3 `% E6 s3 ], q7 a/ R4 f- r3 N0 k) N // 模拟填充上行从左到右(左闭右开)
2 \$ Y8 T2 y3 @/ R- M: i) d for (j = starty; j < n - offset; j++) {
& y$ @0 l& r6 [# p- L res[startx][j] = count++;- C7 w1 G' W p4 P* o: S; M) u
}
* c& A' F$ A3 W' f // 模拟填充右列从上到下(左闭右开)7 I3 ^; X2 A( [/ h6 e; w' f/ R
for (i = startx; i < n - offset; i++) {
* P' k" H& P0 c, s0 l res[j] = count++;: C3 Q, K _4 ^0 @. `# Q
}
J6 G, H h% x // 模拟填充下行从右到左(左闭右开)
- X7 r- y7 ~; p2 ^9 G+ C for (; j > starty; j--) {
5 F# Z7 M. x) c6 M3 z res[j] = count++;
" J- r0 f9 e3 L; \; u) x }, D6 W6 D" \6 r4 M
// 模拟填充左列从下到上(左闭右开)
7 K* \% s4 g5 ]" D for (; i > startx; i--) {
* s* _+ A) `2 G" ^; q" T res[j] = count++;
6 a' u( }' f: N/ x+ d4 b3 m# ` }
$ e) ?/ t: z' p* E% e- V6 b6 M8 f2 v
// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
' Q+ r* B; n* r; S3 }1 \/ w" _ startx++;
3 ?% o) ^$ {5 F3 U5 ?3 w: C" E5 b starty++;! a7 l( b! t3 a. L! X9 m
1 d/ u1 Y$ r1 L% ]8 w# ] // offset 控制每一圈里每一条边遍历的长度3 L7 F$ z2 h6 X8 [! M: O- d
offset += 1;
8 ~4 M! C* L2 l& i8 h1 Y }! N+ F8 _ N- m0 f3 n
7 Q E5 f1 ?9 c, r6 N1 D1 U# M // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
. B! l% R: k5 x3 S* A5 f if (n % 2) {3 v# c' V( l# m# [
res[mid][mid] = count;
$ z" A. F( ^" p8 d `% k2 y }
) r, N1 [# z6 H0 B3 q3 J( t% Z; n( X return res;
/ |1 n' u' ?6 ?# ?; D q5 o }# {6 a6 M6 @' ]8 z6 D
};" L0 Q! W" s5 e; p* g
/ I: a- T* ]& e% C6 q3 y# L1 _
————————————————
2 m# D8 F. k0 s* w版权声明:本文为CSDN博主「编程界的谢菲尔德」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
2 l! g5 l" O' p原文链接:https://blog.csdn.net/qq_62309585/article/details/126745039
5 V+ G6 P& F; [$ l5 y$ v; {' K; h+ R
. {' ] m- ^. b- D" X4 [
|
zan
|