【C++】vector OJ练习

这篇具有很好参考价值的文章主要介绍了【C++】vector OJ练习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这篇文章我们来做几道vector相关的OJ练习,练习一下vector的使用。。

1. 只出现一次的数字

题目链接: link
【C++】vector OJ练习

思路讲解

那这道题我们用^来搞是不是就非常简单啊。
两个相同的整数异或结果为0;0和任何整数异或结果还是这个数本身。
所以可以怎么搞,定义一个变量初始值为0,遍历数组,让它和每一个元素进行异或,最终的结果就是数组中只出现一次的那个数字。

AC代码

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

【C++】vector OJ练习

2. 杨辉三角

题目链接: link
【C++】vector OJ练习

思路讲解

这道题呢是给我们一个行数 numRows,生成「杨辉三角」的前 numRows 行。
那这道题的思路是很简单的,没什么难度:
核心思想:找出杨辉三角的规律,发现每一行头尾都是1,中间第[j]个数等于上一行[j-1]+[j]。
但是,如果我们用C语言去写这道题:
【C++】vector OJ练习
大家看,其实是有点麻烦的,一级指针、二级指针,最终返回的数组还得是malloc的。首先这个参数可能就给我们看懵逼了。
而C++呢?
【C++】vector OJ练习
C++有了vector,就爽很多了。
不过这里需要用到vector<vector>,这是什么东西,🆗,就是一个二维的vector嘛,类似于二维数组,但是如果是二维数组,我们开一个m x n的,它的每行元素是不是相等的啊,而这里杨辉三角是不是每行元素个数不一样啊。
但是用vector,我们是不是就可以很方便的控制每行的size啊。
【C++】vector OJ练习
我们只需要定义一个numRows行的vector<vector>,每行的元素个数是多少?
是不是i+1啊,i等于0(第0行),就是一个元素;i等于1,两个元素;以此类推。
然后只需把每行第一个和最后一个元素初始化为1 ,中间剩余的元素是不是就是它上一行的元素和上一行的前一个元素相加的和啊。

AC代码

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

【C++】vector OJ练习

3. 只出现一次的数字 III

题目链接: link
【C++】vector OJ练习

思路讲解

大家看这道题是不是第一题的一个升级版啊,第一道题是让我们找出数组中那个只出现一次的数字,而这道题与第一题的区别是里面多了一只“单身狗”,有两个只出现一次的数字,其余数字都是出现两次,我们要找出这两只单身狗。

那我们可以怎么做呢?

第一道的方法在这种情况下是不是就不适用了啊,那我们能不能把第二道题转换为第一道题的那种情况,然后再用同样的方法求解。
怎么转换呢?
🆗,我们可以考虑去做一个分组:
比如,那这样一组数据:1 2 3 4 5 1 2 3 4 6,那这里5跟6是不是就是我们要找的两个数字啊。
那我们就可以把所有的数据分为两组,但是要保证5跟6在不同的组里,并且每组除了5跟6剩余的数字都是成对出现的:
比如,这样:
【C++】vector OJ练习
或者这样:
【C++】vector OJ练习

那现在问题来了,怎么做可以把5跟6分开到不同的组里呢?

🆗,我们可以这样做,大家想,我们要找的这两个数字肯定是不相等的,那它们异或的结果里面肯定有1:
比如,5的二进制序列是101,6是110,它们异或的结果是011
那这个结果说明了什么?
是不是说明5的二进制序列的第一位和6的二进制序列的第一位是不相等的啊,那肯定一个是1 ,一个是0 ,那我们就可以把数组里所有数字中第一位是0的分到一组,第一位是1 的分到一组,那这样5和6肯定不在同一组,因为我们特意选了它们二进制序列不同的那一位进行的分组,另外这样做的话,除了5跟6之外的其它元素肯定是成对出现在其中一组的
当然,这里不止可以选择用第一位去分组,这里5跟6 二进制序列的第二位是不是也不同啊,你也可以根据第二位是0还是1去分组。
那分完组的话,是不是就是第一题的情况了,每组只有一个单身狗,剩余数字均成对出现,那两组数字与0异或的两个结果就是两个单身狗了。

