考研复试C++上机,leetcode刷题记录

1、两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
你可以按任意顺序返回答案。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int> a;//提供一对一的hash
        vector<int> b(2,-1);//用来承载结果,初始化一个大小为2,值为-1的容器b
        for(int i=0;i<nums.size();i++)
        {
            if(a.count(target-nums[i])>0)
            {
                b[0]=a[target-nums[i]];
                b[1]=i;
                break;
            }
            a[nums[i]]=i;//反过来放入map中,用来获取结果下标
        }
        return b;
    };
};

用到的STL

#include <vector>
vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++)
	cout<<*it;//迭代器访问
vec.insert(vec.begin()+i,a);//在第i+1个元素后面插入a
vec.erase(vec.begin()+2);//删除第三个元素
#include <algorithm>
reverse(vec.begin(),vec.end());//翻转vector中的元素
sort(vec.begin(),vec.end());//默认升序排序
bool compare(const int &a,const int &b)
{
	return a>b;
}
sort(vec.bagin(),vec.end(),compare)//降序排序
#include <map>
map<int,string> hash;
hash.insert(pair<int,string>(1,""));//pair插入
map<int,string>::iterator it;
for(it=hash.begin();it!=hash.end();it++)
{
	cout<<it->first;
}//迭代器遍历
hash[i]="";//数组插入
hash.count("");//查找数据
it=hash.find("");//返回迭代器
hash.erase();//参数可以是关键字、迭代器、范围

2、整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。

class Solution {
public:
    int reverse(int x) {
        int res=0;
        while(x!=0)
        {
            int pop=x%10;
            x/=10;
            if(res>INT_MAX/10||res==INT_MAX/10&&pop>7) return 0;
            if(res<INT_MIN/10||res==INT_MIN/10&&pop<-8) return 0;
            res = res*10+pop;
        }
        return res;
    }
};

知识点
C++中,int的范围是[-231,231-1],[-2147483648,2147483647],

INT_MAX
INT_MIN

3、回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。

//刚好可以利用上一题的整数反转
class Solution {
public:
    int reverse(int x)//针对这道题只需要求正整数的翻转
    {
        int res=0;
        while(x>0)
        {
            int pop=x%10;
            x/=10;
            if(res>INT_MAX/10||res==INT_MAX/10&&pop>7)return 0;//整数范围溢出
            res=res*10+pop;
        }        
        return res;
    }
    bool isPalindrome(int x) {
        if(x<0) return false;
        if(reverse(x)==x) return true;
        return false;
    }
};

4、罗马数字转整数
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

class Solution {
public:
    int romanToInt(string s) {
        int res=0;
        char pre_s=' ';
        for(int i=0;i<s.length();i++)
        {
            switch(s[i])
            {
                case 'I':
                    res+=1;
                    pre_s=s[i];
                    break;
                case 'V':
                    res+=5;
                    if(pre_s=='I')
                        res-=2;
                    pre_s=s[i];
                    break;
                case 'X':
                    res+=10;
                    if(pre_s=='I')
                        res-=2;
                    pre_s=s[i];
                    break;
                case 'L':
                    res+=50;
                    if(pre_s=='X')
                        res-=20;
                    pre_s=s[i];
                    break;
                case 'C':
                    res+=100;
                    if(pre_s=='X')
                        res-=20;
                    pre_s=s[i];
                    break;
                case 'D':
                    res+=500;
                    if(pre_s=='C')
                        res-=200;
                    pre_s=s[i];
                    break;
                case 'M':
                    res+=1000;
                    if(pre_s=='C')
                        res-=200;
                    pre_s=s[i];
                    break;
            }
        }
        return res;
    }
};

switch语法复习:

switch(choice)
{
	case 'A':
		expression;
		break;
	case 'B':
		expression;
		break;
	default:
		expression;
}

5、最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。

class Solution {
public:
    int getminindex(vector<string> str)//返回字符串数组中最短字符串的下标
    {   
        int length=INT_MAX; 
        int index=0;
        for(int i=0;i<str.size();i++)
        {
            if(str[i].length()<=length)
                length=str[i].length();
                index=i;
        }
        return index;
    }
    string longestCommonPrefix(vector<string>& strs) {
        if(strs.empty())
            return "";
        int minlength_index=getminindex(strs);
        string res="";
        for(int i=0;i<strs[minlength_index].length();i++)
        {
            char ch=strs[minlength_index][i];
            int j;
            for(j=0;j<strs.size();j++)
            {
                if(ch==strs[j][i])
                    continue;
                else
                    return res;
            }
            if(j==strs.size())
                res+=ch;
        }
        return res;
    }
};

