QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1989|回复: 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
    数据结构之数组练习8 j7 g! |% _" Y7 t+ P5 k9 J
    1.leetcode7043 E  W) M! N" r) d" ]
    给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。: n' J3 k: e  B" k' A/ M- }

    " }4 {) @# Z0 w5 H$ w- @1 a# o题解:升序 数组
    5 Z; b2 ~/ p; X- Y! r' @% E$ b1 M3 U' u9 P
    方法:   二分法
    * r1 }' h+ K- {0 r  |: c+ J2 o/ D' S/ i: S! P6 ^
    思想:定义查找范围[left,right],初始查找范围为mid((left+right)/2): a2 s+ u6 ]0 l) y
    . C# B4 e4 n+ X- Y$ `  E( x5 }
    比较nums[mid]和target的值:8 r3 S9 P+ h8 q9 h% E9 B7 m0 g! Y5 U
    ; ]- i$ J$ ~8 ~" {0 z3 I
    如果nums=target,则下标i即为要寻找的下标;
    ! B3 U$ r: g: ]; g! H: ^/ i. Y% K9 w9 [6 c2 Z3 d, `
    如果nums[列]> target,则target 只可能在下标i的左侧;
    # [' \2 u/ O3 g2 u- i1 F" X- v
    class Solution {
    ' ~& i' k1 {* z3 G2 r" J" \# upublic:; V# y$ K4 j" _5 j% g
        int search(vector<int>& nums, int target) {. ^& a: W$ H: |1 X# s1 y
            //区间[left rigth]  o' O3 W3 B1 M! W$ q# P! ?
            int left=0;
      k- Z. E5 k& H+ U+ B6 [        int right=nums.size()-1;
    ( l; r2 [0 `* \        //结束条件 left>rigth  }8 C4 y2 l/ O6 P: g
            while(left<=right)
    % a( h! s& L" W( A: }        {* Z$ v) F4 C1 }7 C
                int middle=left+((right-left)/2);//始终保证 有变量 [left,middle]或[middle rigth]) S! {9 H2 S4 b2 W1 o* e# z" O
                //[middle+1 right]# X- u; h, U* J# x7 u
                if(nums[middle]<target)
    # r  h# k$ b. E$ ^1 ]3 n            {7 y  C$ p; A+ A2 s) D; I4 f! [
                    left=middle+1;0 e0 Z" t. A& {! L4 e
                }
    , Q5 P5 Z  f8 T& q            //[left middle-1]0 }; r8 w% m% @
                else if(nums[middle]>target)/ G3 E+ u7 \+ H  I. ]4 Y! x" \
                {7 E, k' J* C6 M, K* ~, s
                    right=middle-1;
    9 \6 Q3 M1 M+ t            }
    / R$ z# t( J0 ^) t4 _: H* c            else{
    + b2 ~3 G# R. c1 O                return middle;0 ~7 w5 ]- {' V5 j! {' H
                }, R5 k" Z/ M8 f9 r' C/ a) M- G

    * A9 K+ w- G6 e7 w& O( u        }
    # L3 w' A8 e  E! d$ P8 }; v7 w, G        return -1;
    * w' m2 ~; W1 u5 L1 _" Y' X7 H1 A  d% w1 s
        }0 Z$ @5 b( C6 _3 v! z4 ~
    };
    ! T# L& `, x4 |7 H0 u8 c) R
    4 f8 o. u1 G8 k& J! D注意:
    $ y6 g5 K4 N2 H& Q# C0 U
      i) B  @# o2 t: Q% f+ X4 m/ k(1)设立区间为[left, right],终止条件为left>rigth
    0 P% N9 E, T  I  (2)   (left + right)/2==int middle = left + ((right - left) / 2)
    ' [& V" }7 Z8 X8 w. A  (3)    通过改变区间的左右值;复杂度logn+ o2 c3 I3 n( O. ^8 G1 n! d' C
    7 e8 Z9 w$ x- _4 X8 U; U( |* D
    2.leetcode 27移除元素
      f, c9 m* x7 K给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
    % h8 L. E0 s" j* j2 R/ y5 T" R" |( S2 G3 w
    不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。; {0 C5 o/ s) y5 x2 }: G. G

    * h" _5 ?1 w% Y' m- l, N, b8 R: u2 ~元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
    8 P8 k' M) p. O
    ' f7 r, J; Z+ U' b示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。
    , ?3 x3 x" R+ p! p; G5 Y7 }* J" J& E( H/ A2 p0 f
    示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。3 b3 i- i+ R) b! ~
    : W2 d; E/ b* a0 P- V, j
    思路:要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。5 j: h7 `/ K# w- ]! {9 A

    5 |( V  C5 D  d: T方法:双指针, v8 D. j5 {8 }% _5 u
    ' A$ w% d# y* U# m& {9 Z' g
    class Solution {/ v, S$ _, J. c: i& J
    public:
    $ T/ C% N& S/ H! @& k/ S* C: w# {, J( e    int removeElement(vector<int>& nums, int val) {" h- B4 L, Z( R3 N( z
               int solwIndex=0;
    4 ?6 d6 K0 i: Y; r           for(int fastIndex=0;fastIndex!=nums.size();fastIndex++)& c8 r( Q, D, ~. h# @
               {
    * |) z; f  N) X7 ]0 A7 T               if(nums[fastIndex]!=val), B% _  H9 M1 G3 ?
                   {
    & f# b* b2 N0 O% X; j( c5 b, f                   nums[solwIndex++]=nums[fastIndex];
    $ v3 o" I" g& J# x2 b! `( @               }2 u7 ]- a( L- }  `3 p+ v
               }( J0 [" O- ]8 g& R
               return solwIndex;
      J1 B- B! }3 g; `4 e    }, S- w. c* Y) _& Q* `0 I
    };
    8 X1 _+ L2 t* Y6 O& Y2 @solwindex:用来覆盖
    8 j; \6 {4 g" E1 k5 r" T2 i
    5 @6 z% W! c" zfastindex:来找删除元素++
    / e6 j" v8 b, a7 e! Z! `9 Q- _2 N( E- U& _
    3.有序数组的平方
    & K- |$ }9 _& w% m9 ~给你一个按 非递减顺序 排序的整数数组 A,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
    ! J, ~, U/ E0 t" |8 R% d8 P
    & w4 A6 y' s) R2 A0 B3 V数组其实是有序的, 只不过负数平方之后可能成为最大数了。1 u! V; v$ T* N+ @9 ]! h8 Y  m/ v
    5 h# \& }2 R8 Y0 {7 A  t* w! R. p
    那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。& C' n3 M. F3 n3 x! X

    5 ~  z- Y; s  @+ U此时可以考虑双指针法了,. U" d3 Y: ~8 p4 m5 |; [/ J
    ) J" F  _6 r3 z' V" `
    i指向起始位置(负数),j指向终止位置(正数)。$ X$ ?: }. f. s1 g6 G9 ^- I; G& t
    , j( s" V9 `, R9 n5 M2 _; |
    定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。) d7 a4 ?. N% `! `9 H* C

    8 U: _3 M  H: c' j8 y3 ^: ^如果A * A < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。
    5 d; i5 K* T( `! p
    9 m+ f# j( B5 Y) p如果A * A >= A[j] * A[j] 那么result[k--] = A * A;( G; C7 P- T- P
    $ l, ]2 ^/ t; `3 R/ |
    class Solution {( O, t4 U) Y: U2 u# F: Q/ h+ J
    public:  N& H  N3 g6 X% z$ X' A9 z$ m
        vector<int> sortedSquares(vector<int>& A) {
    0 Z# ~6 r) h# r9 Y& ]        int k=A.size()-1;
    7 o% Q3 @8 c1 g        vector<int> result(A.size(),0);
      |$ Y% A. V0 o5 x6 t5 d        for(int i=0,j=A.size()-1;i<=j;)% C. u1 d, e6 I
            {1 j4 e% F6 u( `: }/ T; T) ]2 Q# Q' M- V
                //遍历一遍
    3 q1 G' ~5 L8 ~9 B) u8 j( O7 I            if(A*A<A[j]*A[j])" q0 g. W2 s; }& F  K8 g/ w
                {2 x" H; c' n% L/ g( B# a1 J7 }
                    result[k--]=A[j]*A[j];
    , x/ o, I- P9 J                j--;# T2 F5 Y9 W6 u
                }
    3 r; P& p) [/ N            else2 @7 l$ N) C9 V+ P# N3 x) A9 A
                {: R' J: _, W  r6 y$ A9 N! k
                    result[k--]=A*A;7 C3 @! R# K1 D! V+ a
                    i++;5 O. b0 \, Q0 h3 \1 M7 C* q( @
                }
    ; t6 Q  @* H) Z& ~- `" X0 Q+ W        }5 d- q  D$ A5 Z& v: n; W! G
            return result;
    $ z* Z/ D5 J; ^% f! f# J
    8 T: g5 V; w0 t" @    }. X' B. E7 \; _; D! Z/ q
    };7 h2 Z' d5 j; P$ g0 w8 A7 S) U; ]
    2 ~/ }: I! D9 r8 h
    4.长度最小的子数组6 H3 y, m# [5 w, L- [; U
    给定一个含有 n 个正整数的数组和一个正整数 target 。2 B6 J3 ~$ t& U% c' I
    4 A. v! p4 K0 S: E
    找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。: b# `9 D( x9 y& W: j, H6 P

    ( X0 g$ a0 L  T) N方法:滑动窗口法
    , v# ^- F  h2 E1 `, I# u; V
    ; ?2 r7 V2 ~# z) d4 |$ d6 w) p就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。1 _* A; b" L" u5 f5 k( g
      D! g% o& H* Y: r* R
    三点重要:' W. s" i+ k; @. f8 F. t+ y* x

    0 Y9 x: {6 n6 {3 r2 ~- `窗口内是什么?
    # Q6 O+ s: c" Q窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。4 n$ n! Z1 h7 L) t, i4 r' W  x4 C
    如何移动窗口的起始位置?2 v, a; q+ u1 k! ?# p% z% Q8 v
    窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了0 y2 q! O6 \# j
    如何移动窗口的结束位置?$ R% `* d. Q0 ~0 t2 K
    窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。6 B. `8 ?2 y+ Q5 B1 P. [/ M5 \7 [

    / v( |, u  e6 j4 p 代码如下
      `1 R. K  D( B  v! @$ y9 d) l$ A0 R0 x0 s( }5 Z+ [( Y
    class Solution {5 [: y) H; @9 V. B" p$ A, [/ f
    public:
    ! O0 c; X/ e5 m& ]" Q    int minSubArrayLen(int s, vector<int>& nums) {
    0 G- R" b5 l$ H6 |  A* B        int result = INT32_MAX;
    : L0 o1 J6 ?9 L& x0 h$ T& Z  z        int sum = 0; // 滑动窗口数值之和# V6 H# h0 h2 ^# C/ p" F9 t
            int i = 0; // 滑动窗口起始位置
    4 T: H+ V" T$ |0 t        int subLength = 0; // 滑动窗口的长度
    7 x- X  B$ i0 H/ b% o        for (int j = 0; j < nums.size(); j++) {
    ; i; l# l3 c; b/ E' q5 P; w$ W; f            sum += nums[j];
    , U1 J4 A+ L+ m; p: N            // 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
    2 E9 }7 G9 @0 [) w' i            while (sum >= s) {
    & s' x0 x3 Q$ @* _/ v                subLength = (j - i + 1); // 取子序列的长度. Y/ I# h% d7 p: \( Y4 V
                    result = result < subLength ? result : subLength;//一定会赋值7 `6 i* d6 x/ t) E# v
                    sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
    * F6 l( v2 H, J            }
      X% W8 S0 B5 t, E        }% x5 ?+ S' \7 X( s* j. E
            // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列0 R2 c0 {; v2 M! V2 L
            return result == INT32_MAX ? 0 : result;
    # o* m6 ?: o9 G! S, L    }: [6 O- j5 P6 O4 m0 s: |; s3 `
    };! a- _! I9 k, d, {1 b% n
    6 L, w/ t! y" O+ O+ o! s
    一旦大于,就减去左区间的值$ X& w0 }& u7 Q8 Y/ G, @# O
    % m+ Q3 O% D8 |. `9 ~- H
    5.最难题螺旋矩阵||
    , A0 y) Q/ l+ N. L. H! u模拟顺时针画矩阵的过程:7 D! Q$ t0 \" U& c7 e# `6 n

    6 ^2 x: W, ^$ Q) y" m9 v& Y' n9 C9 C填充上行从左到右. |4 N$ s( B2 `. y5 d+ n' e
    填充右列从上到下7 d7 `% ^6 E) p/ d
    填充下行从右到左% c) z# h1 J4 m2 ?/ k
    填充左列从下到上! @. u. L1 F9 G4 @' N8 E
    由外向内一圈一圈这么画下去。5 g2 V) T' ^5 f6 j4 W

    6 V& A1 j7 k* W% \! ]1 ?% v这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。" u$ P) [; \2 j* Z

    1 Z3 h, A5 S9 }# w9 ], E
    6 s# r0 W  l0 [* q0 x
    ) M7 H3 z+ u4 g% ~$ k; q7 C: S4 X6 }
    3 [* c7 [, w+ K/ G5 U5 }  L+ A
    class Solution {' G1 V# S9 |9 n: ?  ^
    public:: J1 L5 l- i0 ~2 ~: ?# U
        vector<vector<int>> generateMatrix(int n) {0 e6 H, o/ i. u# |+ ^; `# ~6 r" E
            vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组! o$ T- k7 d, c1 `' ^
            int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
    9 n7 U0 g, o- E/ F        int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
    1 p) k! h* r& S0 s* ?# J6 L; }        int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)7 X9 I2 K1 K; c
            int count = 1; // 用来给矩阵中每一个空格赋值3 }6 g% K3 s" ]+ F8 _  x
            int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位- v# V( P& j2 w* h$ x3 X  N
            int i,j;
    7 `( m  q- @- E1 [+ r, K        while (loop --) {
    / n5 h: q+ P7 w# R: x0 T$ B            i = startx;( U- d# [$ T/ R7 X
                j = starty;+ a/ J/ c0 B. I: h, t; R

    4 w0 n+ n: s" y4 L, X. _5 ^- z! R            // 下面开始的四个for就是模拟转了一圈3 D! v" D2 E' D6 z1 k2 w0 k* O
                // 模拟填充上行从左到右(左闭右开)
    ) Q+ H' s+ D* B2 }' {            for (j = starty; j < n - offset; j++) {9 j* T7 T) \( |- e- L- z2 U8 N
                    res[startx][j] = count++;" l# I& t  X; V( H
                }* s/ y% Q; d8 }9 {
                // 模拟填充右列从上到下(左闭右开)0 h* P$ M5 ^2 E$ t8 J
                for (i = startx; i < n - offset; i++) {
    / F' \- v& g$ S8 P6 L. M7 w                res[j] = count++;
    6 T- `3 Q# S% n" [7 T5 c            }
    8 q- F% u: A5 w7 E" r# \4 [            // 模拟填充下行从右到左(左闭右开)- ~. M: ?; x! J
                for (; j > starty; j--) {
    0 i, B% V% [0 c                res[j] = count++;
    , g5 b! ~" o* ]2 V0 N& ~- d            }0 y/ v; ?- g7 b2 }6 b* S
                // 模拟填充左列从下到上(左闭右开)2 T, L6 Y6 u9 ^) K. F
                for (; i > startx; i--) {
    + @# W6 e  }# F  a$ a: S" |% U, o& [                res[j] = count++;: s' I$ f6 v. d7 a
                }" G. i' g1 `* t. b/ V

      n* ~7 ^. |4 g  ?" E. `( O. B            // 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1). v! K7 [1 M6 S& [$ B( z' a' C; f: y
                startx++;
    0 m, ?3 ~& v. h1 Y; M8 Q2 a# }            starty++;
    % t) n' w7 u) p, U; Y, w# _+ p
    + M) ~. c' a, a! U            // offset 控制每一圈里每一条边遍历的长度
    7 P# [: s" H2 }            offset += 1;
    5 @- ]8 b3 F/ Y# t8 a+ h# K0 p9 {        }; _& V5 b& ^, Z, j" K' U( _

    & Q1 c9 w3 x; z        // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
    ! `. n8 x8 V; b/ M        if (n % 2) {
    6 Y0 m; j8 P& t3 M            res[mid][mid] = count;
    ( ?+ C3 w8 b( O. l# ^1 o        }  J6 n& b9 Z! a* ]- L! _4 @: j
            return res;
    & p+ q  a1 r4 m5 K3 }6 S    }! ~, x& n& N0 A7 L4 b  E
    };
    % ?( r! e( T" q7 {1 @" i
      }7 f' Q! m7 _' P" [9 \2 t/ Q————————————————
      y; s( _  C4 E, L; _  g# [版权声明:本文为CSDN博主「编程界的谢菲尔德」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    7 d7 R: R. a; M/ j  {! v7 o原文链接:https://blog.csdn.net/qq_62309585/article/details/126745039
    4 a+ E% {' L0 B+ {4 ^' O# L7 W
    6 {  c  E" i: z8 U+ q# J' d
    ! y: a# a# n, c' H) b
    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-4-11 13:00 , Processed in 0.384035 second(s), 50 queries .

    回顶部