AC代码

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        //0和所有数字异或,最终结果ret就是两个单身狗异或的结果
        int ret=0;
        for(auto e:nums)
            ret^=e;
        //判断两个单身狗的二进制位中第几位不同(即ret哪一位是1),我们选第一个不同的位置就行了
        int pos=0;//pos记录不同的位置
        for(int i=0;i<31;i++)
        {
            if((ret>>i)&1==1)
            {
                pos=i;
                break;
            }
        }
        int num1=0;
        int num2=0;
        //将数组中所有元素中的二进制位中第pos位为1的分一组,为0的分一组,两组数字与0异或的两个结果就是两个单身狗
        for(auto e:nums)
        {
            if((e>>pos)&1==1)
                num1^=e;
            else
                num2^=e;
        }
        vector<int> fin;
        fin.push_back(num1);
        fin.push_back(num2);
        return fin; 
    }
};

【C++】vector OJ练习

4. 只出现一次的数字 II

题目链接: link
【C++】vector OJ练习

思路讲解

这道题还是让我们找出数组中只出现一次的那个数字,但是与第一题不同的是,其余数字均出现三次。
那我们用第一题的方法肯定是不行了,那我们可以怎么做呢?
我们后面学了unordered_map的话用unordered_map其实可以很容易解这道题,不过我们现在还没学。

那这里我就用了一种比较暴力的方法,也很好理解:

怎么做呢?
遍历数组,一次取每个元素与其余元素进行比较,如果出现相等的情况,那就说明当前元素不是我们要找的数字,那就看下一个,如果某个元素与其余数字都不想等,就是要找的目标数字。
当然效率可能没有那么高。

AC代码

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret=0;
        for(int i=0;i<nums.size();++i)
        {
            int flag=1;
            for(int j=0;j<nums.size();++j)
            {
                if(i==j)
                    continue;
                if(nums[i]==nums[j])
                {
                    flag=0;
                    break;
                }
            }
            if(flag)
            {
                ret=nums[i];
                break;
            }
        }
        return ret;
    }
};

【C++】vector OJ练习

5. 删除有序数组中的重复项

题目链接: link
【C++】vector OJ练习

思路讲解

这道题我们可以考虑使用“双指针”来求解:
首先,定义两个变量作为指针,初始都指向下标为0位置。
【C++】vector OJ练习
如果两指针指向的元素相等,我们只让 src++往后走,过滤掉重复值。
【C++】vector OJ练习
如果不再相等,先让dest++,让后把src指向的元素赋值给dest指向的元素,然后再让src++。
【C++】vector OJ练习
然后再判断两指针指向的元素是否相等,重复上述操作,直至src遍历完数组。
【C++】vector OJ练习
最终dest+1就是去重后的数组长度。

AC代码

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int dest=0;
        int src=0;
        while(src<nums.size())
        {
            if(nums[src]==nums[dest])
                ++src;
            else
            {
                // ++dest;
                // nums[dest]=nums[src];
                // ++src;
                nums[++dest]=nums[src++];
            }
        }
        return dest+1;
    }
};

【C++】vector OJ练习

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

题目链接: link
【C++】vector OJ练习

思路讲解

这道题其实有一个很简单的解法:
怎么做呢?
只要给这个数组排下序就行了,然后直接返回排好序之后数组中间的那个元素即可。
因为我们要找的数字在数组中出现的次数超过数组长度的一半,所以排好序之后中间位置的元素肯定是这个出现的次数超过数组长度的一半的元素。

AC代码

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        sort(numbers.begin(),numbers.end());
        return  numbers[numbers.size()/2];
    }
};

【C++】vector OJ练习

这篇文章的内容就到这里,欢迎大家指正!!!
【C++】vector OJ练习文章来源地址https://www.toymoban.com/news/detail-426229.html

