LeetCode 解题笔记(二)数组篇

2023-05-16

文章目录

  • 一、基础篇
    • 26.删除排序数组中的重复--2022/01/16
    • 122. 买卖股票的最佳时机 II--2022/01/17
    • 189. 轮转数组--2022/01/18
    • 217. 存在重复元素--2022/01/19
    • 136. 只出现一次的数字--2021/12/14
    • 350. 两个数组的交集 II -- 2022/01/12
    • 66. 加一 -- 2022/01/20
    • 1.两数之和(2022/01/20)


总目录:      LeetCode 解题笔记(一)总


一、基础篇

26.删除排序数组中的重复–2022/01/16

链接: 26.删除有序数组中的重复项

题目: 简单
在这里插入图片描述在这里插入图片描述

标签: 数组、快慢指针

题解: 逆向思维!判断每一个不相等的数,并计数,答案就出来了!!!

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.size() <=0 )
            return 0;
        int c = 0;
        nums[c++] = nums[0];

        for(int i=1; i<nums.size(); i++) {
            if(nums[i] != nums[i-1])
                nums[c++] = nums[i];
        }
        return c;
    }
};

官方

思路: 快慢指针

定义两个指针 fast 和 slow 分别为快指针和慢指针,快指针表示遍历数组到达的下标位置,慢指针表示下一个不同元素要填入的下标位置,初始时两个指针都指向下标 1。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int n = nums.size();
        if (n == 0) {
            return 0;
        }
        int fast = 1, slow = 1;
        while (fast < n) {
            if (nums[fast] != nums[fast - 1]) {
                nums[slow] = nums[fast];
                ++slow;
            }
            ++fast;
        }
        return slow;
    }
};

122. 买卖股票的最佳时机 II–2022/01/17

链接:122. 买卖股票的最佳时机 II

题目: 中等
在这里插入图片描述
**标签:**数组、动态规划、贪心

我的答案:

思路:暴力解法,考虑边界条件,然后试错得出,效果还行:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int minp = prices[0], maxp= 0;
        int sum = 0, n=prices.size();

        for(int i=1; i<n; i++) {
            if(prices[i] <= prices[i-1]) {
                if(maxp) {  
                    sum += maxp - minp;   //存在了最大利润了,并且这次又是新的最小值买入时机
                    maxp = 0;
                }
                minp = prices[i];         //最小值买入时机
            }
            else {
                maxp = prices[i];             //保存当前的最大利润
                // minp = prices[i-1];        //不需要的,试错出来的
                if(i == n-1) { 
                    sum += maxp - minp;       //最大值结束的话,得计算一遍
                }
            }
        }
        return sum;
    }
};

时间复杂度:O(n),其中 n 为数组的长度。我们只需要遍历一次数组即可。
空间复杂度:O(1),只需要常数空间存放若干变量。

参考答案:

看动态规划比较累,看这个贪心太舒服了:

https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/solution/tan-xin-suan-fa-tong-su-yi-dong-de-ti-ji-avcz/
在这里插入图片描述

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int res = 0;
        for(int i = 0; i < prices.size() - 1; i++)
            if(prices[i + 1] > prices[i])
                res += prices[i + 1] - prices[i];
        return res;
    }
};


189. 轮转数组–2022/01/18

链接:189. 轮转数组

题目: 中等
在这里插入图片描述
标签: 数组

我的答案: 最容易想到的:建立个临时的数组

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        if(nums.size() == 0) return;
        int n= nums.size();

        vector<int> tmp ;           // vector<int> tmp = {0}; 这样初始化就已经添加了一个值
        for(const auto& num: nums){
            tmp.push_back(num);
        }
        for(int i=0; i<n; i++) {
            nums[(i+k)%n] = tmp[i];
        }
    }
};

官方:若干答案,后续补充…


217. 存在重复元素–2022/01/19

链接:217. 存在重复元素

标签: 数组、排序、哈希表

题目:
在这里插入图片描述

我的答案:

**思路:**应该是最快的一次呢,排序+遍历判断就好!

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        int n = nums.size();
        if(n==0 || n==1) return false;

        //快速排序
        std::sort(nums.begin(), nums.end());
        for(int i=1; i<n; i++) {
            if(nums[i] == nums[i-1]) return true;
        }
        return false;
    }
};

