LeetCode-Easy1.1:两数之和、整数反转、回文整数
开新坑
各路师兄建议早点开刷,积累才是关键,虽然论文方向还没着落,但是以后该做的准备得做好。
Easy篇
对于一个自学完数据结构和算法的新手,Easy篇的难度足以让人捶胸顿足。我把难度的定义不在于你做不出来,而是吸收别人的精华的难度。虽然是一个简单的小功能,但照师兄说的,如何优化到极致才是关键的。
两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1]= 2 + 7 = 9 所以返回 [0, 1]
大体瞅一眼,其实是两个for循环就能解决的事情,O(n2)的时间复杂度让这个题的没办法从算法角度的去优化,而HashTable这种数据结构成为解决这个问题的关键。
解法:两次遍历
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { map<int,int> a; for(int i = 0; i<nums.size();++i) a.insert(map<int,int>::value_type(nums[i],i)); for(int i = 0;i<nums.size();++i){ if(a.count(target-nums[i])>0&&a[target-nums[i]]!=i) return {i,a[target-nums[i]]}; } return {0,0}; } };
哈希表的key用来存储nums的各个值,value用来存储nums的下标,先将映射关系保存到哈希表a中。这要对nums遍历一次。
然后对nums的每个元素进行遍历,直接搜索哈希表中有没有target-nums[i]这个键值,这里对nums遍历一次。
所以,这个地方成为了代码降低时间复杂度的关键,传统的两次for循环的第二次for循环就是为了在列表中逐个比较才能知道是否有target-nums[i],而哈希表是直接通过target-nums[i]计算存储位置(count方法)。一个是逐个找,另一个是直接算,二者的时间复杂度不言而喻,
改进:一次遍历
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { map<int,int> a; for(int i = 0;i < nums.size(); ++i){ if(a.count(target-nums[i])>0&&a[target-nums[i]] != i) return{a[target-nums[i]],i}; a.insert(map<int,int>::value_type(nums[i],i)); } return{0,0}; } };
相对于两次遍历,一次遍历是在计算存储位置之后,如果哈希表中没有满足条件的key值,就顺便插入新的键值对,如果满足条件就直接返回。二者实质相同,后者更加优美。
整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0
示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: 21
这个当年计算机二级考了无数遍,但是均没有考虑溢出的情况。但是这个题难度纯粹是考察对内置类型的运用,关键是对于溢出的解决。
解法:除10保留余数和商
最传统的解法就是这个,但是考虑不周的同学可能依然会用32位的内置类型(int)存储整数反转的结果sum。
虽然这种方法可以通过绝大部分的测试用例,但仍然有一小部分测试用例没办法通过。
例如231-1=2147483647,-231=-2147483648,如果选择231-1=2147483647作为需要翻转的数字,那么翻转到最后一位的时候就会溢出报错。
所以最简单的解决方法就是在做翻转计算的时候,sum的类型采用long型,返回之前判断转换成int是否溢出即可。
#define Integer_MAX_VALUE 2147483647 #define Integer_MIN_VALUE -2147483647 class Solution { public: int reverse(int x) { long sum = 0; while(x!=0){ sum = sum*10+x%10; x = x/10; } if(sum<Integer_MIN_VALUE||sum>Integer_MAX_VALUE) return 0; return sum; } };
回文整数
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。 示例 3: 输入: 10 输出: false 解释: 从右向左读, 为 01 。因此它不是一个回文数。
此题将各位数字转换成字符串,然后用字符串判断回文的算法去解决没有任何问题,但就时间复杂度而言,以上做法将各位数字遍历两次。
其实如果没有上一题的铺垫,那么这一题很容易就陷入思维定势。实际上,翻转以后依然是数字,只需考虑翻转以后是否相等即可。
解决:先翻转,后比较,
显然,题干上就是误导我们用判断字符串回文的方法去解题(不然-121反转成121-考虑成整数翻转求解也太不符合常理了…)
因此,负数翻转一定不符合题干中的回文要求,剩下的就是对正整数的翻转比较。
class Solution { public: bool isPalindrome(int x) { if(x<0) return false; long b = 0; int x1 = x; while(x){ b = b*10+x%10; x = x/10; } if(x1 != b) return false; return true; } };
当然,翻转的时候要注意第二题中在计算sum时会溢出的情况,事先用long型避免掉这个问题。
其次,这个题只是值比较,不需要32位值返回,因此也不需要做溢出比较。
- 点赞
- 收藏
- 分享
- 文章举报
- leetcode-Easy(JAVA)7.整数反转
- leetcode之O(1)空间复杂度判断一个整数是否是回文整数
- leetcode NO.7 整数反转 腾讯精选练习50
- LeetCode刷题--整数反转(简单)
- LeetCode题解(python)-7. 整数反转
- LeetCode第七题整数反转-c语言
- 【leetcode】7.整数反转
- C语言刷LeetCode:简单篇:整数反转
- leetcode 腾讯精选练习(50 题)4.整数反转
- leetcode第七题:整数反转
- Java&LeetCode 初入门——007. 整数反转
- LeetCode 7.整数反转(Java)
- LeetCode第7题:整数反转 之 先从简单刚起(C++)
- 【leetcode】Reverse Integer整数反转----Java代码实现
- Leetcode(7)之整数反转
- LeetCode 整数反转
- leetcode-整数反转
- LeetCode每日一题——T7. 整数反转(易):反转字符串
- Leetcode(7) - 整数反转 - java版
- LeetCode-7-反转整数-c# 版本