重拾C++之菜鸟刷算法第一篇---数组

03-07 1530阅读

数组

一、二分查找

知识点:

重拾C++之菜鸟刷算法第一篇---数组
(图片来源网络,侵删)
  • int middle = itBegin + (itEnd - itBegin)/ 2; // 防止溢出

    在 C++ 中,如果两个整数相加的结果超过了整数类型的表示范围,就会发生溢出,导致结果不再是预期的值。

    考虑到二分查找中常用到的 (itBegin + itEnd) / 2,如果 itBegin 和 itEnd 都是很大的正整数时,它们的和可能超过整数类型的最大表示范围,导致溢出。

    而使用 (itBegin + (itEnd - itBegin) / 2) 这样的写法,可以避免这个问题。首先,通过 itEnd - itBegin 计算出两个迭代器之间的距离,然后再除以2。这样,即使 itBegin 和 itEnd 很大,它们之间的差值仍然是正数,不会导致溢出。

    • middle - 1, middle + 1;

      假如有一堆数字牌,从最左边到最右边,这些数字是按照从小到大的顺序排列的。我们要找的数字就叫做 "target"。

      现在,我们先看最中间的一张牌的数字,这张牌的位置就是 middle。如果这张牌上的数字比我们要找的数字 "target" 大,那么我们就知道 "target" 只可能在这张牌的左边,因为数字是按照从小到大的顺序排列的。

      所以,我们把牌堆缩小到左边一半,把最右边的牌移到 middle - 1 的位置。这样,我们就把寻找的范围缩小了一半,继续找。

      这样做的好处有两点:

      1. 防止出现无限循环

      如果有两张相邻的牌上的数字相等且都等于目标数字,我们每次猜中间的数字都不变,就陷入了无限循环,就像玩一个不停的游戏一样。

      2. 提高搜索效率

      如果目标数字比中间的数字小,那就说明目标数字在这张牌的左边。

      题目

      给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

      题解

      class Solution {
      public:
          int search(vector& nums, int target) {
              // 求vector长度 .size()
              int itBegin = 0;
              int itEnd = nums.size() - 1;
              while (itBegin  nums[middle])
                  {
                      itBegin = middle + 1;
                  }
                  else{
                      return middle;
                  }
              }
              return -1; 
          }
      };
      

      二、移除元素

      知识点

      这是一个快慢指针的问题,我想到了这个题解,但是没有想到快慢指针也可以用数字表示。

      反正fast往前冲,slow只有符合条件的时候才赋值往前移动。

      题目

      给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
      ​
      不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
      ​
      元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

      题解

      class Solution {
      public:
          int removeElement(vector& nums, int val) {
              int slow = 0;
              int fast = 0;
              while(fast  
       
      

      三、有序数组的平方

      知识点

      • 双指针 (使用条件,需要构造一个新数组)

        题目

        给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

        题解

        class Solution {
        public:
            vector sortedSquares(vector& nums) {
                vector result(nums.size(), 0); // vector的构造函数
                int begin = 0;
                int end = nums.size() - 1; 
                int Final = nums.size() - 1; 
                while(begin  nums[begin] * nums[begin]){
                        result[Final] = nums[end] * nums[end];
                        end --;
                        Final --;
                    }
                    else{
                        result[Final] = nums[begin] * nums[begin];
                        begin ++;
                        Final --;
                    }
                }
                return result;
            }
        };

        四、长度最小的子数组

        知识点

        • 滑动窗口

          1. 滑动窗口内容

          2. 滑动窗口的起始位置

          3. 滑动窗口的结束位置

          题目

          给定一个含有 n 个正整数的数组和一个正整数 target 。

          找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

          题解

          class Solution {
          public:
              int minSubArrayLen(int target, vector& nums) {
                  int subLength = 0;
                  int result = INT32_MAX;// 记录最大数
                  int sum = 0; // 用来记录子序列总和
                  int i = 0; // 用来记录起始指针位置
                  for (int j = 0; j = target)
                      {
                          subLength = j - i + 1; // 滑动窗口的内容
                          result = result > subLength ? subLength:result;
                          sum -= nums[i++]; // 滑动窗口的起始位置移动规则
                      }
                  }
                  return result == INT32_MAX ? 0 : result;
              }
          };

          五、螺旋矩阵 II

          知识点

          • 不变性原则,规则是具有确定性的(比如开区间和闭区间,如果你决定了遍历都是【闭区间,开区间),那么请仔细确定接下来的步骤也应该遵守这个原则)

            题目

            给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

            题解

            class Solution {
            public:
                vector generateMatrix(int n) {
                    vector Matrix(n, vector(n, 0));
                    int startX = 0;
                    int startY = 0;
                    int offset = 1;
                    int count = 1;
                    int k = 0;
                    int i, j;
                    while(k  startY; j--){
                            Matrix[i][j] = count++;
                        }
                        for (; i > startX; i--){
                            Matrix[i][j] = count++;
                        }
                        k++;
                        startX++;
                        startY++;
                        offset++;
                    }
                    if(n % 2 == 1){
                        Matrix[n/2][n/2] = count;
                    }
                    return Matrix;
                }
            };

            题目整理来自{代码随想录},今天就到这啦~

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]