C++STL之vector类:相关习题解析

news2024/9/21 4:38:38

目录

只出现一次的数字|

只出现一次的数字||

只出现一次的数字|||

杨辉三角(vector>的理解)

删除排序数组中的重复项

删除排序数组中的重复项||

数组中出现次数超过一半的数字


只出现一次的数字|

. - 力扣(LeetCode)

思路:

我们都知道,对于二进制的异中,相同的两个数异或为 0, 不同的两个数异或为 1,即,相同为 0 ,相异为 1。而 0 异或任何数都是该数本身。

举例:

        假设 a = 2, b = 2;   a^b = 0;

        假设 a = 0, b = 2;   a^b = 1;

要在数组中找只出现一次的数字,其它数字出现了两次并且是相同的,我们就可以把所有的数异或起来,相同的数异或会抵消成了 0,而 0 异或任何数都是 0,最后就只剩下那个出现一次的数。

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

只出现一次的数字||

. - 力扣(LeetCode)

思路:

在很多实际应用场景中,32 位整数已经足够满足大部分的需求。很多常见的数据和计算任务并不需要用到 64 位的整数范围。

① 在二进制中,把每个数的每一位都相加起来,为什么相加呢 ?题目中所说,三个数相同,另外一个异类,也就是 4个数的每一位相加,如果取模 3 正好是 1,说明这一位就是 1。

当时7个数(3相同+3相同+1异类) 的时候也是同理。

例如: 2     2    3      2

            0   0  1   0

            0   0  1   0

            0   0  1   1

      +    0   0  1   0

---------------------------------------

             0  0  4   1               

1 和 4 取模 3 等于1,说明该位的值为 1 。

得到了该位为 1 ,然后在按位或 |,这里不能使用按位与&,

假设当前 ans 0110(假设这是前面部分位的计算结果),现在处理第二位(从右往左数),且第二位的累计异或结果为 1,表示只出现一次的那个数在第二位是 1。

 

如果使用 “|”(按位或):
执行ans |= (1 << 1)1 << 1 得到 0010,按位或操作后结果为0110 | 0010 = 0110,因为该位原本就是 1,所以结果保持不变,没有影响到其他位。

 

如果使用 “&”(按位与):
执行ans &= (1 << 1)1 << 1 得到 0010,按位与操作后结果为0110 & 0010 = 0010,原本的第三位和第一位被清零了,导致结果错误。

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        int ans = 0;
        for(int i = 0; i < 32; ++i) 
        {
            int ctn = 0;
            for(int j = 0; j < nums.size(); ++j) 
            {
               ctn += (nums[j] >> i) & 1 ;
            }
            if(ctn % 3 == 1) 
            {
                ans |= (1 << i);
            }
        }
         return ans;
    }
};

只出现一次的数字|||

. - 力扣(LeetCode)

思路:

① 先全部异或起来,两两相同的全部抵消,最终得两个不同的数异或的结果。

② 找到该数的第 i 位为1。

③ 分组异或出最终结果。

a. 我们找到了第 i 位为 1, 在这一位中,要么是 0,要么是1。


b. 我们就可以把所有的数 按位与&1 结果不是 0 就是 1,正好把结果为 0 的分成一组,结果为1 的分成一组。

为什么这样分组呢???

两个不同的数异或的结果,肯定是一个为 0 ,一个为 1,所以必然可以分成两组。假设除掉这两个数外,剩下的要么都是结果为 1 的组 或者都是结果为 0 的组,都被分到了一组,他们异或都抵消了,最后还是剩下两个不同的数。

c.把0的这一组全异或起来,把1的这一组全异或起来。相同的数都异或成了0,最终就出来了这个数。
 

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) 
    {
        //1,全部异或起来
        int val = 0;
        for(auto e : nums) 
        {
            val ^= e;
        }
        //2,找到第 i 位为 1
        int m = 0;
        for(int i =0; i< 32; ++i) 
        {
            if(val & (1 << i))
                break;
            else
            ++m;
        }
        //3,分组异或出最终结果
        int a = 0, b = 0;
        for(auto e : nums) 
        {
            if(e & (1 << m)) 
                a ^= e;
            else
                b ^= e;
        }
        vector<int> v;
        v.push_back(a);
        v.push_back(b);
        return v;
    }
};

