任务1:1~2天
1.学习目标
自己知识还是有很多不足,学习这个课程还是有难度的,身边真的是有很多优秀的人,希望可以跟随你们的脚步好好学习。
1.1 数组
实现一个支持动态扩容的数组
实现一个大小固定的有序数组,支持动态增删改操作
实现两个有序数组合并为一个有序数组
学习哈希表思想,并完成leetcode上的两数之和(1)及Happy Number(202)!(要求全部用哈希思想实现!)(选做)
1.2 链表
实现单链表、循环链表、双向链表,支持增删操作
实现单链表反转
实现两个有序的链表合并为一个有序链表
实现求链表的中间结点
1.3 LeetCode练习题
数组
Three Sum(求三数之和,第15题,难度:Medium)
英文版:Loading…
中文版:Loading…
Majority Element(求众数,第169题,难度:Easy)
英文版:Loading…
中文版:Loading…
Missing Positive(求缺失的第一个正数,第41题,难度:hard)
英文版:Loading…
中文版:Loading…
链表
Linked List Cycle I(环形链表,第141题,难度:Easy)
英文版:Loading…
中文版:Loading…
Merge k Sorted Lists(合并 k 个排序链表,第23题,难度:hard)
英文版:Loading…
中文版:Loading…
2.学习过程
2.1数组
2.1.1实现一个支持动态扩容的数组
class dyArray(object):
def __init__(self, obj, capacity=10):
self._data_type = obj
self._data = [None] * capacity
self._size = 0
def __str__(self):
return f"size: {self._size}, " \
f"capacity: {len(self._data)}\n{str(self._data[:self._size])}"
def _resize(self, new_cap):
if new_cap == 0:
raise ValueError('capacity can not be zero!')
new_data = [None] * new_cap
new_data[:self._size] = self._data[:self._size]
self._data = new_data
def push(self, v, k):
if self._size == len(self._data):
self._resize(2*self._size)
for i in range(self._size-1, k-1, -1):
self._data[i+1] = self._data[i]
self._data[k] = v
self._size += 1
if __name__ == '__main__':
A = dyArray(int)
for i in range(12):
A.push(i, i)
print(A.__str__())
2.1.2实现一个大小固定的有序数组,支持动态增删改操作
class dyArray(object):
def __init__(self, obj, capacity=10):
self._data_type = obj
self._data = [None] * capacity
self._size = 0
def __str__(self):
return f"size: {self._size}, " \
f"capacity: {len(self._data)}\n{str(self._data[:self._size])}"
"""
def _resize(self, new_cap):
if new_cap == 0:
raise ValueError('capacity can not be zero!')
new_data = [None] * new_cap
new_data[:self._size] = self._data[:self._size]
self._data = new_data
"""
# 增
def insert(self, v, k):
#if self._size == len(self._data):
#self._resize(2*self._size)
if k >= len(self._data):
raise IndexError('Index out of range!')
for i in range(self._size-1, k-1, -1):
self._data[i+1] = self._data[i]
self._data[k] = v
self._size += 1
def push_last(self, v):
self.insert(v, self._size)
def push_first(self, v):
self.insert(v, 0)
# 删
def delete(self, k):
value = self._data[k]
for i in range(k+1, self._size):
self._data[i - 1] = self._data[i]
self._size -= 1
return value
def delete_ele(self, v):
key = self.find(v)
if key != -1:
return self.delete(key)
# g改
def set(self, k, v):
self._data[k] = v
# 查
def find(self, v):
for idx, item in enumerate(self._data):
if item == v:
return idx
return -1
if __name__ == '__main__':
A = dyArray(int)
for i in range(10):
A.insert(i, i)
print(A.__str__())
A.delete(5)
print(A.__str__())
A.set(3,100)
print(A.__str__())
A.find(8)
2.1.3实现两个有序数组合并为一个有序数组
def merge(a, b):
indexa = 0
indexb = 0
li = []
while indexa < len(a) and indexb < len(b):
if a[indexa] <= b[indexb]:
li.append(a[indexa])
indexa += 1
else:
li.append(b[indexb])
indexb += 1
li = li + a[indexa:] + b[indexb:]
return li
if __name__ == '__main__':
b = [1,2,3,6,7,8,9,101]
a = [2,4,5,9,100]
print(merge(a,b))
2.2链表
2.2.1实现单链表、循环链表、双向链表,支持增删操作
class LNode: # 定义节点类
def __init__(self, elem, next_=None):
self.elem = elem
self.next = next_
class LList: # 定义单链表类
def __init__(self):
self._head = None
# 增,包括链表头、尾和中间位置三种方法
def prepend(self, elem):
self._head = LNode(elem)
def append(self, elem):
if not self._head:
self._head = LNode(elem)
return
p = self._head
while p.next:
p = p.next
p.next = LNode(elem)
def insert(self, elem, key):
tmp = LNode(elem)
p = self._head
for i in range(key-1):
p = p.next
tmp.next = p.next
p.next = tmp
# 删,也是三种方法
def delete(self, key):
# todo: key边界限制待添加
p = self._head
for i in range(key - 1):
p = p.next
p.next = p.next.next
def print_all(self):
p = self._head
while p :
print(p.elem, end='')
if p.next:
print('->', end='')
p = p.next
print('')
class CList: # 定义循环链表类
def __init__(self):
self._head = LNode(None)
self._head.next = self._head
self._rear = self._head
def insert(self, key, value):
tmp = LNode(elem)
p = self._head
for i in range(key-1):
p = p.next
tmp.next = p.next
p.next = tmp
if tmp.next == self._head:
self._rear = tmp
def delete(self, key):
# todo:key边界
p = self._head
for i in range(key-1):
p = p.next
if not p:
print('WRONG POSITION!')
return
tmp = p.next
p.next = p.next.next
del tmp
if p.next ==self._head:
self._rear = p
class DLNode(LNode): # 定义双链表节点
def __init__(self, elem, next_=None, prev=None):
super(DLNode, self).__init__()
self.prev = prev
if __name__ == '__main__':
l = LList()
for i in range(10):
l.append(i)
l.print_all()
l.insert(50, 3)
l.print_all()
l.delete(10)
l.print_all()
2.2.2实现单链表反转
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
prev = None
cur = head
while cur:
nxt = cur.next
cur.next = prev
prev = cur
cur = nxt
return prev
2.2.3实现两个有序的链表合并为一个有序链表
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
l3 = ListNode(0)#空链表
cur = l3
while (l1 != None) & (l2!=None):
if l1.val <= l2.val:
cur.next = l1
l1 = l1.next
else:
cur.next = l2
l2 = l2.next
cur = cur.next
if l1 != None:
cur.next = l1
if l2 != None:
cur.next = l2
l3 = l3.next
return l3
2.2.4实现求链表的中间结点
def find_middle_node(head):
slow, fast = head, head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
return slow
2.3LeetCode练习题
2.3.1求三数之和
class Solution:
def threeSum(self, nums):
nums.sort()
ans = []
left = 1
right = len(nums)-1#首先设置左右指针
cur = 0
for i in range(0,len(nums)):
if i==0 or nums[i]>nums[i-1]:
if nums[i]<=0:#如果扫描到大于0的就停下
cur = i
left =i+1#从当前位置下一个开始
right = len(nums)-1
while right>left:
sum = nums[cur]+nums[left]+nums[right]
if sum==0:#只有=0时才会出现重复情况
ans.append([nums[cur],nums[left],nums[right]])
left+=1
right-=1
while left<right and nums[left]==nums[left-1]:
left+=1
while left<right and nums[right]==nums[right+1]:
right-=1
elif sum>0:
right-=1
else:
left+=1
return ans
if __name__ == '__main__':
a = Solution()
a.threeSum([0,0,0,0])
2.3.2求众数
方法一,最常规的方法,但是占用内存较多
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
order = list(set(nums))
count = []
length = len(nums)
for i in order:
a = 0
for j in range(0,length):
if nums[j] == i:
a+=1
count.append(a)
index = count.index(max(count))
return order[index]
##方法二,摩尔投票法,相同+1,不同-1,为0换数
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
count= 0
for num in nums:
if count == 0:
temp = num
if num == temp:
count += 1
else:
count -= 1
return temp
3.参考链接
数组和链表参考:https://note.youdao.com/ynoteshare1/index.html?id=6b47b08c91b05db6c33fe92b88b53192&type=note#/
求三数之和:https://github.com/LauraWong233/Datawhale-datastructure-LinkedList/blob/master/threesum.py
求众数:https://github.com/LauraWong233/Datawhale-datastructure-LinkedList/blob/master/majorityElement.py