以后准备找算法岗工作,才开始刷leetcode,果然是渣渣一枚,慢慢刷题吧。记录一下刷题的过程吧。
第一题:两数之和
解法1:暴力搜索法
Python3:
# -*- coding: utf-8 -*-
"""
Created on Mon Aug 19 13:52:35 2019
@author: cc
"""
'''leetcode两数之和'''
class Solution:
def twoSum(self,List, target):
for i in range(len(List)):
diff=target-List[i]
for j in range(i+1,len(List)):
if diff == List[j]:
print(i,j)
return i,j
print('None')
return False
暴力搜索法用了两个for循环,所以时间复杂度是O(n^2)。
2.一次循环法
class Solution:
def twoSum(self,List, target):
for i in range(len(List)):
diff=target-List[i]
if diff in List:
if i!=List.index(diff):
print(i,List.index(diff))
return i,List.index(diff)
值使用了一个for循环,时间复杂度是O(n)。
3.Python中的字典法
Python中的字典结构本身就属于一种哈希表,官方文档中给的方法也有利用一次哈希表的。
class Solution:
def twoSum(self,List, target):
dict={}
for i in range(len(List)):
diff=target-List[i]
if diff in dict:
print(dict[diff],i)
return i,dict[diff]
else:
dict[List[i]]=i
时间复杂度同样为O(n)。
第二题 两数相加
这道题没有什么技巧上的东西,注意的几个坑就是空链表和进位以及最高位可能存在进位的问题。
解法:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
if l1 is None:
return l2
if l2 is None:
return l1
carry=0 #进位
head=ListNode(0)
l3=head
while l1 or l2 or carry:
sum_ ,carry=carry, 0
if l1 is not None:
sum_=l1.val+sum_
l1=l1.next
if l2 is not None:
sum_=sum_+l2.val
l2=l2.next
if sum_>=10:
carry=1
sum_=sum_-10
l3.next=ListNode(sum_)
l3=l3.next
return head.next
时间复杂度是O(max(m,n)),m和n是两个链表的长度。空间复杂度也是O(max(m,n)),新链表长度最多为max(m,n)+1。
第四题 寻找两个有序数组的中位数
这道题看完之后,因为题目要求时间复杂度是O(log(m+n)),所以第一反应是二分法查找,根据二分法的思路大概想了一下,但是有些地方没有相通,所以最后也没写出来,看了官方的解法,核心也是二分查找,这里对官方解法进行梳理,并贴上官方解法。
分析:(编辑公式太麻烦,加上本人习惯手推,所以这里就放上扫描的手推分析版)
解法:python3
def median(A, B):
m, n = len(A), len(B)
if m > n:
A, B, m, n = B, A, n, m
if n == 0:
raise ValueError
imin, imax, half_len = 0, m, (m + n + 1) / 2
while imin <= imax:
i = (imin + imax) / 2
j = half_len - i
if i < m and B[j-1] > A[i]:
# i is too small, must increase it
imin = i + 1
elif i > 0 and A[i-1] > B[j]:
# i is too big, must decrease it
imax = i - 1
else:
# i is perfect
if i == 0: max_of_left = B[j-1]
elif j == 0: max_of_left = A[i-1]
else: max_of_left = max(A[i-1], B[j-1])
if (m + n) % 2 == 1:
return max_of_left
if i == m: min_of_right = B[j]
elif j == n: min_of_right = A[i]
else: min_of_right = min(A[i], B[j])
return (max_of_left + min_of_right) / 2.0
作者:LeetCode
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xun-zhao-liang-ge-you-xu-shu-zu-de-zhong-wei-shu-b/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这道题如果题目没有要求O(1)空间复杂度,解答会非常简单。但是要求了空间复杂度,要求在原列表上操作,这时候可以考虑使用双指针法。另外,题目中还说元素顺序可变,那么就可以利用双指针,遍历列表,将列表中等于指定值的数字进行交换,从而保证列表前面的元素均不等于指定元素。
python3实现如下:
def removeElement(nums,val):
i=0
for j in range(len(nums)):#i,j为快慢指针
if nums[j]!=val:
nums[i]=nums[j]
i+=1
return i