杨辉三角(vector<vector<int>>的理解)

. - 力扣(LeetCode)

思路:

① 创建二维数组 vector,并调整大小。

② 初始化每行的首尾元素。

③ 计算中间元素的值。

④ 返回结果。

class Solution {
public:
    vector<vector<int>> generate(int numRows) 
    {
        vector<vector<int>> vv;
        vv.resize(numRows);
        for(size_t i = 0; i < vv.size(); ++i) 
        {
            vv[i].resize(i + 1);
            vv[i][0] = 1;
            vv[i][vv[i].size() - 1] = 1;
        }
        for(size_t i = 0; i < vv.size(); ++i) 
        {
            for(size_t j = 0; j < vv[i].size(); ++j) 
            {
                if(vv[i][j] != 1) 
                {
                   vv[i][j] = vv[i-1][j] + vv[i-1][j-1];
                }
            }
        }
        return vv;
    }
};

删除排序数组中的重复项

. - 力扣(LeetCode)

思路:

定义两个指针,一个快指针,一个慢指针。

慢指针指向开头,快指针指向第二个元素。让快指针去遍历该数组,如果和慢指针的数相同就跳过,如果找到了不同的数,让慢指针走一步,并把快指针的值给慢指针,这样就可以到达去重的效果。

最后慢指针位置加一就是去重后数组长度。

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

删除排序数组中的重复项||

. - 力扣(LeetCode)

思路:

在有序数组中

  • 特殊情况处理:

    • if(nums.size() < 3):如果数组的长度小于 3,那么肯定不存在重复出现三次的情况,直接返回数组的长度即可。
  • 初始化指针:

    • int slow = 2:慢指针初始指向数组第三个位置(索引为 2),因为要保证每个元素最多出现两次,前两个位置不需要检查是否重复。
    • for(int fast = 2; fast < nums.size(); ++fast):快指针从第三个位置开始遍历整个数组。
  • 去重过程:

    • if(nums[slow - 2]!= nums[fast]):检查当前慢指针往前数第二个位置的元素与快指针指向的元素是否不同。
    • 如果不同,说明快指针指向的元素不是重复出现三次的元素,可以将其放入去重后的数组中。
    • nums[slow++] = nums[fast]:将快指针指向的元素赋值给慢指针位置,并将慢指针向后移动一位。
  • 返回结果:

    • 最终慢指针的值就是去重后数组的长度。
class Solution {
public:
    int removeDuplicates(vector<int>& nums) 
    {
        if(nums.size() < 3) 
        {
            return nums.size();
        }
        int slow = 2;
        for(int fast = 2; fast < nums.size(); ++fast) 
        {
            if(nums[slow-2] != nums[fast]) 
            {
                nums[slow++] = nums[fast];
            }
        }
        return slow;
    }
};

数组中出现次数超过一半的数字

数组中出现次数超过一半的数字_牛客题霸_牛客网

思路:

解法一:

大家都会的解法,就是先排序,然后在取中间的下标,返回这个值就是那个数字。

题目说了该数字超过了一半,所以排序之后必定是这个超一半的数,这种解法大家都会。

代码如下:

class Solution {

public:

    int MoreThanHalfNum_Solution(vector<int>& numbers)

    {

       sort(numbers.begin(),numbers.end()); //先排序

       int mid = numbers.size() / 2;  // 找到中间值

       return numbers[mid];

    }

};

解法二:

此题主要是让大家理解摩尔投票法。

核心思想:

        在一组数据中,找出出现次数超过一半(大于数组长度的一半)的元素。其主要思想是通过不断 “抵消” 不同的元素,最终剩下的可能就是出现次数超过一半的元素。

