寒假刷题笔记、总结,C++语言

写在前面

寒假备考考研复试,上机/C/C++笔试,写此文章,以记录一些重点,基本/中级算法,题目、解题思路、代码等。如有错误,欢迎各位大佬指正。

C++ 容器、STL 整理集合

(部分摘自网络,不做商业用途,仅学习使用)

vector

定义:向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。
特性:
1.顺序序列:顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素。
2.动态数组:支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算述进行该操作。操供了在序列末尾相对快速地添加/删除元素的操作。即可以通过下标读取元素。
3.能够感知内存分配器的(Allocator-aware):容器使用一个内存分配器对象来动态地处理它的存储需求。
基本函数:
1.增加
**void push_back(const T& x)**向量尾部增加一个元素X
iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一个元素x
iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n个相同的元素x
iterator insert(iterator it,const_iterator first,const_iterator last):向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据
2.删
iterator erase(iterator it):删除向量中迭代器指向元素
iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
void pop_back():删除向量中最后一个元素
**void clear()😗*清空向量中所有元素
3.遍历
一般用迭代器 , 有 .begin() , .end()
4.其他
是否为空 empty()
大小 size()
5. 对其排序 调用函数 sort(xx.begin(), xx.end())
或者重写一个比较方法,然后 sort(a,a+10,比较方法函数)
6. vector ans(NULL); //生成一个空的
7. vector ans(几个,值);

字符串 string

在这里插入图片描述参考文章:http://c.biancheng.net/view/400.html
1.求长 length 成员函数返回字符串的长度。size 成员函数可以实现同样的功能。
2.连接: += 或者 append()
3.求子串 substr(下标位置,长度),若只有下标位置,则从其之后都截下来
4. 替换 replace(替换下标位置开始,结束,替换的子串,替换子串下标开始,结束)
5. 删除 erase(下标位置,长度) 和求子串一样,位置+长度
6. 插入 insert(位置,“插入啥”),比如在位置2,则01002345,从2开始为插入子串

Map

//插入数据
Map<类型,类型> xx;
xx.insert(pair<类型,类型>(值,值))

题目:成绩排序
Map、sort、pair

#include<bits/stdc++.h>
using namespace std;
typedef pair<string, int> Pair;
bool com(const Pair &p1, const Pair &p2)
{
    return p1.second<=p2.second;
}

int main()
{
    int n,x;
    scanf("%d%d",&n,&x);
    map<string,int> sc;
    for(int i=0; i<n; i++)
    {
        string s;
        int y;
        cin>>s>>y;
        sc.insert(pair<string, int>(s,y));
    }
    map<string,int>::iterator ite;
    vector<Pair> vec;
    for(ite = sc.begin(); ite!=sc.end(); ite++)
        vec.push_back(make_pair(ite->first,ite->second));
    sort(vec.begin(),vec.end(),com);
    vector<Pair>::iterator it;
    if(x==1)
    {
        for(it=vec.begin(); it!=vec.end(); it++)
        {
            cout<<it->first<<" "<<it->second<<endl;
        }
    }else
    {
        for(it=vec.end()-1; it>=vec.begin(); it--)
        {
            cout<<it->first<<" "<<it->second<<endl;
        }
    }

    return 0;
}

在这里插入图片描述

队列

在这里插入图片描述

其他补充

初始化数组 二维也可以
memset( a, 0, sizeof(a));
vector<vector> flag(m, vector(n, 0));
留白

sort

sort(begin,end,bmp);
sort(a,a+m);
bmp return a<b; 是从小到大升序排序

异或

二进制位的异或运算规则为:相同为0,不同为1。
一个数组只有一个出现一次: 遍历异或
交换2个数:a^b, ba,ab;

一组数组,2个出现1次,其他出现2次:
异或,然后第一位为1的将数组分为2部分,分别每部分异或
一组数组,一个数出现1次,其他数出现n次
int 32位统计每位出现次数,%n ==0 为0 ,其他为1

C++ 基础知识、面试常问问题总结

