两数之和
要求:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
方法一:两次循环数组
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(nums)):
for j in range(i+1, len(nums)):
if nums[j] == target - nums[i]:
return [i,j]
方法一的改进:一次遍历
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(nums)): #遍历数组
diff = target - nums[i] #差值
if diff in nums[i+1:]: #若差值在i之后的元素中
tmp = nums[i]
nums[i] = "$" #临时改变numx[i],避免i等于j
j = nums.index(diff)
nums[i] = tmp
return [i,j]
方法二:使用一次hash表
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
map = {}
for i in range(len(nums)):
diff = target - nums[i] #差值
if diff in map:
return [map.get(diff), i]
map[nums[i]] = i #数组nums中元素作为键,元素的索引是对应键的值。如果键相同,新值会覆盖旧值。
注:Python 字典 get() 函数返回指定键的值,如果值不在字典中返回默认值。上述方法中if的条件原本是map.get(diff) != i and diff in map,但是在map中的键是i之前的元素,键对应的值肯定小于i。
整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下32位的有符号整数,则其数值范围为[−231, 231 −1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
思路:使用数学方法获得x的最后一位数字,再将它放在rev的后面,如此循环,最后rev与x相反。注意rev = rev*10 + pop这一步可能会导致溢出,分为两种情况:rev>INTMAX/10;rev=INTMAX/10且pop>7。Python中负数求余数不同于正数,所以统一化为正数,判断溢出的时候分开即可。负数求余数参考:实数范围内的求模(求余)运算:负数求余究竟怎么求
对于下面这种解法:先把反转的数求出来,再判断是否在[−231, 231 −1]范围内,我觉得这样不妥,因为最多存储32位有符号整数,计算的结果是不可能超过上面的范围的,计算的过程中就可能已经发生了溢出。上述做法相当于在64位环境下模拟32位计算过程。
class Solution:
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
flag = 1
if x < 0:
flag = -1
x = abs(x)
rev = 0
MAX_VALUE = 2**31-1
while x != 0:
pop = x % 10
x //= 10
if flag == 1:
if rev > MAX_VALUE//10 or (rev==MAX_VALUE//10 and pop>7):
return 0
else:
if rev > MAX_VALUE//10 or (rev==MAX_VALUE//10 and pop>8):
return 0
rev = rev*10 + pop
return rev*flag