LeetCode之vector

前言

本篇是对vector的一个巩固练习, 题目分别在leetcode和牛客网

博客主页: 酷酷学!!!

感谢关注~


正文开始

1. 杨辉三角

在这里插入图片描述

题目思路

首先我们需要返回二维数组, 那么首先创建二维数组, 观察可发现, 杨辉三角的每一行的第一列和最后一列都是1, 其余位置都是上一行的同位置的值和上一行的前一个为位置的值. 由此我们来构建杨辉三角

参考代码

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

    }
};

2. 删除有序数组的重复项

在这里插入图片描述

题目思路

采用双指针法, 快指针用来遍历数组, 慢指针用来记录待插入的位置, 因为是有序, 所以我们不需要考虑其它的地方, 重复的数组一定是挨着的, 所以如果快指针和前一个位置的值不相等, 就往慢指针的地方放.

参考代码

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

3. 只出现一次的数字Ⅲ

在这里插入图片描述

题目思路

本题有点类似于我们之前做的单身狗的进阶版本, 如果找出数组中唯一只出现一次的数字, 我们可以使用异或进行求解, ^ 相同为0, 不同为1 , 自己和自己异或也是0 , 所以如果里面的一个数和所有的数组都异或一遍, 结果一定是那个唯一的数字, 那么本题如果全部异或则是最后两个不同的数字异或的结果.

如果我们能够将这两个数字分到不同的组中, 然后不同的组分别异或, 则最后的分别求出组中唯一的数字, 不就可以了吗, 那么怎么分组呢, 首先需要保证这两个数字进行分开, 然后相同的数也要分到不同的组, 相同的数二进制是一样的, 我们考虑用二进制分, 两个数异或的结果, 如果为1, 则说明这两个数在这一位上不同, 就根据这一位进行分组, 当然任意一位的1都可以, 我们从右往左找到为1的位, 进行分组, 这一位为0的为一组, 为1的为一组, 那些相同的数字这一位一定也是一样的, 所以所有数字都已经分好了, 然后再分别异或, 结果采用列表返回, 这个是vector构造方法中的一种.

参考代码

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int len = nums.size();
        int tmp = 0;
        int count1 = 0, count2 = 0;
        //tmp为那两个数异或的结果,据此进行分组
        for(int i = 0; i< len ; i++)
        {
            tmp = tmp ^ nums[i];
        }

        //找到一个值为1的位,进行分组
        int pos = -1;
        for(int i = 0; i< 32 ; i++)
        {
           if(tmp & 1 == 1)
           {
                pos = i;
                break;
           }
            tmp = tmp >> 1;
        }   
        //分组
        for(int i = 0; i< len ; i++)
        {
            if((nums[i] >> pos) & 1 == 1)
            {
                count1 = count1 ^ nums[i];
            }
            else
            {
                count2 = count2 ^ nums[i];
            }
        }

        return {count1,count2};
    }
};

4. 只出现一次的数字Ⅱ

在这里插入图片描述
题目思路

我们知道计算机存储整数都是以二进制的方式进行存储, C++对符号位也会进行区分, 根据题目描述, 只有一个数字出现了一次, 其余数字都出现了三次, 因为二进制的位除了1就是0, 所以我们可以将所有数的二进制位按位与1求出来, 对每一位遍历数组, 将数组的元素这个位上的所有数组都求和, 如果能被3整除, 则说明那个唯一一个数的这一位为0, 如果被除以3余数为1,则说明那个唯一一个数的这一位为1, 然后将求得的位数为别加到ans中,即为唯一的数.

参考代码

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ans = 0;
        int n = nums.size();
        for(int i = 0; i< 32 ;i++)
        {
            int tmp = 0;
            for(int j = 0; j < n; j++)
            {
                tmp += (nums[j] >> i) & 1;//每个数的所有位相加
            }
            if(tmp % 3 == 1)
            {
                ans |= (1<<i);//ans是1的位 
            }
        }
        return ans;
    }
};

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

在这里插入图片描述

题目思路

首先由题意得那个数超过数组长度的一半, 那如果我们将数组进行排序, 那么那个数一定出现在中间位置, 由此求出, 我们这里采用C++SLT中的方法sort进行排序.

参考代码

#include <limits>
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param numbers int整型vector 
     * @return int整型
     */
    int MoreThanHalfNum_Solution(vector<int>& numbers) {
        sort(numbers.begin(),numbers.end());
        return numbers[numbers.size()/2];
    }
};

补充讲解sort()

在这里插入图片描述

在c语言阶段, 我们一般使用qsort函数进行排序, 那样比较麻烦, 我们还需要传递一个比较函数的指针, 没有sort使用起来方便, sort包含在头文件 < algorithm > 这个库中, 参数为迭代器区间, 排序时, 我们只需传递容器的迭代区间即可.

举个例子

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

int main()
{
	vector<int> v1;
	v1.push_back(213);
	v1.push_back(12);
	v1.push_back(3);
	v1.push_back(0);
	v1.push_back(27);

	sort(v1.begin(), v1.end());
	auto it1 = v1.begin();
	while (it1 != v1.end())
	{
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;

	greater<int> gt;
	sort(v1.begin(), v1.end(), gt);//降序
	auto it2 = v1.begin();
	while (it2 != v1.end())
	{
		cout << *it2 << " ";
		++it2;
	}
	cout << endl;

	return 0;
}

在这里插入图片描述

sort函数默认的排序方式是升序, 当然我们可以进行降序, 可以看到sort的第三个参数, 这里可以传递一个函数指针或者一个函数对象, 这个函数的返回值可以转化为一个bool值,从而区分两个数的前后顺序. 这里我们可以传递gerater的对象, 默认为比较为>,当然还有less默认比较为<

在这里插入图片描述
在这里插入图片描述


如果认为此文对您有帮助, 感谢您的关注, 三连!!!

  • 52
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷酷学!!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值