到了这里,关于【C++】vector OJ练习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++ OJ练习】5.字符串最后一个单词的长度

    字符串最后一个单词的长度_牛客题霸_牛客网 倒着找第一个空格的下标 用下标之间的差来计算  【C++ OJ练习】5.字符串最后一个单词的长度 完

    2024年02月13日
    浏览(31)
  • 《C++ primer》练习3.20:输出vector相邻元素的和&输出vector头尾对象的和

    最近看《C++ Primer》,有这样一个题目 读入一组整数并把它们存入一个vector对象,将每对相邻整数的和输出出来。 这里要注意输入的奇数个和偶数个的数的区别。偶数个整数的话刚好数全部用完,奇数个整数最后一个数空出来,也输出出来,后面没有数了(再使用后面的索引

    2024年02月09日
    浏览(27)
  • 【C++】unordered_map和unordered_set的使用 及 OJ练习

    在前面的文章中,我们已经学习了STL中底层为红黑树结构的一系列关联式容器——set/multiset 和 map/multimap(C++98) 在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 l o g 2 N log_2 N l o g 2 ​ N ,即最差情况下需要比较红黑树的高度次。 在C++11中,

    2024年02月11日
    浏览(31)
  • C++ //练习 11.14 扩展你在11.2.1节练习(第378页)中编写的孩子姓到名的map,添加一个pair的vector,保存孩子的名和生日。

    练习 11.14 扩展你在11.2.1节练习(第378页)中编写的孩子姓到名的map,添加一个pair的vector,保存孩子的名和生日。 环境:Linux Ubuntu(云服务器) 工具:vim   代码块 运行结果显示如下

    2024年04月10日
    浏览(28)
  • 《vector的一些OJ》

    本文主利用我们的vector来解决一些OJ题 前三个题目很类似,分别为 一个数字只出现一次,其他数字都出现两次 两个数字只出现一次,其他数字都出现两次 一个数字只出现一次,其他数字都出现三次 思路 :这个其实很简单,我们 使用异或的思想 即可。 因为两个相同的数异

    2024年02月03日
    浏览(20)
  • C++ //练习 11.12 编写程序,读入string和int的序列,将每个string和int存入一个pair中,pair保存在一个vector中。

    练习 11.12 编写程序,读入string和int的序列,将每个string和int存入一个pair中,pair保存在一个vector中。 环境:Linux Ubuntu(云服务器) 工具:vim   代码块 运行结果显示如下

    2024年04月10日
    浏览(34)
  • 链表OJ练习(1)

    本题为力扣原题203 题目介绍: 给你一个链表的头节点  head  和一个整数  val  ,请你删除链表中所有满足  Node.val == val  的节点,并返回  新的头节点  。 列表中的节点数目范围在 0~10000内 1=Node.val=50 0=val=50   思路:利用双指针解决,struct ListNode*dst=NULL;struct ListNode*cur=he

    2024年02月10日
    浏览(22)
  • 链表OJ练习(2)

    题目介绍: 思路:创建两个链表,ghead尾插大于x的节点,lhead尾插小于x的节点。先遍历链表。最后将ghead尾插到lhead后面,将大小链表链接。           我们需要在创建两个链表指针,指向两个链表的头节点,用这两个指针标记lhead和ghead的尾结点,方便与尾插。 注:极端边

    2024年02月10日
    浏览(23)
  • 力扣练习——链表在线OJ

    目录 提示: 一、移除链表元素 题目: 解答: 二、反转链表 题目: 解答: 三、找到链表的中间结点 题目: 解答: 四、合并两个有序链表(经典) 题目: 解答: ①:接上一篇文章 本次我们来做一些在线OJ题,进一步加深印象和感觉,并且本次某些方法会沿用上一篇文章

    2024年02月08日
    浏览(39)
  • 数据结构——二叉树(OJ练习)

    大家好,本期是二叉树的最后一期,这一期我们来看看二叉树的编程题 . - 力扣(LeetCode) 首先我们的思路是: 遍历二叉树,把每个节点去比较一次,按照要求返回 我们来看代码 . - 力扣(LeetCode) 这里我们的思路是:同时遍历两给树,遇到空树或者不相等时返回。 . - 力扣

    2024年04月12日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包