1,Two_Sum
第一题的最优做法是模拟哈希表,在python中有字典可以很好地做到这件事情:
所以最初的想法应该是这样的,
class Solution(object):
def twoSum(self, nums, target):
hashmap = {}
for idx, num in enumerate(nums):
hashmap[num] = idx
for i, num in enumerate(nums):
j = hashmap.get(target - num)
if j is not None and i != j:
return [i, j]
第一个for循环构建字典将所有的值储存一下
第二个for循环可以查出所需的索引
注意:in 和 .get的使用
但是可以用一遍循环来更好地解决问题
更好地使用in,可以做优化:
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
dict = {}
for idx,num in enumerate(nums):
cp = target - num
if cp in dict:
return [dict[cp],idx]
else:
dict[num] = idx
2, 两数之和
这一道题主要使用了链表,要注意链表类型的构建,
r储存了进位的数字,
在每一次收集完total之后,分别把total拆分为r和cur.next的val部分
这里节点的移动靠的是next创造一个新的节点
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def addnums(self, l1: ListNode, l2: ListNode) -> ListNode:
# -> 用于描述函数返回的数据类型。
res = cur = ListNode()
reminder = 0
while l1 or l2:
x = l1.val if l1 else 0
y = l2.val if l2 else 0
total = x + y + reminder
cur.next = ListNode(total % 10)
reminder = total // 10
if l1: l1 = l1.next # 节点向后推进
if l2: l2 = l2.next
cur = cur.next
if reminder: cur.next = ListNode(reminder)
return res.next
3,无重复字符的最长子串
见滑动窗口一文~
4, 寻找中位数
tag:二分查找
class Solution:
def binarysearch(self, nums1, nums2):
def getKthelement(k):
idx1, idx2 = 0, 0
# 处理特殊情况,指针指向某一个序列的末尾或者k == 1
while True:
if idx1 == m:
return nums2[idx2 + k - 1]
if idx2 == n:
return nums1[idx1 + k - 1]
if k == 1:
return min(nums1[idx1],nums2[idx2])
newidx1 = min(idx1 + k // 2 - 1, m - 1)
newidx2 = min(idx2 + k // 2 - 1, n - 1)
value1, value2 = nums1[newidx1], nums2[newidx2]
if value1 <= value2 :
k -= newidx1 - idx1 + 1
idx1 = newidx1 + 1
else :
k -= newidx2 - idx2 + 1
idx2 = newidx2 + 1
m, n = len(nums1), len(nums2)
total = m + n
if total % 2 == 1:
return getKthelement(total // 2 + 1)
else:
return (getKthelement(total // 2) + getKthelement(total // 2 + 1))/2
需要注意的是两种特殊情况的判断,k == 1,有一段序列提前到末尾,都是整个函数的出口,需要好好思考一下,
这里体现了截短数列的示意图,比较直观~