QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2066|回复: 0
打印 上一主题 下一主题

数据结构之数组练习

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-8 09:59 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    数据结构之数组练习" j, z3 D+ M. |. E; S4 e( M
    1.leetcode704
    - {% B0 I+ @, c* d给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。; I! y0 l: o/ O2 ?+ U2 [+ Q

    # I2 Q; |1 A, b/ M$ {4 H- J题解:升序 数组: |" M* Z9 J" X% B" h

    - ?5 Z' V$ U6 V方法:   二分法
    + }' F4 m2 A2 t% _: `/ G" ^/ A( S+ c5 |* N$ K: b+ |4 u5 J/ J
    思想:定义查找范围[left,right],初始查找范围为mid((left+right)/2)
    0 o0 K1 u0 S# e6 ?
    8 ^3 ]6 N7 O. {( ~4 b6 ]% {- K9 h比较nums[mid]和target的值:$ u2 Y& H. [6 ^2 v8 N, c
    : B9 M7 I) m" R( h6 K
    如果nums=target,则下标i即为要寻找的下标;
    . z  {- ^% X- {3 J) D: P* V7 M+ \- g) H9 |3 I; m! h
    如果nums[列]> target,则target 只可能在下标i的左侧;
    ! f9 t/ B- J! K  D) d" Q
    0 F) x& t2 S) m4 ~$ C. rclass Solution {
    9 W- r, K/ B7 ~0 v3 e/ D# Zpublic:6 ?' F, D1 C  R6 ?, [- U0 P* t
        int search(vector<int>& nums, int target) {, Z6 q' }" e$ |' i0 O# L
            //区间[left rigth]- ~6 b5 n/ N" |! \
            int left=0;, D" @  a2 G- Q- T/ M% s1 l
            int right=nums.size()-1;+ v" ~, Q6 N8 K  I& |+ E( x
            //结束条件 left>rigth
    ; g1 P2 l" r5 K4 d5 y- @6 |5 m        while(left<=right)8 d8 [& E9 @  q6 Y( o  r
            {* y& j6 z' R, v
                int middle=left+((right-left)/2);//始终保证 有变量 [left,middle]或[middle rigth]
    9 L' R4 |, y5 i' B            //[middle+1 right]# A" E  N$ e+ i. [
                if(nums[middle]<target)
    * y! G  {: g$ R6 g+ g0 t( ^1 _. \- n            {
    % E0 o9 Y5 D! {  Y                left=middle+1;
    5 u- M# r% U- H7 K9 t+ T            }
    ) V( O- o7 H6 N4 K4 \            //[left middle-1]
    ' C5 o8 ~) ^/ R- U8 f* Y% X2 ~/ q# E            else if(nums[middle]>target)
    8 {5 q4 u; J# [9 m( u$ X            {( v% D% T% b( D& }
                    right=middle-1;
    7 m) B. R9 }; |$ A/ @6 R' Y- W. z8 h            }2 \* L  G) k; H, V" j  ?
                else{3 W1 ]( s1 o1 }; b
                    return middle;
    & k4 o4 ~& P7 B% }- i' ]            }$ P: T  i, o, k; g
    ! q* w3 \2 i& A2 S, A# F# z; M
            }5 ?, ~: `+ u6 Z" z5 s" p
            return -1;' L$ Z  P6 K+ [# _
    & P, q: G2 q7 m( v
        }
    3 J- z. I7 M# z0 ]# w  ?9 ?3 z};
    7 C  W  r( a* U& K3 d+ f& _% A
    ' b: Y+ g' H; Q5 r7 @0 R( N注意:' D+ y3 w0 u# [" d# n: W
    3 p# o2 ?5 d, q5 k, Y3 p  b& N  C
    (1)设立区间为[left, right],终止条件为left>rigth
    8 Z' U. v$ [9 Z- p, d( G+ [  (2)   (left + right)/2==int middle = left + ((right - left) / 2)
    * x5 t. L# \. \' n; _/ h# L6 M  (3)    通过改变区间的左右值;复杂度logn4 r$ E  x( J7 {- w
    & {0 s8 ]; s) Q! j
    2.leetcode 27移除元素
    " e* o8 P- `; C' n0 G' n给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
    2 z& _8 V7 S+ R8 V  y+ H
    - [! g. I0 `- T; r7 q2 h: d不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。5 Z# w. l9 K6 l. A4 S1 t* ~- J- Y

    ' E) y) L$ ]" x% ?' z! O8 j元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
    , d/ `" Q! F% g9 S) j+ @1 c" b( _( {; F
    示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。
    4 d0 I2 B% B7 ]( Y7 m, l+ V4 _; m6 n% _# T, V2 H
    示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
    - {8 c7 }/ t* P8 I4 Q. Z5 L+ k7 R. ^' |3 Y/ B% I
    思路:要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
    $ F; e: _# Y) x& l9 b. F2 X# g" q1 C% _, w: f  I9 `) G
    方法:双指针
    + C$ |6 h! @* {0 Q4 ?3 C5 N4 Y8 J9 C8 j4 `; [
    class Solution {2 G. Q! y7 S, U8 y# {. {3 C4 \
    public:
    2 S$ f. I% J% x9 x6 V0 }0 n    int removeElement(vector<int>& nums, int val) {1 m& ?" y" H- E$ _9 ]
               int solwIndex=0;1 a! r8 {5 \; L1 H
               for(int fastIndex=0;fastIndex!=nums.size();fastIndex++)
      f8 m2 p; e% y7 {$ Y           {0 u3 K; u8 U+ y& v8 h4 x
                   if(nums[fastIndex]!=val)
      F3 h4 P  g) X, ]& E1 N               {
    ; o! {! z0 A  f' m+ X1 I& @' n, _                   nums[solwIndex++]=nums[fastIndex];
    $ o: L* Q2 r4 h: `, Y1 q               }
    4 N: `3 R$ e7 o" u. K- y           }" A$ g# m* E* n8 w3 N; ?
               return solwIndex;- C+ R0 K3 E  t/ d: Z; F
        }& z- \" x0 P, c/ J* v1 m
    };
    % H& d. S1 }. P4 hsolwindex:用来覆盖
    ' p; _) w# M2 c  X8 @
      w) _* U7 V7 Q/ E* f, G3 T1 Q4 Sfastindex:来找删除元素++2 b4 V% ~$ {2 Y' ]  e
    & F; A' v, Z- o% ]9 X
    3.有序数组的平方
    . ]* M/ P( N, I" L2 Y给你一个按 非递减顺序 排序的整数数组 A,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。5 N/ d! d1 n# R7 M6 j
    2 \/ u; h& ^# G& E) p
    数组其实是有序的, 只不过负数平方之后可能成为最大数了。
    2 z+ I  N) ]6 \: X  _* t) u& O7 @
    1 R% x8 ]' I) b" Q" E: d" L" x: ^8 `那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。: r8 t3 ~' H. i" A

    , K: \. `2 d6 [# P) n3 T# a此时可以考虑双指针法了,
    6 `5 m3 x3 N, r5 K7 I2 N# ?; U8 p2 \4 V7 C4 W6 [( B3 Y
    i指向起始位置(负数),j指向终止位置(正数)。
    7 ~3 H+ C9 M8 w' q
    ( b$ Z6 e% e/ b7 S: t- z定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。: }4 z" e. y4 \5 b- @
    ) z! |4 G8 q9 U2 d. ~% x
    如果A * A < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。
    , {) o" Q2 ?4 B, Y2 K5 d$ L
    ! g+ }; z; @$ r6 [8 c: t, ?, K9 K如果A * A >= A[j] * A[j] 那么result[k--] = A * A;
    & M; |6 U9 t4 M" B" Y9 ]1 S! V
    * l; f, H% j( r, c, i+ wclass Solution {
    & C& }1 j+ @! G/ ?5 ~public:( q! D6 N% @7 m" z
        vector<int> sortedSquares(vector<int>& A) {" C. _5 k$ d: x
            int k=A.size()-1;
    - L5 y+ }9 n' @& Z+ `' m        vector<int> result(A.size(),0);$ H% z( ?: @1 O" ~$ X1 a
            for(int i=0,j=A.size()-1;i<=j;)
    2 V) ^+ Y* f! j$ r! P3 ^6 [        {
    + E- n, C( C' `9 x( p& r5 Q( _7 e/ [            //遍历一遍! x/ m, S( N* f
                if(A*A<A[j]*A[j])" X6 N9 f8 p( ~3 f
                {( n1 f% I3 _, W. |' c! P
                    result[k--]=A[j]*A[j];
    * @; e, x" U9 q/ g7 t                j--;' t; M3 f) S, {( _" a! @
                }. p: _9 g7 Y3 e
                else
    0 }' u/ V* @; S& {- R            {/ o+ {7 K) t- B! W" o6 u
                    result[k--]=A*A;8 ^3 I* f2 R' h* H+ j
                    i++;& ]* ~$ y* A# d) j1 m3 T( \
                }3 ?- }$ S/ A: a& Q& J" i9 r! V
            }( F; L. P5 S  Z  [# d
            return result;1 d. L* \' V. B6 N2 Z0 T, E

    # [+ u! y: }/ [) U    }: f0 x! D  U! Y* @' e9 \
    };9 _- q( V2 X7 q$ |' n) H5 h

    & J; Y4 e' ~5 V1 o4.长度最小的子数组; C+ F) L+ F/ `1 L2 {
    给定一个含有 n 个正整数的数组和一个正整数 target 。
    5 n6 Z4 f$ K& n  L, t, [# A8 \' R0 |8 {" V
    找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。2 I5 T: D5 L3 x; l' q8 T/ v+ J
    + w  `; S# F* x6 a0 x" U8 p6 v
    方法:滑动窗口法
    - E: Z0 c* I8 q/ }( ^7 A: f8 i
    就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。( D% u3 k9 U7 R

    6 w* D8 {: h7 p7 t3 B三点重要:
    ( E0 I  Z8 ?& W+ z; f% r) a# b7 l1 D
    窗口内是什么?8 Y# ?; `1 c( q: S+ ~
    窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。$ P, h9 H# W, H# W% o2 e
    如何移动窗口的起始位置?
    ) K7 m4 K  s/ o/ t* s6 G窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了
    # J9 L% ^) y4 o" I4 y; `% x0 ?" S2 o* w如何移动窗口的结束位置?5 _) K" s0 t2 m8 ]. Y
    窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
    ) R4 ]' v) u2 c: m- P, p" C; s
    : q% J2 T( }; U- D- V& D) ] 代码如下
    . t, N; d- W9 o. I5 z/ i; }% b3 H( b! s$ d: b
    class Solution {
    2 o* N' k3 X% ^/ _+ K& K4 \public:% \+ h0 d* w) X+ m1 {0 F
        int minSubArrayLen(int s, vector<int>& nums) {# q+ U. _3 s2 A
            int result = INT32_MAX;' Y( Z% X7 M) ?
            int sum = 0; // 滑动窗口数值之和
    ) T5 o( ?' F- f  H9 Z* w; w9 w        int i = 0; // 滑动窗口起始位置8 Z, d1 d7 [3 y1 t9 G
            int subLength = 0; // 滑动窗口的长度: i( Q# z2 F* z7 @
            for (int j = 0; j < nums.size(); j++) {# O+ Z- T/ p# o( v) m
                sum += nums[j];
    ' j% H# h- J6 L* _. K            // 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
    " d  L0 U8 }& o$ O  |6 `3 H* @/ ~            while (sum >= s) {" F1 Z+ [' d; E# h" |- t
                    subLength = (j - i + 1); // 取子序列的长度
    % h. }0 N) ?: A5 A, x, x                result = result < subLength ? result : subLength;//一定会赋值
    ' d# U( _" p( [. ]- X( N                sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
      J( q. o/ v9 g0 X) x            }) s. K6 r- g. ]6 G8 ^) H
            }; D0 Q3 {5 p. ^
            // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列& L6 ]0 \' [+ Q9 k& x
            return result == INT32_MAX ? 0 : result;& ^! I9 B) }9 Z/ f  w
        }
    * w8 E: J  C0 [) ~};. k$ Q% H+ u% C$ S2 t% t% d

    ' I9 A7 _- b1 A- W一旦大于,就减去左区间的值3 q) f+ ?2 C9 i1 b2 o  i' l/ v1 m
      o7 ^: i2 B8 x
    5.最难题螺旋矩阵||
    ! ]. H% d+ O" S! Y% c5 D模拟顺时针画矩阵的过程:
    ) n* u, U# ~  x  V# P$ E  J! a$ d* `( f( Y2 Q
    填充上行从左到右6 [" Y( F% p/ S. W
    填充右列从上到下
    9 ^* ~# ?3 f5 l0 {/ E填充下行从右到左
    & A' q7 e' S4 q, c2 f" k填充左列从下到上
    8 F9 r7 K* p" n! u3 h& U由外向内一圈一圈这么画下去。
    ; _5 T- F, j- H3 Z' z" X8 X* ?
    # B' X+ `+ t3 w/ O' \1 i这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。# S# i% y4 I* v% W
    % m/ c) f$ B- s; c2 m6 t

    - I+ `: q* i1 v7 y$ S7 n; j5 [" z
    0 y1 E7 R; D6 P4 Y* o: {' i7 I' |  g% e0 q! z
    % [; h/ w1 l: M0 ?. L
    class Solution {
    2 {2 K0 A  Q. r" apublic:
    ; ?0 {& r/ C5 i  O. N; ]/ S5 b    vector<vector<int>> generateMatrix(int n) {
    . |& S. V. |( W+ O        vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组9 e, z: E4 H" n/ }5 N( U- f
            int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
    5 E. e2 A0 \+ a) F% d$ N        int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理$ j8 T/ j( I$ F& Z1 p& ^2 Z
            int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)7 ?$ m+ p) F! k0 x1 p' T
            int count = 1; // 用来给矩阵中每一个空格赋值
    ; k! r% i! u$ r, M! q        int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位0 I2 `, e+ c/ M- L% ?, V+ C: Y
            int i,j;( P2 j, g3 Y* F6 Z" E
            while (loop --) {
    4 @  R9 m' q* X+ @& [8 e4 w' l: E            i = startx;
    ! u% C0 J( e6 J1 W, j& j5 }7 g            j = starty;4 V1 Y1 d& b* w+ n- C/ k- y

    ( L2 O$ k! p" C' W            // 下面开始的四个for就是模拟转了一圈. h2 m* j% P- q0 l, u7 J" @$ X
                // 模拟填充上行从左到右(左闭右开)
    , _" C* H. l& [* m: T            for (j = starty; j < n - offset; j++) {
    . u6 H3 O  Y) N' |                res[startx][j] = count++;/ J8 ^7 c% t$ ?
                }
    , B( B- v- ^  {( t8 G            // 模拟填充右列从上到下(左闭右开)2 q4 F- R5 G7 h8 n7 q+ J, H' m; c
                for (i = startx; i < n - offset; i++) {
    : n' I* P5 z% S( |. I                res[j] = count++;
    4 w1 r( @+ _& A3 Y2 A% v            }& r- u* L$ b) K  ?- s
                // 模拟填充下行从右到左(左闭右开)" ]9 ]4 W0 q, X* V
                for (; j > starty; j--) {, n7 a) m  `9 e4 i7 ]: m  {
                    res[j] = count++;
    * y9 W! E# h; [, A7 j            }
    3 j- `5 P$ r: \9 P4 g+ B' _            // 模拟填充左列从下到上(左闭右开). P5 l2 j6 U$ E% z+ K
                for (; i > startx; i--) {7 y; ]4 D# {7 @& [5 |  e( ?0 p( ~* ^
                    res[j] = count++;
    2 `" ?" S4 q8 ?' A0 Q5 b9 u1 }            }% e$ d8 y' C( w/ L. b
    8 v/ W: _8 N8 i4 r6 e- x
                // 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
    . F# e( z+ c$ }' ^) J            startx++;) l6 M# o# I" x3 z8 E
                starty++;
    % Z. [" T0 y8 c: U4 t- I# ~- Q/ D! x# z3 M7 e
                // offset 控制每一圈里每一条边遍历的长度
    5 P5 w3 R4 U( v( P9 P' ?( b. \% x            offset += 1;! n7 ^: Y% G1 I: F2 Q
            }
    3 S: n- w  E7 w5 g. C, k  V
    - @, z5 M5 y0 t" t4 z        // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
    * _  j2 f, t7 j& \' k        if (n % 2) {
    / a9 l0 S* [3 j$ U$ N- d: P+ E            res[mid][mid] = count;
    : B7 i) p- u% h4 G/ s% j        }
    # e3 n' Y6 E* b/ C) _0 f        return res;
    ' O" P8 c, n. U    }' _0 f/ k7 `; V- g4 k2 K" C- p$ T
    };
    5 ?8 [, x6 q9 n! V3 x; K4 G; p) e/ y5 Y; O& ~
    ————————————————
    7 a$ }3 k( n8 o- Y+ \7 H9 @2 p版权声明:本文为CSDN博主「编程界的谢菲尔德」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 C$ f3 r' r& b/ B" _
    原文链接:https://blog.csdn.net/qq_62309585/article/details/1267450396 W# V1 H4 o$ `
    1 I" i7 O" g5 j

    . O# |% A  F# N
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-9-13 19:21 , Processed in 0.333607 second(s), 51 queries .

    回顶部