1.栈是系统自动分配的,堆(非数据结构的堆)需要程序员自己来,malloc/new
操作系统有个记录当前空闲内存地址的链表,申请时会遍历,第一个大于申请空间,然后删除其,,将多余部分自动加入链表中
2.const: 定义指针变量时,const int *p再类型前,则值不能改,再类型后,int const *p则其地址不能改,若两个都有,则两者都不能改
在函数形参声明中,使用const,可以防止传进来的参数被修改。

3.C的结构体和C++的结构体的区别

a.C结构体内部不允许有函数存在,C++允许
b.内部成员变量权限不同,C的只能是public,C++的可以有三种。
c.C结构体不可以继承,C++可以继承结构体或者类

4.浅拷贝和深拷贝的原理

其实这两个概念很简单,浅拷贝就是两个对象共享一块内存,其缺点就是当析构一个对象的时候,另一个对象也不存在了,如果再使用它就会发生错误。深拷贝就是完完全全的复制出一个对象,两者在内存上无任何关系。

5.不能重载的5个运载符号: . -> ? sizeof ::
不能声明为虚函数: 普通函数、静态成员函数、内联成员函数、构造函数、友元函数

6.C++的静态多态和动态多态

所谓静态多态就是运行前确定类型或者函数调用(也就是编译后确定),其采用的是函数重载和泛型(例如,模板。
所谓动态多态就是运行后确定类型或者函数调用,其采用虚函数实现。

7.C++虚函数的原理

虚函数由虚表管理,这张表存放着所有虚函数的地址,而类的实例对象维护着一个虚表指针,指向这个表。运行的时候,根据new的对象里面的虚表指针,确定调用的函数。

8.new和malloc
①②new返回*,malloc返回void *,要强制类型转换③new分配失败抛出异常,malloc返回空④指定类型大小否⑤。

9.C++中有哪几种数据存储区?

栈、堆、自由存储区、全局/静态存储区、常量存储区

刷题 LeetCode 初级算法

动态规划

(一)爬楼梯

在这里插入图片描述

思路

和斐波那契数列一样,0,1,2……

代码

class Solution {
public:
    int climbStairs(int n) {
        if(n<=0)
        return 0;
        if(n==1) return 1;
        if(n==2) return 2;
    else
    {
        int a[n+1];
        a[0]=0;
        a[1]=1;
        a[2]=2;
        for(int i=2; i<n; i++)
        {
            a[i+1]=a[i]+a[i-1];
        }
        int b;
        b = a[n];
        return b;
    }
    }
};

(二)买卖股票的最佳时机

在这里插入图片描述

思路

也是用数组遍历,j记录买入时候,初始为a[0],若差为负,将j改为a[i]

代码

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int ans = 0;
        int len = prices.size();
        if(len==0) return 0;
        else{
            int j=prices[0];
            int t = 0;
            for(int i=1;i<len;i++)
            {
                t = prices[i]-j;
                if(t<0) j = prices[i];
                if(t>ans) ans = t;
            }
            return ans;
        }
        
    }
};

(三)打家劫舍

在这里插入图片描述

思路

 if(a[i-2]+nums[i]>a[i-1]) 
     a[i] = a[i-2]+nums[i];
 else a[i] = a[i-1];

代码

class Solution {
public:
    int rob(vector<int>& nums) {
        int len = nums.size();
        if(len==1) return nums[0];
        else if(len<=0) return 0;
        else if(len==2)
        {
            if(nums[0]>nums[1]) return nums[0];
            else return nums[1];
        }else
        {
            int a[len];
            a[0] = nums[0];
            if(nums[0]>nums[1]) a[1] = nums[0];
            else a[1] = nums[1];
            for(int i=2; i<len; i++)
            {
                if(a[i-2]+nums[i]>a[i-1]) a[i] = a[i-2]+nums[i];
                else a[i] = a[i-1];
            }
            return a[len-1];
        }
    }
};

刷题 LeetCode 中级算法

数组和字符串

(一)三数之和

在这里插入图片描述

思路

