2019.1.30
9. Palindrome Number
方法1(自己想的比较笨的方法):
将给的数字逆序判断与原来是否一致
class Solution:
def isPalindrome(self, x):
if x >= 0:
b = 0
y = x
while y > 0:
a = y % 10
b = b*10 + a
y //=10
if x == b:
return True
return False
Runtime: 244 ms, faster than 67.26% of Python3 online submissions for Palindrome Number.
方法2.discussion中的直接将input转化为字符串格式,将字符串逆序。
class Solution:
def isPalindrome(self, x):
return str(x) == str(x)[::-1]
Runtime: 228 ms, faster than 99.53% of Python3 online submissions for Palindrome Number.
discussion里面的C,JAVA的runtime基本都是小于100ms的,python的运行速度和基础语言差别好大。
2019.2.17
Roman to Integer
题目要求:将罗马数字字符串转换为整数形式,"I"代表1,"V"代表5,"X"代表10,"L"代表50,"C"代表100,"D"代表500,"M"代表1000。较大数字在前则表示相应数字加和,较小数字在前则代表大数字减小数字。
思路:首先需要把罗马数字所代表的含义以字典的形式储存起来,然后对字符串进行遍历,如果遍历到的字符所代表的数字大于后一个字符所代表的数字,当前整数则加上遍历到的字符所代表的数字;如果遍历到的字符所代表数字小于后一个字符所代表的数字,当前整数则减去遍历到的字符所代表的数字。遍历到倒数第二个字符停止,最终返回停止循环时的整数再加上最后一个字符所对应数字。
class Solution:
def romanToInt(self, s):
roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
integer = 0
for i in range(len(s)-1):
if roman[s[i]]< roman[s[i+1]]:
integer = integer - roman[s[i]]
else:
integer = integer + roman[s[i]]
return integer + roman[s[-1]]
Runtime: 116 ms, faster than 99.24% of Python3 online submissions for Roman to Integer.
Memory Usage: 12.7 MB, less than 100.00% of Python3 online submissions for Roman to Integer.
2.25 20. Valid Parentheses
给定关于“{}”,“[]”, "()"的字符串,判断字符串是否是有效的括号配对结果。
思路:把“{[(”存在一个list中,“}])”存在一个list中,遍历整个字符串,如果当前遍历到的字符再左括号list中,则将其存在一个栈中,若在右括号list中,则首先判断栈的长度是否为0,若不为0则栈的最后一个元素应该与当前的遍历到的字符能够配对,若配对成功则将栈的最后一个元素删除,最终遍历结束后栈中无元素即可。
class Solution:
def isValid(self, s):
left = ["(", "[", "{"]
right = [")", "]", "}"]
stack = []
if s == [" "]:
return True
for obj in s:
if obj in left:
stack.append(obj)
elif obj in right:
if len(stack) == 0:
return False
if left.index(stack.pop()) != right.index(obj):
return False
return len(stack) == 0
Runtime: 40 ms, faster than 47.54% of Python3 online submissions for Valid Parentheses.
Memory Usage: 13.1 MB, less than 5.22% of Python3 online submissions for Valid Parentheses.
想了以下,其实不需要分成左右两个list,直接用一个dict存储括号之间的对应关系可能会更加高效。
class Solution:
def isValid(self, s):
left = {")":"(", "]":"[", "}":"{"}
stack = []
if s == [" "]:
return True
for char in s:
if char in left.values():
stack.append(char)
elif char in left.keys():
if stack == [] or left[char] != stack.pop():
return False
else:
return False
return stack == []
Runtime: 40 ms, faster than 47.54% of Python3 online submissions for Valid Parentheses.
Memory Usage: 13.1 MB, less than 5.22% of Python3 online submissions for Valid Parentheses.
并没有什么提升。。。
2.26 21. Merge Two Sorted Lists
把两个list按照大小重排融合为一个list。
# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def mergeTwoLists(self, l1, l2):
if l1 is None:
return l2
if l2 is None:
return l1
if l1 is None and l2 is None:
return None
head = ListNode(0)
cur = head
while l1 and l2:
if l1.val > l2.val:
cur.next = l2
l2 = l2.next
else:
cur.next = l1
l1 = l1.next
cur = cur.next
cur.next = l1 or l2
return head.next
Runtime: 48 ms, faster than 52.71% of Python3 online submissions for Merge Two Sorted Lists.
Memory Usage: 13.2 MB, less than 5.06% of Python3 online submissions for Merge Two Sorted Lists.
3.4 26. Remove Duplicates from Sorted Array
这个题目比较特别的一点就是不能再用一个新的序列存储,所有的modify必须都是对原有的序列进行的。思路相当于是找到两个point,一个point在遍历整个list,另一个point在储存不重复的数量。当遍历到的前后都是一样的值时,point2停下不动,出现不一样时,point2+1同时将新的值赋给list[point2+1],最终返回point2的现值+1即为不重复的list长度。
class Solution:
def removeDuplicates(self, nums):
if not nums:
return 0
tail = 0
for i in range(1,len(nums)):
if nums[i] != nums[tail]:
tail +=1
nums[tail] = nums[i]
return tail+1
Runtime: 72 ms, faster than 58.40% of Python3 online submissions for Remove Duplicates from Sorted Array.
Memory Usage: 14.8 MB, less than 5.43% of Python3 online submissions for Remove Duplicates from Sorted Array.
在discussion中看到另一种解法,用到了OrderedDict.fromkeys(nums).keys(),直接将重复项去除了,答主解释nums[:]不会占用新的空间。https://leetcode.com/problems/remove-duplicates-from-sorted-array/discuss/11880/Python-2-liner-O(N)
def removeDuplicates(self, nums):
nums[:] = OrderedDict.fromkeys(nums).keys()
return len(nums)
3.6 28. Implement strStr()
class Solution:
def strStr(self, haystack, needle):
if len(needle) ==0:
return 0
if len(needle) ==0 and len(haystack) ==0:
return 0
return haystack.find(needle)
Runtime: 36 ms, faster than 82.91% of Python3 online submissions for Implement strStr().
Memory Usage: 13.2 MB, less than 5.13% of Python3 online submissions for Implement strStr().
3.6 27. Remove Element
class Solution:
def removeElement(self, nums, val):
if not nums:
return 0
nums[:] = [x for x in nums if x!=val]
return len(nums)
3.6 35. Search Insert Position
简单想法就是直接遍历整个list,比较intuitive
class Solution:
def searchInsert(self, nums, target):
for i in range(len(nums)):
if nums[i]>=target:
return i
return i+1
时间复杂度O(n)
discussion中说可以用binary search
class Solution(object):
def searchInsert(self, nums, key):
if key > nums[len(nums) - 1]:
return len(nums)
if key < nums[0]:
return 0
l, r = 0, len(nums) - 1
while l <= r:
m = (l + r)/2
if nums[m] > key:
r = m - 1
if r >= 0:
if nums[r] < key:
return r + 1
else:
return 0
elif nums[m] < key:
l = m + 1
if l < len(nums):
if nums[l] > key:
return l
else:
return len(nums)
else:
return m
还有一个据说很快的方法
def searchInsert(self, nums, target):
return sorted(nums + [target]).index(target)
2019.07.28
22. 括号生成
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
class Solution(object):
def generateParenthesis(self, n):
"""
:type n: int
:rtype: List[str]
"""
#把一组括号插入到已经生成的括号组合的某个位置即可
#首先初始化一个res的set
res = set(['()'])
for i in range(n-1): #除了初始的一个再加上n-1个括号
tmp = set() #用来存放每次加入一个括号之后的结果
for j in res: #结果集中的每一个结果都要尝试一次再各个位置加入一个括号,用set去重
tmp.update(set([j[:k]+'()'+j[k:] for k in range(len(j))]))
res = tmp #赋值给结果集
return list(res) #列表形式输出
我的提交执行用时
已经战胜 75.16 % 的 python 提交记录
24.两两交换链表中的节点
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return head
if not head.next:
return head
pre = ListNode(0)
cur = head
pre.next = head
temp = pre
while cur != None and cur.next != None:
next_ = cur.next
cur.next = next_.next
next_.next = cur
pre.next = next_
pre = cur
cur = cur.next
return temp.next
思路就是需要建立一个辅助的头节点,然后pre,cur,next三个指针进行移动
1-2-3-4变成0-1-2-3-4变成0-2-1-3-4变成0-2-1-4-3
发现while a.next!=None and a != None和while a != None and a.next != None是不一样的,应该用后者,不然会报错:NoneType object has no attribute next
执行用时 :20 ms 在所有 Python 提交中击败了88.75%的用户
内存消耗 :11.6 MB, 在所有 Python 提交中击败了43.56%的用户
31.下一个排列
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
执行用时 :32 ms, 在所有 Python 提交中击败了94.66%的用户
class Solution(object):
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
if not nums:
return nums
n = len(nums)-1
while n>0 and nums[n-1]>= nums[n]:
n-=1
#跳出循环的就是索引值最大的a[i-1]<a[i]的i,这说明i到最后一个是降序排列,然后需要在i到结尾中找到最接近a[i-1]且大于
#a[i-1]的数字a[k],直接从最后一个开始找就可以,交换a[i-1],a[k],然后对a[i:]排序,本来是逆序的,变成正序就可以。如果不存在跳出循环的值,那此时正好n-1就是0
j = len(nums)-1
if n>0:
#需要排除倒序的情况
while j >= n:
if nums[j]>nums[n-1]:
nums[n-1],nums[j] = nums[j],nums[n-1]
break
j-=1
nums[n:] = reversed(nums[n:])
return nums