由于刚开始练习,所以比较菜。python学了感觉跟没学一样,所以想找些题来练习练习。日后将会不断的更新,如果哪位大神有更好的思路可以在评论区留言。
1. 两数之和
解题思路:由于刚开始,算法知道的比较少,所以就想来分享一下大神们的思路,20个案例用时40ms。他的思路是这样的:建立一个用来存放检查的字典,用target去逐个减去nums列表里的值,将这些差值存入字典,然后遍历列表nums,如果之后遇到的数字有和字典中的值一样,那么输出字典中之所对应的key(被减数的索引)和当前数的索引。
代码如下
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
check={}
for i in range(len(nums)):
if nums[i] in check:
return [check[nums[i]],i]
else:
check[target-nums[i]]=i
2. 两数相加
解题思路:之前没有怎么学过链表,对链表不是很懂,在查阅了一些资料之后,稍微有些理解了。如果有说的不对的地方欢迎纠正指导。首先要知道单链表由两部分组成:元素和指针,元素是用来存放数据的,指针是用来存放下一个节点元素的地址。
两数相加就意味着两个链表对应节点的元素值相加。在代码前五行就定义了一个链表,self.val为元素的值,self.next为指针。在写代码的过程中要注意设一个负责进位的变量。具体的代码流程我在代码中加具体的注释。
代码如下
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
#先初始化temp链表,l3链表指向temp的0值地址
temp = ListNode(0)
l3 = temp
a = 0 #进位的数字
#当l1不为空或者l2不为空或者a不等于0的时候
while l1 != None or l2 !=None or a != 0:
if l1 != None:
#a等于a加上l1当前的值
a += l1.val
#l1的指针指向下一个元素,下次调用l1.val就是下一个元素的值
l1 = l1.next
if l2 != None:
a += l2.val #把l2和l1相应节点的值相加赋给a
l2 = l2.next
#temp的下一个的值就是 a%10
temp.next = ListNode(a%10)
temp = temp.next
a=a//10
#l3代替temp来输出链表
return l3.next
另外一种写法的代码
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
# 如果有一个链表为空,返回另外一个
if l1 is None:
return l2
if l2 is None:
return l1
# tmp是暂存(temporal)
tmp = ListNode(0) # 引用ListNode类定义了一个链表节点并赋给tmp
# res是重置(reset)
res = tmp # 赋值
# flag 标示
flag = 0 # 初始化
while l1 or l2: # l1或l2不为空就持续执行
tmp_sum = 0 # 链表节点值的和
if l1: # 如果l1不为空,把l1的某个节点值的和赋给tmp_sum
tmp_sum = l1.val # 把l1的某个节点的值赋给tmp_sum
l1 = l1.next
if l2: # 如果l2不为空,把l2中和l1对应的节点的值加到tmp_sum
tmp_sum += l2.val
l2 = l2.next # 指向下一个节点,为下一次的加和做准备
tmp_res = ((tmp_sum + flag) % 10) # 个位数字
flag = ((tmp_sum + flag) // 10) # 进位的数
res.next = ListNode(tmp_res)
res = res.next # res后移
if flag: # 如果flag不为0,就是对应位置相加后有进位
res.next = ListNode(1) # res的下一节点设为1
res = tmp.next # 赋值
del tmp # 删除tmp变量
return res # 返回res链表
7.反转整数
自己的解题思路:首先将输入的有符整数转换为字符串,然后进行判断,正数直接反转,负数去除符号后进行反转,最后将反转后的字符串转换为整数进行输出,在返回的时候加一个判断数字范围的条件。大神的解题思路和我们的差不多,不过他的代码更为简便。
自己代码如下
class Solution:
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
str_x = str(x)
if '-' in str_x:
flip = str_x[1:][::-1]
result = -int(flip)
else:
flip = str_x[::-1]
result = int(flip)
return result if -2147483648 < result < 2147483647 else 0
大神代码如下
class Solution:
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
flag = 0
if x > 0:
flag = 1
else:
flag = -1
s = str(abs(x))[::-1]
n = int(s) * flag
return n if n.bit_length() < 32 else 0
8. 字符串转整数 (atoi)
这个代码调的我真的要吐了,由于自己的逻辑性不好,所以调了有六七次才通过。希望自己以后在考虑问题的时候逻辑性强一些,考虑问题全一些。
解题思路:按照题目的要求一步一步来,先移除字符串句首的空格,如果句首如果为+或者-,那么就从字符串的第二个字符开始后续工作,如果为空字符就返回0,然后逐位进行遍历判断,是数字就保留,不是数字就截止,最后进行判断,空字符返回0,是数字进行返回并进行范围考虑。
代码如下:
class Solution:
def myAtoi(self, str):
"""
:type str: str
:rtype: int
"""
str = str.strip()
if not str:
return 0
num = ['0','1','2','3','4','5','6','7','8','9',]
flag = 1
if (str[0] == '-'):
str = str[1:]
flag= -1
elif(str[0] == '+'):
str = str[1:]
for x in range(len(str)):
if str[x] not in num:
str = str[0:x]
break
if str == '':
return 0
result = int(str)*flag
if result < -2**31:
return -2**31
elif result > 2**31-1:
return 2**31-1
else:
return result
直接上前几名的代码,思路也非常明确。直接从字符串开始一位一位判断,不去转换为整数。
class Solution:
def myAtoi(self, str):
"""
:type str: str
:rtype: int
"""
if (str == ""):
return 0
res = ''
index = 0
while index < len(str) and str[index] == ' ':
index += 1
if index < len(str) and str[index] in '-+':
res += str[index]
index += 1
while index < len(str) and str[index] in '0123456789':
res += str[index]
index += 1
if (res == '' or res == '+' or res == '-'):
return 0
if (int(res) > 2**31 - 1):
return 2**31 - 1
elif (int(res) < -2**31):
return -2**31
else:
return int(res)
网上还有另外一种思路,就是调用re库 https://www.cnblogs.com/zjltt/p/6955965.html?from=singlemessage&isappinstalled=0 ,这样的话代码用时比较长。他的代码如下:
class Solution:
def myAtoi(self, str):
"""
:type str: str
:rtype: int
"""
import re
res = re.findall(r"^[\+\-]?\d+",str.strip())
print(res)
if res !=[]:
if int(res[0]) > (2**31-1):
return (2**31-1)
if int(res[0]) < (-2**31):
return (-2**31)
return int(res[0])
else:
return 0
9. 回文数
解题思路:这道题有两种解法。1、常规的解法就是将输入的整形数转换为字符串,再将字符串进行反转,之后与原数进行判断。2、第二种方法是采用数学的方法。方法为逐次整除,将余数提取出来带入,重新组建数字,不断乘以10去加上新算出的余数,如果是回文数字,那么新组建的数字就和输入的一样。
注意:python中" / "就表示 浮点数除法,返回浮点结果;" // "表示整数除法
方法一代码如下
class Solution:
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
x = str(x)
x1 = x[::-1]
if x == x1 :
return True
else:
return False
方法二代码
class Solution:
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
if x > 0:
n,newed = 0,0
n = x
while x > 0:
newed = newed *10 + x % 10
x = x//10
if newed == n:
return True
else:
return False
elif x == 0:
return True
elif x < 0:
return False
看了第一名的代码不得不佩服是大佬,请欣赏大佬的表演
class Solution:
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
if x < 0:
return False
else:
return int(str(x)[::-1]) == x
13、罗马数字转整数
解题思路:首先要读懂题目,对于罗马这7个字符要熟悉,应该要想到使用字典去构建这个罗马数字转字符的储存,接着去读懂罗马数字规则,前面这个数字比后面数字大就正常加上这个数字本身值,如果小的话就用后面这个数字减去前面这个数字的值。初步的想法就是去遍历每一个字符,与其后面的字符比较,将结果加入总和中,最后存在一个问题,最后一个数字没有办法加上,在返回值中加入最后一个数字在比如IV这样的案例中会重复计算。所以转换一下想法,在总和的基础上只添加当前这个数字,比后面大的话为+号,比后面小的话为-号。
我的代码如下:
class Solution:
def romanToInt(self, s):
"""
:type s: str
:rtype: int
"""
sum = 0
convert = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
for i in range(len(s)-1):
if convert[s[i]] >= convert[s[i+1]]:
sum = sum + convert[s[i]]
else:
sum = sum - convert[s[i]]
return sum+convert[s[-1]]
这种方法耗时太长,将sum = sum - convert[s[i]]写为sum -= convert[s[i]]会节约一些时间,我看用时比较快的人写法是将可能出现的情况都列入字典中,减少了计算的过程,然后从输入的字符中从前往后遍历。遍历的过程中分为两种情况,一种两个字符,一种一个字符,然后在字典中寻找相应的值相加。代码如下
class Solution:
def romanToInt(self, s):
"""
:type s: str
:rtype: int
"""
convert = {"I":1,"IV":4,"V":5,"IX":9,"X":10,"XL":40,"L":50,"XC":90,"C":100,"CD":400,"D":500,"CM":900,"M":1000}
len_n = len(s)
n = 0
i = 0
while(i < len_n):
key = s[i:i+2]
if key in convert:
n+=convert[key]
i+=2
continue
key = s[i]
if key in convert:
n+=convert[key]
i+=1
return n