官方:

思路:哈希表,对于数组中每个元素,我们将它插入到哈希表中。如果插入一个元素时发现该元素已经存在于哈希表中,则说明存在重复的元素。

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        unordered_set<int> s;
        for (int x: nums) {
            if (s.find(x) != s.end()) {
                return true;
            }
            s.insert(x);
        }
        return false;
    }
};


136. 只出现一次的数字–2021/12/14

标签:位运算、异或
题目:136. 只出现一次的数字
在这里插入图片描述

思路:

异或特性(异或是找不同!):
① 任何数与0异或,都是它本身
② 任何数与自身异或,都是0
③ 满足交换律、结合律

所以两个一样的数都可以消掉,然后单独的数与0异或

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret = 0;
        for(const auto& num: nums) {
            ret ^= num;
        }
        return ret;
    }
};

350. 两个数组的交集 II – 2022/01/12

题目:350. 两个数组的交集 II
在这里插入图片描述

标签: 数组、哈希表、双指针、二分查找、排序

方法一:我的思路: 先排序,后用双指针…

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        if(nums1.size()==0 || nums2.size()==0) return {};
        
        //先排序
        std::sort(nums1.begin(), nums1.end());
        std::sort(nums2.begin(), nums2.end());

        int i1=0,i2=0;
        int n1 = nums1.size(), n2 = nums2.size();
        vector<int> ret;
    
        //双指针
        while((i1!=n1) && (i2!=n2)) {
            if(nums1[i1] < nums2[i2]) {
                ++i1;
            }
            else if(nums1[i1] > nums2[i2]) {
                ++i2;
            }
            else {
                ret.push_back(nums1[i1]);
                ++i1;
                ++i2;
            }
        }
        return ret;
    }
};

方法二:参考官方的哈希表方法后写的:

1636 有点相似

首先遍历第一个数组,并在哈希表中记录第一个数组中的每个数字以及对应出现的次数,然后遍历第二个数组,对于第二个数组中的每个数字,如果在哈希表中存在这个数字,则将该数字添加到答案,并减少哈希表中该数字出现的次数。

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        //调整为 num1 为短的数组, 高级技巧
        if(nums1.size() > nums2.size()) {
            intersect(nums2, nums1);
        }
        
        //添加 num1 到哈希表中, 键-值类型,且无序的,用 unordered_map
        unordered_map<int,int> map;
        for(const auto& num: nums1) {
            ++map[num];            //不用指定多大空间的?
        }

        unordered_map <int, int> m;
        for (int num : nums1) {
            ++m[num];
        }

        //判断 num2 中
        vector<int> ret;
        for(const auto& num: nums2) {
            if(map.count(num)) {  //判断键有木有
                --map[num];
                if(map[num] == 0) {  //减到了 0 了
                    map.erase(num); //删除之
                } 
                ret.push_back(num); //添加一次
            }
        }
        return ret;
    };
};

66. 加一 – 2022/01/20

链接:66. 加一

题目: 简单
在这里插入图片描述
标签: 数组、数字

我的答案:

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int n = digits.size();
        if(n==0) { return {}; }

        bool carry = true; //最高位进位

        for(int i=n-1; i>=0; i--) {
            if(carry) {
                if( digits[i] == 9) {
                    digits[i] = 0;
                    carry = true;
                }
                else {
                    digits[i]++;
                    carry = false;
                }
            }
        }

        if(carry) {
            vector<int> ret(n + 1);
            ret[0] = 1;
            return ret;
        }

        return digits;
    }
};

!官方的答案复杂了,不贴了

参考网友的,很简洁,就发现我的 array 很没必要!

public int[] plusOne(int[] digits) {
      int n = digits.length;
      for (int i = n - 1; i >= 0; i--) {
          if (digits[i] == 9) {
              digits[i] = 0;
          } else {
              digits[i] += 1;
              return digits;
          }
      }
      int[] ans = new int[n + 1];
      ans[0] = 1;
      return ans;
  }

1.两数之和(2022/01/20)

链接: 1. 两数之和

题目:
在这里插入图片描述

