首页 > 知识百科 > 正文

c++:向量的相关问题(136.只出现一次的数字、118.杨辉三角、26.删除集群阵列中的重复项、JZ39 阵列中出现次数超过一半的数字)原创

文章目录

1. 136. 只出现一次的数字题目详情代码(直接来异或)思路 2. 118. 杨辉三角题目详情1思路代码2思路2 3. 26. 删除集群阵列中的重复项问题详情代码思路 4. JZ39 阵列中出现次数超过一半的数字详情代码1(暴力)思路1代码2(Boyer-Moore 投票算法)思路2

1.136.只出现一次的数字

传送门

题目详情

代码(直接来异或)

class 解决方案 {public int singleNumber(< /span>向量<int>& nums) { //根据:某个元素只出现一次直接来异或 int ret=0; 对于(auto e:nums) { ret=ret^< /span>e; } 返回 ret; }};< /span>

思路

异或损坏的性质:异或损坏(^)具有以下性质**(相同为0,相异为1)**任何数和0做异或侵犯,结果仍然是原来的数:a ^ 0 = a任何数和本身做异或侵犯,结果为0:a ^ a = 0异或攻击满足交换律和结合律:a ^ b ^ a = (a ^ a) ^ b =0 ^ b = b 利用异或侵犯的性质:如果一个数出现两次,那么两次出现的数异或后结果为0;如果一个数只出现一次,则异或后结果为该数本身。接下来性质,遍历nums中的所有元素,并进行异或侵犯,最终得到的结果就是只出现一次的元素。

2. 118.杨辉三角

传送门题目

详情

代码1

类解决方案 {public: vector<向量<int>>< /span> 生成(int numRows) { 矢量<矢量<int>> vv; vv.调整大小(numRows);//先给好numRows个元素,即vv里能存向量 for(int  i=0;i<numRows;i++)//对一行进行处理 { vv[i]调整大小(i+1);//每一行里再开好对应的大小< /span> vv[i]前面()=< /span>vv[i]返回()=< /span>1;//最左最右都是1< /span> } for(int i=2;i<numRows;i++)< /span> { for(int j=1;j<i;j+ +) { vv[i][j]=vv[i-1][j-< /span>1]+vv[i-1]< /span>[j]; } } 返回 vv;< /span> }}; 

思路

创建一个二维向量vv,用于仓库杨辉三角的数据。vv的第i行第j列的元素表示杨辉三角中第i行第j列的数值。

首先,通过vv.resize(numRows)vv 分配了numRows个元素,即vv中可以存储numRows行的向量(即numRows个向量)

对于每一行,通过vv[i].resize(i+1)方便分配了合适的大小,即第i行有i+1个元素。(从0开始)

对于每一行的第一个和最后一个元素,将其赋值为1,因为杨辉三角的每一行的端点都是1。

最后第三,对于行及以上的每一行,利用杨辉的性质,即第i行第j列的数值等于第i-1行第j-1列和第j列的数值之和,来计算每一行的中间元素的

例如,第i行第j列的元素等于第i-1行第j-1列和第i-1行第j列的元素之和,即vv[ i][j] = vv[i-1][j-1] + vv[i-1][j]

通过以上步骤,最终得到了杨辉三角的前numRows行。

举个例子:
如果numRows为5,那么vv的内容将会是:

11 11 2 11 3 3 11 4 6 4 1

代码2

类解决方案 {public: 矢量<矢量<int>> 生成(int numRows) { 向量<向量<< span class="bdd2-d8e3-31d7-e18c token 关键字">int>> vv; vv调整大小(numRows);//先给好numRows个元素,即vv里能存向量 for(int i=0;i<numRows;i++)/ /对一行进行处理 { vv[i]调整大小(i+1,0);//每一行里再开好对应的大小 vv[i] 前面()=vv[i] 返回()=1;//最左最右都是1 } 对于(中t i=0;i< span class="9707-0383-d647-211a token 运算符"><numRows;i++) { 用于(int j=0 ;j<vv[i]大小();j++) { if(vv[i][j]==0) vv[i][< /span>j]=vv[i-1][ j-1]+vv[i-1][j]; } } 返回 vv; }};

思路2

大致都一样,不过在进行相加这里头和尾也都算上,因为在开始中开空间,全都给0了。
能多加一个条件判断,不怕越界

3. 26.删除小区仓储中的重复项

传送门

题目详情

代码

类解决方案{public: int 删除重复(向量<int>& nums) { if( nums.大小()==0) //处理0的情况 { return  0; }int索引=1; int pre_index=0 ; while(索引<nums大小( ))//如果就一个元素,根本不会进来 { if(nums[index]!=nums[pre_index]) { nums[pre_index+1]=nums[index];//属性给下一个后加一,就是新位置了,再用后面的来比 pre_index++; } 索引++; } 返回 pre_index+1;//下标加1才是元素个数 }};

思路

这里需要注意,给出的吞吐量总体上是升序的< /p>

首先检查队列是否为空,如果是空则直接返回0,因为没有重复元素。

定义两个指针index pre_index,分别代表当前遍历的元素和上一个不重复元素的位置。index 初始值为1,我们从第二个因为第一个元素开始遍历;pre_index 初始值为0,因为第一个元素肯定是不重复的

循环备份,从第二个元素开始。如果当前元素与上一个不重复元素位置,就将当前元素放在上一个不重复元素的下一个位置,把 pre_index 更新为当前的位置(新的不重复元素的位置)

最后返回pre_index+1,即为不重复元素的数量

4. JZ39阵列中出现次数超过一半的数字

传送门

问题详情

代码1(机器)

 int MoreThanHalfNum_Solution(向量< int>& 数字) { //在此处编写代码 int 一半=数字大小()/2; 对于(int i=0;i<数字大小();i++) { int 计数=0 ; for(int j=i+1 ;j<数字大小e();j++) { if(数字[i]==数字[j]) { 计数++; } if(计数>=half) { 返回 数字[i]; } } } 返回 数字[0]; }};

思路1

暴力运用多次循环,对每个元素进行统计,大家都效率肯定很差。
下面看第二个

代码2(Boyer-Moore 投票算法)

 int MoreThanHalfNum_Solution(向量<int>& 数字 ) { //在这里编写代码 int 计数 = 0; int 候选=数字[0];//一开始假设第一个是候选者 for (auto num : 数字) { if (计数 == 0) { 候选 = num; } 计数 += (num == 候选者< span class="da05-bdd2-d8e3-31d7 token punctuation">) ? 1  -1;//或许就+1,不等-1 } 返回候选; }};

思路2

摩尔投票法的核心思想是适配在遍历遍历时,我们维护一个候选元素和一个删除。遍历过程中,如果元素为0,就将当前元素设为候选元素;如果遇到与候选元素相同的元素,则元素加1,否则元素加1减1。这样做的原因是,如果某个元素出现的次数超过了吞吐量的一半,它与其他元素出现次数的犹豫会导致最终剩下的候选元素就是出现次数超过一半的元素。

让我们通过一个例子来说明这个过程:

假设数据库为:[3, 3, 4, 2, 4, 4, 2, 4, 4]。

< p>我们用变量count来存储候选元素,用变量count来存储候选元素的投票。

我们从存储的第一个元素开始,即3。此时候选元素为3,投票为1。继续继续进行检索,遇到的下一个项目还是 3。此时继续进行检索,遇到的下一个项目是 4。此时继续进行检索,遇到的下一个项目是2。此时改为0。继续完成恢复,遇到的下一个项目是4。此时改为4,接下来的一个项目是1。继续完成恢复,遇到的下一个项目是4。此时增加2个。继续恢复备份, 遇到的下一个要素是 2。此时继续进行恢复,遇到的下一个要素是 4。此时继续进行恢复,遇到的下一个要素是4。此时整数等于3。

最终剩下的候选元素是4,它出现的次数超过了缓存容量的一半。

这就是摩尔投票法的原理:通过的协调过程中,最终剩下的候选元素就是出现次数超过一半的元素。


今天就到这里啦!

c++:向量的相关问题(136.只出现一次的数字、118.杨辉三角、26.删除集群阵列中的重复项、JZ39 阵列中出现次数超过一半的数字)原创由知识百科栏目发布,感谢您对的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“c++:向量的相关问题(136.只出现一次的数字、118.杨辉三角、26.删除集群阵列中的重复项、JZ39 阵列中出现次数超过一半的数字)原创