排序,然后i遍历,j从i+1,k从末尾遍历,注意去重

代码

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int> > ans;
        int len = nums.size();
        if(len<3) return ans;
        sort(nums.begin(),nums.end());
        int j,k;
        for(int i=0; i<len-2; ++i)
        {
            if(i>0 && nums[i-1]==nums[i]) continue;
            //关键 去重
            for(j=i+1, k=len-1; j<k; )
            {
                if(j>i+1&&nums[j-1]==nums[j]) { // 去重
                    ++j;
                    continue;
                }
                if(k<len-1&&nums[k]==nums[k+1]) {
                    --k; // 去重
                    continue;
                }
                if(nums[i]+nums[j]+nums[k]==0)
                {
                  vector<int> temp;
                  temp.push_back(nums[i]);
                  temp.push_back(nums[j]);
                  temp.push_back(nums[k]);
                  ans.push_back(temp);
                  ++j;
                  --k;
                }
                else if(nums[i]+nums[j]+nums[k]<0)
                    ++j;
                else if(nums[i]+nums[j]+nums[k]>0)
                    --k;
            }
        }
        return ans;
        
    }
};

(二)矩阵置0

把矩阵元素为0的行和列都置为0,要求原地算法
遍历一遍,遇到0就把行列改为*
输出时遍历,遇*输出0

(三)无重复字符的最长子串

在这里插入图片描述

思路

找到前面和其重复的元素,记录

代码

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int len = s.size();
        char t[100000];
        int ans=0;
        int l=0, temp = 0,k;
        if(len==0) return 0;
        if(len==1) return 1;
        t[0]=s[0];
        for(int i=1; i<len; i++)
        {
            t[i]=s[i];
            for(k=l; k<i; k++)
            {
                if(t[k]==s[i]) break;
            }
            if(k<i) l=++k;
            temp = i-l+1;
            if(temp>ans) ans=temp;
        }
        return ans;
    }
};

累了,歇会

回溯算法

(一)电话号码的字母组合

在这里插入图片描述

思路

built函数(结果向量, 当前电话号串下标)
{
如果 超过上限len 返回
遍历对应的map容器{
清空这一位及之后的
加上 map里对应的字符
如果完事了, 加入结果向量中
built(下一位) ;
}
}

代码

class Solution {
public:
    vector<vector<char> > map = {{' '},{' '},{'a','b','c'},{'d','e','f'},{'g','h','i'},{'j','k','l'},{'m','n','o'},{'p','q','r','s'},{'t','u','v'},{'w','x','y','z'}};
    int len;
    string t;
    string digit; //
    vector<string> ans;
    void built(int n, vector<string>& ans)
    {
        // n传进来的是电话号串的第几位 
        if(n>=len) return ;
        for(int i=0; i<map[digit[n]-'0'].size(); i++)
        {
            t.erase(n,t.size()-n); //把这位及后头都清空
            t+=map[digit[n]-'0'][i];
            if(n==len-1) ans.push_back(t); //把结果弄进去
            built(n+1,ans);
        }
    }
    
    vector<string> letterCombinations(string digits) {
        digit = digits;
        len = digits.size();
        built(0,ans);
        return ans;
    }
};

(二)生成括号

在这里插入图片描述

思路

built函数(结果向量,string s,左括号个数, 右括号个数, 要求的括号对上限n)
{
如果 右括号个数 > 左括号个数 或者左/右括号个数超过上限n 返回
如果 左括号个数=有括号个数=上限n, 加入结果向量vector ans中
built(加个右括号);
built(加个左括号);
}

代码

class Solution {
public:
    void built(string s, int n, int left, int right, vector<string>& ans)
    {
        if(right>left || left>n || right>n ) return ;
        if(right==left && left==n) ans.push_back(s);
        built(s+")",n,left,right+1,ans);
        built(s+"(",n,left+1,right,ans);
    }
    
    vector<string> generateParenthesis(int n) {
        vector<string> ans;
        if(n<=0) return ans;
        string s = "(";
        built(s,n,1,0,ans);
        return ans;
    }
};