标签: 哈希,数组

思路:

我的暴力解题

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    	n = nums.size();
        for(int i=0; i<n ; i++) {
            for(int j=i+1; j<n ; j++) {
                if(nums[i] + nums[j] == target)  {
                    return {i,j};
                }
            }
        }
        return {};
    }
};

我的双指针:(错误答案)

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        //1.排序
        std::sort(nums.begin(), nums.end());
        
        //2.双指针
        int left = 0, right = nums.size()-1;
        vector<int> ret;
        while(left < right) {
            int t = nums[left] + nums[right];
            if(t == target) {
                ret.push_back(left);
                ret.push_back(right);
                break;
            }
            else if(t < target) {
                left ++;
            }
            else {
                right --;
            }
        }

        return ret;
    }

然而,是要返回数组的下表的,所以此方法不适应,考虑哈希才是最快的! 用哈希的 count 方法

map.count(Key) 返回值为1或者0,1返回存在,0返回不存在

网友答案:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int> _map;    //        unordered_map<int,int> _map; 都行
        vector<int> b(2,-1); //用来承载结果,初始化一个大小为2,值为-1的容器b

        for(int i=0; i<nums.size() ; i++) {
            //从第二个数开始寻找哈希表中是否有对应的 key
            if(_map.count(target-nums[i])) {
                b[0] = _map[target-nums[i]];
                b[1] = i;
                break;
            }

            //第一次的时候,反过来存入键值,为了count函数
            _map[nums[i]] = i;  //第一次存入了 (3,0) 第二次(2,1)
        }
        return b;
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode 解题笔记(二)数组篇 的相关文章

  • Docker 服务端口一览

    最近研究微服务 xff0c 使用Docker来进行部署应用 说实话docker是个好东西 xff0c 只要编写好Dockerfile文件和docker compose yml文件 xff0c 便能快速启动并运行相关服务 调试过程中查看服务可