string知识点复习

string str="";//定义一个空串
char ch;
str+=ch;//在string后面继续增加字符
char ch=str[i];//string的遍历为char类型
str.empty();//string串判空

6、括号匹配
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

class Solution {
public:
    bool match_left(char ch)
    {
        if(ch=='('||ch=='['||ch=='{')
            return true;
        return false;
    }
    bool match(char ch1,char ch2)
    {
        if((ch1=='('&&ch2==')')||(ch1=='['&&ch2==']')||(ch1=='{'&&ch2=='}'))
            return true;
        return false;
    }
    bool isValid(string s) {
        stack<char> stk;
        for(int i=0;i<s.length();i++)
        {  
            if(match_left(s[i]))
            {
                stk.push(s[i]);
            }
            else
            {
                if(!stk.empty())
                {
                    char ch=stk.top();
                    stk.pop();
                    if(match(ch,s[i]))
                        continue;
                    else
                        return false;
                }
                else
                    return false;
            }
        }
        if(stk.empty())
            return true;
        return false;
    }
};

利用栈的思想匹配括号,用到的STL容器

#include <stack>
stack<char> stk;
char ch;
stk.push(ch);//入栈
if(!stk.empty())//注意判空
{
	ch=stk.top();//返回栈顶元素
	stk.pop();//仅出栈,不返回值
}

7、合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
法一:递归

class Solution{
public:
	ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
		if(l1==nullptr)
			return l2;
		if(l2==nullptr)
			return l1;
		if(l1->val<l2->val){
			l1->next=mergeTowLists(l1->next,l2);
			return l1;
		}
		else{
			l2->next=mergeTowLists(l2->next,l1);
			return l2;	
		}
	}
};

法二:遍历

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    ListNode *head= new ListNode(-1);
    ListNode *p=head;
    while(l1!=nullptr&&l2!=nullptr)
    {
        if(l1->val<l2->val)
        {
            p->next=l1;
            l1=l1->next;
        }
        else
        {
            p->next=l2;
            l2=l2->next;
        }
        p=p->next;
    }
    if(l1!=nullptr)
        p->next=l1;
    else
        p->next=l2;
    return head->next;
    }
};

8、并查集判断是否有回路

struct Node{
int from;
int to;
int weight;
};
int findroot(int a){
int t=a;
while(parent[t]!=-1)
	t=parent[t];
return t;
}
bool isring(vector<Node>G){
	for(int i=0;i<G.size();i++){
		int v1=findroot(G[i].from);
		int v2=findroot(G[i].to);
		if(v1==v2)
			return true;
		else
			parent[v2]=v1;
	}
	return false;
}

9、最长递增子序列

int d[max_n];
for(int i=0;i<length;i++){
	d[i]=1;
	for(int j=0;j<i;j++){
		if(a[i]>a[j])
			d[i]=max(d[i],d[j]+1);
	}
}
return d[n-1];

10、图的DFS遍历

void dfs(int v){
	vis[v]=true;//v被访问
	for(int i=0;i<n;i++){
		if(Graph[v][i]!=0&&!vis[i])
			dfs(i);
	}
}

11、Dijkstra算法,单源最短路径

void Dijkstra(int v){
	bool S[n]={false};
	S[v]=true;
	for(int i=0;i<n;i++){
		dis[i]=G[v][i];
		if(G[v][i]!=INT||i==v)
			path[i]=v;
		else
			path[i]=-1;
	}
	for(int i=0;i<n-1;i++){
		int min=INT;
		int u=-1;
		for(int j=0;j<n;j++){
			if(!S[j]&&dis[j]<INT){
				min=dis[j];
				u=j	;
			}
		}
		S[u]=true;
		for(int j=0;j<n;j++){
			if(!S[j]&&dis[u]+G[u][i]<dis[j])
				{
					dis[j]=dis[u]+G[u][i];
					path[j]=u;
				}
		}
	}
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值