LeetCode1.两数之和(2019.2.17日)
直接思路:暴力求解
从list的两端开始遍历,一直遍历到两端指向同一个元素,如果遍历过程中找到了两个元素之和等于target,返回索引,没有则将首端的指针指向下一个元素。显然算法复杂度为O(n2)
class Solution:
def twoSum(self, nums, target):
""" :type nums: List[int] :type target: int :rtype: List[int] """
length = len(nums)
for i in range(length-1):
for j in range(length-1,i,-1):
if nums[i] +nums[j] == target:
return [i,j]
改进算法:哈希表
将每个值的索引存入哈希表中,遍历list的每一元素value,求出target-value值,用这个值去哈希表中寻找对应的索引,找到即返回。算法复杂度为O(n)
class Solution:
def twoSum(self, nums, target):
""" :type nums: List[int] :type target: int :rtype: List[int] """
hashmap = {}
for i,value in enumerate(nums):
tmp = target - value
if tmp in hashmap:
return [i,hashmap[tmp]]
hashmap[value] = i
LeetCode7.整数反转
思路:获得每个位上的数字,具体可以通过%10操作获得个位数字压入队列中,再整除10,再%10获得十位上的数字,直到最后一位,将最后一位压入队列中。如果整数小于0,预先把符号保存下来,正数就不需要管。其次就是120,1230这种最后以0结尾的数,在反转后的数字第一位不能是0,所以我们需要从队列第一个不为0的数字开始恢复,依次将队列里面的数字出队,乘以10,再加上下一个出队数字,再乘以10。最后还要检查反转后的数字是否溢出!有个测试样例1534236469反转后的9646327351就溢出了。
class Solution:
def reverse(self, x):
""" :type x: int :rtype: int """
tmp = []
flag1 = 1
if x < 0:
x *= -1
flag1 = -1
if -10<x<10:
return x*flag1
flag = 1
while(flag):
count = x % 10
tmp.append(count)
x = x // 10
if x < 10:
flag = 0
tmp.append(x)
newx,counts = (0,0)
for i in range(len(tmp)):
if tmp[i] != 0:
counts = i
break
for j in range(counts, len(tmp)):
newx += tmp[j]
if j != len(tmp)-1:
newx *= 10
if -2**31<newx*flag1<2**31 -1:
return newx*flag1
else:
return 0
LeetCode9.回文数
思路:这其实是一个字符串反转的问题,没什么好说的。python中字符串反转的方法还有递归的思路,用栈,用字符串的分片操作,还有reversed函数一共五种,具体参考这个网址。
class Solution:
def isPalindrome(self, x):
""" :type x: int :rtype: bool """
x_str = str(x)
y_str = ""
for i in x_str:
y_str = i + y_str
count = 0
for i in range(len(x_str)):
if x_str[i] == y_str[i]:
count += 1
if count == len(x_str):
return True
else:
return False
LeetCode13.罗马数转换成整数
思路:这个问题我们可以直接将罗马数字和整数之间转换关系用字典表示,然后再判断"IV",“IX”,“XL”,“XC”,“CD”,"CM"这六种特殊情况。罗马数字转换到整数直接将每个字符串按位相加就可以了。
Tips:我的解法有个小问题就是需要注意判断那六种特殊情况是,需要加上"索引i大于0"条件,不加的话,碰到”XXVII“这类会输出25而不是27,因为第一个”X“会被判定为8而不是10
class Solution:
def romanToInt(self, s):
""" :type s: str :rtype: int """
index_dic={'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
value_int=0
for i,value in enumerate(s):
if s[i] == 'V' and s[i-1] == 'I' and i > 0:
value_int += 3
elif s[i] == 'X' and s[i-1] == 'I' and i > 0:
value_int += 8
elif s[i] == 'L' and s[i-1] == 'X'and i > 0:
value_int += 30
elif s[i] == 'C' and s[i-1] == 'X'and i > 0:
value_int += 80
elif s[i] == 'D' and s[i-1] == 'C'and i > 0:
value_int += 300
elif s[i] == 'M' and s[i-1] == 'C'and i > 0:
value_int += 800
else:
value_int += index_dic[s[i]]
return value_int
LeetCode14.最长公共前缀
算法:我的算法解这道题基于一个前提:最长的公共前缀的长度必定小于等于字符串数组中最短的那个字符串。所以先用字符串排序取得最短长度的字符串a。按顺序取出a的每一位,与字符串数组剩下的每一个字符串同样的位置比较是否相等,相等则将这一位存储到list中,继续比较,如果不相等就不需要继续比较了。此时判断list中有0个字符还是大于0个字符,一个字符就返回”“(第一个字符就不相等),多个字符就返回除了当前字符以外别的字符(因为当前字符不相等)。如果最短字符串的所有字符都比较完毕,那么久输出这个最短字符即可。
注意需要判断[]和[""]这两种情况。需要进行特判。我的这个算法在时间复杂度上是最优算法。
class Solution:
def longestCommonPrefix(self, strs: 'List[str]') -> 'str':
if len(strs) == 0:
str = ""
return str
strs.sort(key=len)
short_list = []
if strs[0] == "":
str = ""
return str
for i in range(len(strs[0])):
tmp=strs[0][i]
short_list.append(tmp)
flag = 0
for j in range(len(strs)):
if strs[j][i] != tmp:
flag = 1
if flag and len(short_list)==0:
str = ""
return str
elif flag and len(short_list) > 0:
str = "".join(short_list[:-1])
return str
if i == len(strs[0])-1:
str = "".join(short_list)
return str