(习题)C++算法竞赛语法基础:STL、位运算、常用库函数

目录

习题一:68. 0到n-1中缺失的数字

习题二:32. 调整数组顺序使奇数位于偶数前面

 习题三:20. 用两个栈实现队列

 习题四:75. 和为S的两个数字

 习题五:51. 数字排列

 习题六:26. 二进制中1的个数

习题七:862. 三元组排序


习题一:68. 0到n-1中缺失的数字

题解:y总用了哈希表, 先将所有数全部存入哈希表里,然后再删去与nums数组相同的元素,剩下的那个数就是nums缺失的数。

class Solution {
public:
    int getMissingNumber(vector<int>& nums) {
        set<int> a;
        for(int i=0;i<=nums.size();i++) a.insert(i);
        for(auto x : nums) a.erase(x);
        return *a.begin();
    }
};

我的做法:

class Solution {
public:
    int getMissingNumber(vector<int>& nums) {
        int m=nums.size();
        int i=0;
        for(i=0;i<m;i++)
        {
            if(nums[i]!=i)
            {
                return i;
            }
        }
        if(i==m)
        return m;
    }
};

习题二:32. 调整数组顺序使奇数位于偶数前面

 我的想法是开两个vector,然后一个存奇数,一个存偶数。但是没想到平台会自己返回原数组并打印,所以必须在原数组上改动才行。还有一点就是,题目并没有要求奇数和偶数部分要按照升序来排。

题解:设两个指针分别在最左边 i 和最右边 j ,然后 i 先动直到指向的数字不为奇数,再 j 动直到指向的数字不为偶数,这时若 i < j ,则互换数值,使得偶数在后、奇数在前。

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        int i=0,j=array.size()-1;
        while(i<j)
        {
            while(array[i]%2) i++;
            while(array[j]%2==0) j--;
            if(i<j) swap(array[i],array[j]);
        }
    }
};

 然后我意识到要在原数组上改变就这样改了代码,也通过了:

class Solution {
public:
    void reOrderArray(vector<int> &array) {
            vector<int> a,b;
         for(auto x : array)
         {
             if(x%2==0)
             {
                 b.push_back(x);
             }
             else
             {
                 a.push_back(x);
             }
         }
         for(int i=0;i<a.size();i++)
         {
             array[i]=a[i];
         }
         for(int i=0;i<b.size();i++)
         {
             array[a.size()+i]=b[i];
         }
    }
};

 习题三:20. 用两个栈实现队列

题解:

class MyQueue {
public:
    stack<int> a,b;
    /** Initialize your data structure here. */
    MyQueue() {
        
    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
        a.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        while(a.size()>1) b.push(a.top()),a.pop();//将a的栈顶元素存入b,删除存入b的a元素,直到a只剩1个元素
        int t=a.top();//将a仅剩的1个元素保存
        a.pop();//保存后删除
        while(b.size()) a.push(b.top()),b.pop();//将b中的元素归回给a
        return t;
    }
    
    /** Get the front element. */
    int peek() {
        while(a.size()>1) b.push(a.top()),a.pop();//将a的栈顶元素存入b,删除存入b的a元素,直到a只剩1个元素
        int t=a.top();//将a仅剩的1个元素保存
        //这里就不用删除这个元素
        while(b.size()) a.push(b.top()),b.pop();//将b中的元素归回给a
        return t;
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        return a.empty();
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * bool param_4 = obj.empty();
 */

 习题四:75. 和为S的两个数字

题解:不暴力,可以用哈希表,遍历数组每个元素,假设现在遍历的元素数值为x,找哈希表里是否有sum-x,如果有,则返回x和sum-x;没有,则将x存入哈希表,然后继续数组的下一个元素,看看哈希表里是否有匹配的值。

class Solution {
public:
    vector<int> findNumbersWithSum(vector<int>& nums, int target) {
        unordered_set<int> a;
        for(auto x : nums)
        {
            if(a.count(target-x)) return {x,target-x};
            a.insert(x);
        }
    }
};

遍历的话:

class Solution {
public:
    vector<int> findNumbersWithSum(vector<int>& nums, int target) {
       int 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 {nums[i],nums[j]};
           }
       }
    }
};

 习题五:51. 数字排列

题解:使用stl里的函数next_permutation(begin(),end())。 next_permutation(begin(),end())会返回比传入的数值更大的按字典序排的第一个数。比如传入1 2 3,则返回1 3 2。当全部返回后没有再可返回的,则返回空。

class Solution {
public:
    vector<vector<int>> permutation(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> res;
        do
        {
            res.push_back(nums);
        }while(next_permutation(nums.begin(),nums.end()));
        return res;
    }
};

 习题六:26. 二进制中1的个数

题解:

法一:普通做法,直接遍历

class Solution {
public:
    int NumberOf1(int n) {
        int num=0;
        for(int i=0;i<32;i++)
        {
            if( n>>i&1 ==1)
            num++;
        }
        return num;
    }
};

法二:lowbit写法,每次循环删去一次末尾的1,直到n=0停止,循环了多少次就有多少个1

class Solution {
public:
    int NumberOf1(int n) {
        int res=0;
       while(n){
           n -= n&-n,res++;
       }
       return res;
    }
};

习题七:862. 三元组排序

题解:(有注意点)

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int N=10005;
struct data
{
    int x;
    double m;
    string s;
    bool operator<(const data& t)const
    {
        return x<t.x;
    }
}a[N];
int main()
{
    int n;
    cin>>n;
    
    for(int i=0;i<n;i++)
    {
        cin>>a[i].x>>a[i].m>>a[i].s;
    }
    
    sort(a,a+n);
    
    for(int i=0;i<n;i++)
    {
        printf("%d %.2lf %s",a[i].x,a[i].m,a[i].s.c_str());//这里要注意:printf输出字符串要带c_str()
        printf("\n");
    }
}

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值