(三)全排列问题

在这里插入图片描述

思路

qpl函数(首位元素下标,结果集)
{
挨个交换首位元素下标和后面的元素
qpl 下一位
交换回来
}

代码

class Solution {
public:
    vector<vector<int> > ans;
    void qpl(vector<int>& nums, int n,vector<vector<int> > &ans)
    {
        if(n==nums.size()) {
            ans.push_back(nums);
            return ;
        }
        for(int i=n; i<nums.size(); i++)
        {
            //ans.push_back(nums);
            swap(nums[n],nums[i]);
            qpl(nums, n+1,ans);
            swap(nums[n],nums[i]);
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        qpl(nums,0,ans);
        return ans;
    }
};

(四) 子集

在这里插入图片描述

思路

这真的是让我捉摸了好久的题,最后在这个伙伴这找到中意的解法
原文链接

代码

class Solution {
public: 
    vector<vector<int>> subsets(vector<int>& nums) {
        //先添加一个空集
        vector<vector<int> > ans(1,vector<int>());
        for(int i=0; i<nums.size(); i++)
        {    //遍历给出的nums数列个数
            int t = ans.size();
            for(int j=0; j<t; j++) //遍历ans中每个集合
            {
                ans.push_back(ans[j]);
                ans[j].push_back(nums[i]);
            }
        }
        return ans;
    }
};

(五)单词搜索

在这里插入图片描述

思路

遍历即可,复习时跳过

代码

class Solution {
public:

    
    bool search(int i, int j, vector<vector<char> >& board, string word,int isVisit[][1000] )
    {
        if(i<0 || j<0 || i>=board.size() || j>=board[0].size() || board[i][j]!=word[0] || isVisit[i][j]) return false; 
        if(word.size()==1 && i>=0 && j>=0 && i<board.size() && j<board[0].size() && board[i][j]==word[0] && !isVisit[i][j]) 
        {
            return true;
        }
        if(isVisit[i][j]==1) return false;
        string t = word.substr(1);
        isVisit[i][j]=1;
        bool flag = search(i+1,j,board,t,isVisit) || search(i-1,j,board,t,isVisit) || search(i,j+1,board,t,isVisit) || search(i,j-1,board,t,isVisit);
        isVisit[i][j]=0; // 关键,改回去
        return flag;
        /**
        if(search(i+1,j,board,t,isVisit) || search(i-1,j,board,t,isVisit) || search(i,j+1,board,t,isVisit) || search(i,j-1,board,t,isVisit))
        {
            isVisit[i][j]=0;
            return true;
        }
        isVisit[i][j]=0;
       return false;
       */
    }
    
    
    bool exist(vector<vector<char>>& board, string word) {
        if(board.size()==0 && word.size()!=0) return false;
        int isVisit[1000][1000]={0};
        for(int i=0; i<board.size(); i++)
        {
            for(int j=0; j<board[0].size(); j++)
            {
                if(search(i,j,board,word,isVisit)) return true;
            }
        }
        return false;
    }
};

排序和搜索

(一)颜色分类

在这里插入图片描述

思路

类似快排吧,双指针,一个指0,一个指2,i遍历,遇1,++,遇0交换,遇2交换,但i不变

代码

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n0=0, n2 = nums.size()-1, i;
        for(i=0; i<=n2; i++)
        {
            if(nums[i]==0) swap(nums[n0++],nums[i]);
            else if(nums[i]==2) swap(nums[i--],nums[n2--]);
           
        }
    }
};

动态规划

(一)跳跃游戏

思路

额,似乎暴力解得。。

代码

class Solution {
public:
    bool judge(vector<int>& nums, int pos)
    {
        if(pos==0) return true;
        for(int i=0; i<pos; i++)
        {
            if(pos-i<=nums[i]) return judge(nums,i);
        }
        return false;
    }
    bool canJump(vector<int>& nums) {
        return judge(nums,nums.size()-1);
    }
};
发布了7 篇原创文章 · 获赞 0 · 访问量 88
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览