笔记:代码随想录
数组
概念
存放在连续内存空间上相同类型数据的集合(内存地址、字符数组、下标)。
python中称为列表。
C++要注意vector 和 array的区别,vector的底层实现是array,严格来讲vector是容器,不是数组。
特点
数组元素不能删除,只能覆盖。
方法
双指针法(滑动窗口),二分法,行为模拟
注意一些sum和数组排序后的将问题简化的思路
1.二分法
条件:(1)有序数组;(2)数组中无重复元素。
思路:循环不变量(确定好是左闭右闭还是左闭右开)。
2. 移除元素
3. 有序数组的平方
双指针法
条件:数组、链表、字符串
思路:快指针,寻找新数组的元素,新数组就是不含目标元素的数组;慢指针,指向更新新数组下标位置。
4.长度最小的子数组
滑动窗口
定义:不断调节子序列起始位置和终止位置,得到想要的结果。
不要以为for里放一个while就以为是O(n^2)啊, 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
left, right = 0, 0
cursum = 0
minlength = float("inf")
while right < len(nums):
cursum += nums[right]
while cursum >= target:
minlength = min(minlength, right - left + 1)
cursum -= nums[left]
left += 1
right += 1
return minlength if minlength != float("inf") else 0
5. 螺旋矩阵
模拟
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
matrix = [[0]* n for _ in range(n)]
startx, starty = 0, 0
loop, mid = n // 2, n // 2
count = 1
for offset in range(1, loop + 1):
for i in range(starty, n - loop):
matrix[startx][i] = count
count += 1
for i in range(startx, n - loop):
matrix[i][n - loop] = count
count += 1
for i in range(n - loop, starty, -1):
matrix[n - loop][i] = count
count += 1
for i in range(n - loop, startx, -1):
matrix[i][starty] = count
count += 1
startx += 1
starty += 1
if n % 2 == 1:
matrix[mid][mid] = count
return matrix
链表
概念
通过指针串联在一起的线性结构,每一个节点由两部分组成,一个数据域一个指针域(存放指向下一个节点的指针),最后一个节点的指针指向null(空指针)。(内存地址、数据域、指针域)
链接的入口节点称为链表的头节点(head)。
特点
非连续分布
单链表:只指下。
双链表:每一个节点有两个指针域,指上指下(可向前向后查询)。
循环链表:链表首尾相连(可以解决约瑟夫环问题。)
数组:数据量固定,频繁查询,较少增删。
链表:数据量不固定,较少查询,频繁增删。
单链表节点具备两个属性:val和next,val是当前节点的值,next是指向下一个节点的指针/引用。双向链表还需要一个属性prev以指示链表中的上一个节点。
删除某个节点时,C++里最好是再手动释放这个节点,释放这块内存。其他语言例如Java、Python,就有自己的内存回收机制,就不用自己手动释放了。
链表的增添和删除都是O(1)操作,也不会影响到其他节点。但是要注意,要是删除第五个节点,需要从头节点查找到第四个节点通过next指针进行删除操作,查找的时间复杂度是O(n)。
方法
while截止的地方以及链表指向的问题
1.移除链表元素
思路:使用虚拟头结点。
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
tree = cur = ListNode(next = head)
while cur:
if cur.next and cur.next.val == val:
cur.next = cur.next.next
else:
cur = cur.next
return tree.next
2.设计链表(wei)
class ListNode:
def __init__(val = 0, next = None):
self.val = val
self.next = next
3.翻转链表
4.两两交换链表中的节点
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy = cur = ListNode(next = head)
while dummy.next and dummy.next.next:
temp0 = dummy.next
temp1 = dummy.next.next.next
dummy.next = dummy.next.next
dummy.next.next = temp0
temp0.next = temp1
dummy = dummy.next.next
return cur.next
5.删除链表倒数第N个节点(wei)
思路:双指针法
6.链表相交(wei)
7.环形链表(wei)
思路:从头结点出发一个指针,从相遇节点也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是环形入口的节点。
可以做一下HOT100里的环形链表再巩固一下