class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
num1, num2 = 0, 0
order = 1
while l1:
num1 += l1.val * order
l1 = l1.next
order *= 10
order = 1
while l2:
num2 += l2.val * order
l2 = l2.next
order *= 10
num = num1 + num2
addList = ListNode()
head = addList
if num == 0:
addList.next = ListNode(val = int(0))
else:
while num != 0:
addList.next = ListNode(val = int(num % 10))
num = num // 10
addList = addList.next
return head.next
这个解法主要是先把两数和求出来,再通过取余和取整操作拆分得到的数。这样避免了在链表层面直接操作带来的进位问题。
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
newList = ListNode() #新建一个链表存储和
head= newList #存储头节点位置
carry = 0 #carry代表是否需要进位
while l1 and l2:
addVal = l1.val + l2.val + carry
head.next = ListNode(val= addVal % 10)
carry = 1 if addVal >= 10 else 0
l1, l2, head = l1.next, l2.next, head.next
while l1:
addVal = l1.val + carry
head.next = ListNode(val= addVal % 10)
carry = 1 if addVal >= 10 else 0
l1, head = l1.next, head.next
while l2:
addVal = l2.val + carry
head.next = ListNode(val= addVal % 10)
carry = 1 if addVal >= 10 else 0
l2, head = l2.next, head.next
if carry == 1:
#要考虑当两个链表都走完还有进位的情况,最终链表的位数也许比输入两链表中的长者还多一位
#例如[9,9,9,9,9,9,9]&[9,9,9,9]
head.next = ListNode(val = 1)
return newList.next
这个解法直接在链表层面的操作,要注意进位的处理,尤其要留心当两个链表都走完还有进位的情况,如[9,9,9,9,9,9,9]&[9,9,9,9]
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
nums1.extend(nums2)
nums1.sort()
n = len(nums1)
if n % 2 == 1: #判断为奇数
return nums1[int((n-1)/2)]
else:
return (nums1[int((n-1)/2)] + nums1[int((n+1)/2)]) / 2
这个解法实际上在偷懒,直接用了python列表自带的sort函数【满足O(log(m+n))】,避开了排序过程。
关于Python List sort()方法:
list.sort(cmp=None, key=None, reverse=False)
python中的sorted/list.sort()排序,用的Timsort算法
一个补充博客
class Solution:
def longestPalindrome(self, s: str) -> str:
if len(s) <= 1:
return s
#动态规划就是维护一个表格,这里用一个二维数组表示
table = [[False for _ in range(len(s))] for _ in range(len(s))]
#表格对角线上肯定是True,因为这些元素对应着单个字符的情况
for i in range(len(s)):
table[i][i] = True
maxLength = 1 #记录最长子串的长度
start = 0 #记录最长子串的起始位置
for j in range(1, len(s)):
for k in range(0, j):
if s[k] == s[j]:
if j-k+1 <= 3:
table[k][j] = True
else:
table[k][j] = table[k+1][j-1]
#遍历顺序很重要,table[k+1][j-1]一定要在table[k][j]之前被遍历过
if table[k][j]:
if j-k+1 > maxLength:
maxLength = j-k+1
start = k
return s[start:start+maxLength]
这是我做的第一道关于动态规划的题目,参考了动态规划、中心扩散、Manacher 算法,上面的博文讲的很清晰。
动态规划就是在填一个表格,目前我理解的动态规划的几个要素:
table[k][j]
,它表示s[k,j+1]是否是回文串table[k][j] = table[k+1][j-1]
,表示s[k,j+1]是否是回文串与s[k+1,j]是否是回文串之间的关系。这可以说是最重要的一步。其实很简单,如果s[k]=s[j],且s[k+1,j]是回文串,那么s[k,j+1]一定是回文串。动态规划乍一看很像递归,都是要找到最基础的情况,都是要找情况之间的联系。但是它与递归最重要的区别是,递归到某一层的时候,这一层的问题实际并未解决,只是暂存并打开了比之更简单的一层,一直递归到最基本的问题,才逐渐开始解题。但动态规划不同,到某一个状态,它的前一个状态是已经解决的,直接根据状态转移即可求得此时状态的值,因此每一个状态在当下即可求得其取值。也因此,动态规划填充表格的顺序特别重要,即table[k+1][j-1]一定在table[k][j]之前被填充。