具体过程:

  • 初始化阶段:

    • 选取第一个元素作为候选元素,同时设置一个计数器为 1。
  • 遍历阶段:

    • 从第二个元素开始遍历数组。
    • 如果当前元素与候选元素相同,计数器加 1。
    • 如果不同,计数器减 1。
    • 当计数器变为 0 时,重新选取当前元素为候选元素,并将计数器重置为 1。
  • 验证阶段(可选):

    • 遍历结束后,得到的候选元素可能是出现次数超过一半的元素,但需要进一步验证。
    • 再次遍历数组,统计候选元素出现的次数。
    • 如果候选元素出现的次数确实超过数组长度的一半,那么它就是所求的元素;否则,说明数组中不存在出现次数超过一半的元素。
#include <iostream>
class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int>& numbers) 
    {
       if (numbers.empty()) return 0;
       int candidate = numbers[0];
       int count = 1;
       for(int i = 1; i < numbers.size(); ++i) 
       {
          if(count == 0) 
          {
             candidate = numbers[i];
             count = 1;
          }
          else if (numbers[i] == candidate) 
          {
             ++count;
          }
          else
          {
             --count;
          }
       }
        return candidate;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2095421.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

★ 算法OJ题 ★ 力扣15 - 三数之和

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;芝麻凛将和大家一起做一道双指针算法题--三数之和~ 目录 一 题目 二 算法解析 三 编写算法 一 题目 15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 二 算法解析 解法一&#xff1a;排序 暴力枚举 利…

JavaEE:多线程进阶(常见的锁策略)

文章目录 常见的锁策略各种锁的概念 synchronized特点加锁过程 锁消除(编译器的优化策略)锁粗化(编译器的优化策略) 常见的锁策略 锁是一个非常广义的问题. synchronized只是市面上五花八门的锁的一种典型的实现.它是Java内置的,推荐使用的锁. 各种锁的概念 下面这些概念,一…

JavaScript程序结构

程序结构有三种&#xff1a;选择结构、循环结构 、顺序结构 一、选择结构 1、简介 根据条件进行判断&#xff0c;从而执行不同的操作&#xff0c;称为选择结构&#xff08;分支结构&#xff09;&#xff0c;其实就是条件判断 选择结构的类型&#xff1a;if、switch 2、if结…

第十七篇——九变篇:紧扣战略重心,别跑题

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 九变种前面偏向宏观给讲解了九变的含义&#xff1b;这一篇通过更加微观的…

如何基于numpy和scipy实现曲面的最大梯度计算与显示

大家在做三维可视化研究过程中,经常需要做三维曲面的绘制和相交分析,在不知道三维曲面方程的情况下,如何基于曲面散点数据计算曲面的最大梯度点和梯度线的三维可视化是大家基于曲面分析研究中的重点关注的问题,本文在python环境下,基于numpy、pandas、scipy和matplotlib等…

MYSQL————联合查询

联合多个表进行查询 设计数据时把表进行拆分&#xff0c;为了消除表中字段的依赖关系&#xff0c;比如部分函数依赖&#xff0c;传递依赖&#xff0c;这时会导致一条SQL查出来的数据&#xff0c;对于业务来说是不完整的&#xff0c;我们就可以使用联合查询把关系中的数据全部查…

dk安装redis

docker search redis docker pull redis 由于我是使用的镜像 所以我的拉取命令就是 docker pull dockerpull.com/redis 拉下镜像之后&#xff0c;点击下面地址选择自己需要的 redis 版本的配置文件 redis/redis.conf at 6.2.6 redis/redis GitHubRedis is an in-memory data…

Python和Java及MATLAB和CUDA显微镜导图

&#x1f3af;要点 交互式设备控制和图像处理图像背景和阴影校正可视化萤光团位置算法和读取光学图像读写转换显微镜图像生物医学细胞图像分析荧光图像算法计算亮度数据和模拟表征新型染料和缓冲液强度估计细菌图像分析扫描透射和高分辨率透射图像模拟多模态成像分割可视化透射…

python安装protobuf记录

需求背景 客户需要protobuf环境配置以及插件安装&#xff0c;我主要通过在pycharm里面配置参数&#xff0c;将问题解决&#xff01; 导语 Python中的protobuf(Protocol Buffers)是一种用于序列化结构化数据的语言无关、平台无关、可扩展的机制。它能够让您在不同的应用程序和语…

搭建基于QT的TCP服务器与客户端

1、实现功能 1、服务器和客户端能够建立连接 2、服务器可以给客户端发送信息 3、客户端可以给服务器发送信息 2、server 2-1、widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QTcpSocket> QT_BEGIN_NA…

2024 年 IBM 量子开发者大会:等你来

在 2024 年 IBM Quantum™ 开发者大会上&#xff0c;与会者将获得 IBM Quantum 尖端工具和即将推出的路线图更新的独家、亲身预览&#xff0c;所有这些都围绕一个主题 — — Qiskit 的性能。 2024 年 IBM 量子开发者大会 在此申请 重要日期 7 月 24 日&#xff1a; 开放申请 8 …

leetcode 902. Numbers At Most N Given Digit Set

题目链接 Given an array of digits which is sorted in non-decreasing order. You can write numbers using each digits[i] as many times as we want. For example, if digits [1,3,5], we may write numbers such as 13, 551, and 1351315. Return the number of posit…

Docker续6:容器网络

1.bridge-utils 一个用于Linux系统的网络桥接工具集。它提供了一些命令行工具&#xff0c;帮助用户创建、管理和配置网络桥接。网络桥接是一种将多个网络接口连接在一起&#xff0c;以使它们能够作为单个网络段进行通信的技术。 bridge-utils 常用的命令包括&#xff1a; b…

大阪OSAKA分子泵电源TC163HTC203TC353TC523TC1104TC553TC1813手侧

大阪OSAKA分子泵电源TC163HTC203TC353TC523TC1104TC553TC1813手侧

六、泛型事件框架

一、创建一个BaseEventSO的 基类 写一个泛型事件《T》 启动事件?.Invoke 二、创建一个监听类 同样泛型匹配Event的监听事件 创建OnEable在其中注册事件&#xff1b;OnDisable中注销事件 写一个if语句进行判断是否为空 三、创建一个ObjectEvent 传递Object 原因&#xf…

axios发送post请求实例

在body中的数据格式又有两种&#xff0c;一种是 json 数据格式&#xff0c;另一种是 字符串。具体要用哪种格式取决于后端入参的格式。 如果后端接收json数据类型&#xff0c;post 的 headers 需要设置 { ‘content-type’: ’application/json’ }&#xff0c;传给后端的数…

初学流量分析

一、基本知识 比赛中提供一个包含流量数据的 PCAP 文件&#xff0c;有时候也会需要选手们先进行修复或重构传输文件后&#xff0c;再进行分析。 PCAP 这一块作为重点&#xff0c;复杂的地方在于数据包里充满着大量无关的流量信息&#xff0c;因此如何分类和过滤数据是参赛者需…

stm32f103c8t6引脚功能

STM32F103C8T6拥有丰富的引脚功能&#xff0c;主要包括广泛的GPIO引脚、多种通信接口和特定的调试及电源管理引脚。 STM32F103C8T6是一款基于ARM Cortex-M3内核的微控制器&#xff0c;广泛应用于各种嵌入式系统设计中。它具有72MHz的处理速度&#xff0c;搭载128KB的Flash内存…

行业寒冬下的职场生态:卷与痛的交响曲

在2024年的初春&#xff0c;当万物复苏的季节理应带来希望与机遇之时&#xff0c;职场却笼罩在一片前所未有的“寒冬”之中。经济的波动、技术的快速迭代以及市场需求的微妙变化&#xff0c;共同编织了一幅复杂而严峻的行业图景。工作岗位的数量锐减&#xff0c;质量下滑&#…

域名解析DNS服务

DNS服务基础知识 DNS&#xff1a;Domain Name System (域名系统) DNS 是互联网上解决网络中机器命名的一种系统。在网络中&#xff0c;一台主机去访问另外一台主机时&#xff0c;必须要 知道目标主机的IP地址&#xff0c;虽然网络上的节点都可以用IP地址来标识&#xff0c;并且…