LeetCode算法刷题之旅
简单题
题1 两数之和
2020/4/1 18:30
给定一个整数数组nums和一个目标值target,请你在数组中找出和为目标值的那两个整数,并返回他们的数组下标。每种输入只产生一个答案 不能重复利用相同的元素
示例
给定nums=[2,7,11,15],target=9
因为nums[0]+nums[1]=2+7=9
所以返回[0,1]
我们首先来分析题目,从一个数组里找出两个元素之和为目标值,并且返回那两个元素的下标。看起来比较繁琐,实际上很简单,暴力一点的算法就是直接两个for循环进行搜索,当然搜索的条件要有所限定,避免出现元素是同一个的情况。这里比较推荐的是使用vector容器,这是一种比较高效的做法。好了,废话不多说了,直接上代码。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int>a;
for(int i=0;i<nums.size();i++)
{
for(int j=i+1;j<nums.size();j++)//j从i+1开始搜索,避免了出现i==j的情况
{
if((nums[i]+nums[j]==target))//搜索到了
{
a.push_back(i);//i入堆
a.push_back(j);//j入堆
return a;//返回vector<int>a
}
}
}
return a;//这里是不可以缺少的,因为vector要求这里必须要有一个返回值
}
};
这样就直接通过,内存的消耗也是极小的,而在LeetCode中跟这道题目类似的还有三数之和,四数之和,方法大同小异。
题7 整数反转
2020/4/1 18:55
给出一个32位的有符号整数,你需要将这个整数中每位上的数字进行反转
示例1:
输入:123
输出:321
示例2:
输入:-123
输出:-321
示例3:
输入:120
输出:21
注意:假设我们的环境只能存储下32位的有符号整数,则其数值范围为[-2^{31} ,2^{31}-1].请根据这个假设,如果反转整数溢出后,就返回0
首先,我们需要先来分析题目,反转整数,就是把每一位拆开然后再倒序重组,这个是没问题的,不过我们需要注意的是这道题目给我们的提示,它说反转整数如果溢出之后就返回0,那我们要看看它的溢出条件,32位有符号整数的范围实际上就是从0x80000000-0x7fffffff,那我们最终只需要判断一下,它的反转整数有没有越界,越界了那么就给他置0,好了,废话不多说,直接上代码
class Solution {
public:
int reverse(int x) {
long int c=0;
int max=0x7fffffff;//32位有符号整数的最小值
int min=0x80000000;//32位有符号整数的最大值
while(x!=0)
{
c=c*10+x%10;
x/=10;
}
if(c<min||c>max)//如果反转整数越界
{
c=0;
}
return c;
}
};
做完了这一题,那么就间接地为我们的第9题提供了思路,那让我们来看看第9题的内容吧!
题9 回文数
2020/4/1 19:14
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数
示例1:
输入:121
输出:true
示例2:
输入:-121
输出:false
解释:从左向右读,为-121,从右向左读,为121-。因此他不是一个回文数。
示例3:
输入:10
输出:false
解释:从右向左读,为01。因此它不是一个回文数
进阶
你能不将整数转为字符串来解决这个问题吗?
同样,我们首先看题目,要求我们判断一个数是不是回文数,首先我们想到的方法就是把一个整数的每一位拆分下来放到一个数组里,然后再每一位的进行比较,当然这不失为一个办法,但是我们要想到,我们写代码不仅仅是创造,有些时候,一些别人已经写出来的代码我们是可以直接拿过来用的,我们以前写的代码如果可以用上去也是ok的。那我们再来看看题目,判断一个数是否是回文数,我们从示例中可以直接得到的一个就是负数肯定不是回文数,这样一来,任务就少了一半了。
那我们再来分析一下,回文数的特点,我们是不是感觉从哪里见到过?
对了,就是LeetCode的第7题,整数反转,所以我们就想,如果判断它是不是回文数,那我直接把整个数反转一下,然后再与原来的数进行比较,那么不就很轻松地得到了我们想要的结果嘛!让我们直接上代码
class Solution {
public:
int reverse(int x)//这里负责将整数进行反转
{
long int c=0;
int max=0x7fffffff;
int min=0x80000000;
while(x!=0)
{
c=c*10+x%10;
x/=10;
}
if(c<min||c>max)
{
c=0;
}
return c;
}
bool isPalindrome(int x) {
if(x<0)//负数直接返回false
{
return false;
}
long int c=reverse(x);
return (x==c);//这里直接进行比较
}
};
题13 罗马数字转整数
2020/4/2 10:29
罗马数字包含以下七种字符:I,V,X,L,C,D,M
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如,罗马数字2写作II,即为两个并列的I。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。
给定一个罗马数字,将其转换成整数。输入确保在1和3999的范围内。
示例1:
输入:"III"
输出:3
示例2:
输入:"IV"
输出:4
示例3:
输入:"IX"
输出:9
示例4:
输入:"MCMXCIV"
输出:1994
首先我们来分析一下题目,题目告诉我们罗马字符有七个,分别有不同的值,而且,如果其中小的值放在大的值左边,就表示用右边较大的那个值去减去左边那个较小的值。这样一来,我们就可以知道这个算法的核心是什么了,废话不多说,我们直接上代码!
class Solution {
public:
int getnum(char a)//每一个字符返回一个确定的整数值
{
switch(a)
{
case 'I':return 1;
case 'V':return 5;
case 'X':return 10;
case 'L':return 50;
case 'C':return 100;
case 'D':return 500;
case 'M':return 1000;
default:return 0;//如果输入的字符不在那七个之中,那么判定为0
}
}
int romanToInt(string s) {
int ans=0;
int prenum=getnum(s[0]);//首先得到其第一个字符的值
for(int i=1;i<s.length();i++)
{
int num=getnum(s[i]);
if(prenum<num)//前一个字符的值与后一个相比较
{
ans-=prenum;
}
else
{
ans+=prenum;
}
prenum=num;
}
ans+=prenum;
return ans;
}
};