随机推荐

  • 鱼眼镜头的成像原理到畸变矫正(完整版)

    最近刚接触鱼眼相机 xff0c 发现网上资料还是比较零散的 xff0c 于是把搜罗到的资料汇总梳理了一下 这里推荐大家直接看链接6的论文 xff0c 从成像模型到畸变矫正整个过程讲的比较清楚 xff0c 网上很多版本其实都是根据这两篇论文来
  • STM32通过广和通ADP-L610-Arduino进行TCP/IP通信

    STM32通过广和通L610进行TCP IP通信 一 写在前面 本次参加嵌入式大赛 xff0c 使用了广和通的ADP L610 Arduino板子进行通信 项目要求大概是本地上传数据到服务器 xff0c 服务器接收后发送给客户端 xff0c
  • Visual Studio Code Git版本控制 更改语言成英文

    一 初始化git库 新版vscode只能打开一个文件夹 xff0c 当你打开这个文件夹后 xff0c 再点击左边的git控制按钮 xff0c 就会初始化该文件夹为git工作目录 xff0c 如果已经有git控制 xff0c 则不会改变 在v
  • STM8S003F3 开发环境搭建

    硬件相关 芯片介绍 型号 xff1a STM8S003F3P6 xff0c 用的不是ARM内核 STM32用的是ARM xff0c 而是意法半导体自己生产的高性能8位内核 xff1a STM8AF 主要针对汽车电子应用 xff0c 如 xf
  • 教你写Makefile(很全,含有工作经验的)

    原文 转载文 Makefile 值得一提的是 xff0c 在Makefile中的命令 xff0c 必须要以 Tab 键开始 什么是makefile xff1f 或许很多Winodws的程序员都不知道这个东西 xff0c 因为那些Window
  • 与JWT的不解之缘

    jar xff1a maven lt dependency gt lt groupId gt io jsonwebtoken lt groupId gt lt artifactId gt jjwt lt artifactId gt lt v
  • 连接服务器报错:Key exchange was not finished, connection is closed.

    解决方案 xff1a 在 etc ssh sshd config最后添加如下行内容解决问题 KexAlgorithms diffie hellman group1 sha1 diffie hellman group14 sha1 diffi
  • ros多线程管理

    单线程Spinning ros spin 是最简单的单线程自旋 它会一直调用直到结束 用法 ros spin ros spinOnce 另一个单线程spinning是ros spinOnce 它定期调用等待在那个点上的所有回调 用法 ros
  • (每日一读2019.10.24)一种基于通用优化方法的多传感器全局里程计估计框架(VINS-Fusion)

    参考博文 萌新学VINS Fusion 一 特征跟踪 萌新学VINS Fusion 二 特征跟踪 摘要 精确的状态估计是自主机器人的一个基本问题 为了实现局部精确和全局无漂移状态估计 通常将具有互补特性的多个传感器融合在一起 局部传感器 摄
  • (每日一读2019.10.25)一种基于通用优化方法的多传感器局部里程计估计框架(VINS-Fusion)

    摘要 为了提高机器人的鲁棒性和自主性 越来越多的传感器被安装在机器人上 我们已经看到了不同平台上安装的各种传感器套件 例如地面车辆上的立体摄像机 手机上带有IMU 惯性测量单元 的单目摄像机以及空中机器人上带有IMU的立体摄像机 虽然过去已
  • Gazebo模型下载以及配置--解决Gazebo黑屏原因

    前往ExBot ROS专区下载Gazebo模型 https bitbucket org osrf gazebo models downloads 下载后把文件放在 gazebo下的models文件夹中 span class token fu
  • 相机内外参数以及畸变参数

    关于大佬们的一些见解 下面是引用知乎的一段文字 xff1a 我们从单目视觉说起 平时我们都说要做视觉识别 测量云云 xff0c 然后我们就会去拍照 xff0c 再对数字图像做各种处理 xff0c 颜色处理 灰度化 滤波 边缘检测 霍夫变换
  • cmake学习4--自定义编译选项

    CMake 允许为项目增加编译选项 xff0c 从而可以根据用户的环境和需求选择最合适的编译方案 例如 xff0c 可以将 MathFunctions 库设为一个可选的库 xff0c 如果该选项为 ON xff0c 就使用该库定义的数学函数
  • ROS与C++学习1

    ROS与C 入门教程 构建工作空间 构建Catkin包 搭建开发环境 catkin make 编写简单发布节点和订阅节点 编写简单服务端和客户端 使用类方法作为回调函数 使用Timers类 编写高级的发布器和订阅器 Callbacks和Sp
  • IAR的UI界面优化

    显示行数 Tools Options 点击 Editor Tab size xff1a 设置Tab键占用多少个空格Indent size xff1a 应该是设置过行时缩进多少个空格Insert tab xff1a 选了之后在删除Tab时 x
  • MYNTEYE小觅双目摄像头深度版+VINS测试

    小觅双目深度版性能分析 今年 xff08 18年 xff09 11月9号小觅智能科技的深度版双目相机上市 xff0c 于是我在12月初花了2999软妹币购买了120度视角的相机 其中我比较感兴趣的是 双目 43 惯导 43 结构光 的多传感
  • QT+ROS开发

    Qt Creator for ROS 如果想在Qt上进行ros包的开发和GUI界面开发 建议采用下面的方法 http fumacrom com 1mipW Setup Qt Creator for ROS Setup Ubuntu to a
  • PX4、APM无人机仿真连接QGC地面站记录(udp连接、更改home点等)

    文章目录 一 PX41 gazebo 仿真2 连接地面站3 更改 Home点 二 APM 仿真1 执行仿真指令2 连接地面站3 更改 Home 点 本文仅记录仿真指令 xff0c 搭建安装不在此 一 PX4 首先给飞控源码和子目录权限 sp
  • LeetCode 解题笔记(一)总

    文章目录 一 常用技巧二 常用翻译三 题目x 其他9 回文数 2021 12 0911 盛最多水的容器 2022 01 0515 三数之和 2022 01 14 17 电话号码的字母组合 2022 01 1520 有效的括号 2021 12
  • LeetCode 解题笔记(二)数组篇

    文章目录 一 基础篇26 删除排序数组中的重复 2022 01 16122 买卖股票的最佳时机 II 2022 01 17189 轮转数组 2022 01 18217 存在重复元素 2022 01 19136 只出现一次的数字 2021 1