【要求】 额外空间复杂度为O(1)。
def print_circle(arr,top_row,top_column,down_row,down_column):
if top_row == down_row:
for i in range(top_column, down_column + 1):
print(arr[top_row][i], end=" ")
elif top_column == down_column:
for i in range(top_row, down_row + 1):
print(arr[top_column][i], end=" ")
else:
for i in range(top_column, down_column):
# 第一行打印 从第一列到最后一列
print(arr[top_row][i], end=" ")
for i in range(top_row, down_row):
print(arr[i][down_column], end=" ")
for i in range(down_column, top_column, -1):
print(arr[down_row][i], end=" ")
for i in range(down_row, top_row, -1):
print(arr[i][top_column], end=" ")
def get_print(arr):
if not arr:
return []
m = len(arr) - 1
n = len(arr[0]) - 1
top_row = 0
top_column = 0
down_row = m
down_column = n
while down_row >= top_row and down_column >= top_column:
print_circle(arr,top_row,top_column,down_row,down_column)
top_row += 1
top_column += 1
down_row -= 1
down_column -= 1
arr = [
[1,2,3],
[4,5,6],
[7,8,9]
]
get_print(arr)
【题目】 给定一个整型正方形矩阵matrix, 请把该矩阵调整成
顺时针旋转90度的样子。
【要求】 额外空间复杂度为O(1)。
def roation_square(arr):
if not arr:
return []
m = len(arr) - 1
n = len(arr[0]) - 1
top_row = 0
top_column = 0
down_row = m
down_column = n
while down_row > top_row and down_column > top_column:
for i in range(top_column,down_column):
arr[i][down_column], arr[down_row][down_column - i],arr[down_row - i][top_column],arr[top_row][i] = arr[top_row][i],arr[i][down_column], arr[down_row][down_column - i],arr[down_row - i][top_column]
# arr[top_row][i],arr[i][down_column], arr[down_row][down_column - i],arr[down_row - i][top_column] = a,b,c,d
top_row += 1
top_column += 1
down_row -= 1
down_column -= 1
arr = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]
]
roation_square(arr)
arr
[[13, 9, 5, 1], [14, 6, 6, 2], [15, 7, 11, 3], [16, 12, 8, 4]]
【题目】 给定一个矩阵matrix, 按照“之” 字形的方式打印这
个矩阵, 例如:
1 2 3 4
5 6 7 8
9 10 11 12
“之” 字形打印的结果为: 1, 2, 5, 9, 6, 3, 4, 7, 10, 11,8, 12
【要求】 额外空间复杂度为O(1)。
def printMatrix(arr):
a_row = 0
a_column = 0
b_row = 0
b_column = 0
count = False
end_row = len(arr) - 1
end_column = len(arr[0]) - 1
while a_row <= end_row and a_column <= end_column:
print_level(arr,a_row,a_column,b_row,b_column,count)
if a_column == end_column:
a_row += 1
else:
a_column += 1
if b_row == end_row:
b_column += 1
else:
b_row += 1
count = not count
def print_level(arr,a_row,a_column,b_row,b_column,count):
if not count:
# 向上打印
# 行数从大到小 列数从小到大
j = b_column
for i in range(b_row,a_row - 1, -1):
print(arr[i][j], end=" ")
j += 1
else:
j = a_column
for i in range(a_row,b_row + 1):
print(arr[i][j], end=" ")
j -= 1
arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
printMatrix(arr)
1 2 5 9 6 3 4 7 10 11 8 12
【题目】 给定一个有N*M的整型矩阵matrix和一个整数K,
matrix的每一行和每一 列都是排好序的。 实现一个函数, 判断K
是否在matrix中。 例如: 0 1 2 5 2 3 4 7 4
4 4 8 5 7 7 9 如果K为7, 返回true; 如果K为6, 返
回false。
【要求】 时间复杂度为O(N+M), 额外空间复杂度为O(1)。
def get_bool(arr,num):
n = len(arr) - 1
m = len(arr[0]) - 1
row = n
column = 0
while row >= 0 and column <= m:
if arr[row][column] > num:
row -= 1
elif arr[row][column] < num:
column += 1
else:
return True
return False
arr = [
[0,1,2,5],
[2,3,4,7],
[3,4,4,8],
[4,7,7,9]
]
get_bool(arr,5)
True
not []
True
【题目】 给定两个有序链表的头指针head1和head2, 打印两个
链表的公共部分。
class Node():
def __init__(self,val):
self.val = val
self.next = None
def get_same_node(head1,head2):
cur1 = head1
cur2 = head2
while cur1 and cur2:
if cur1.val == cur2.val:
print(cur1.val)
elif cur1.val >= cur2.val:
cur2 = cur2.next
else:
cur1 = cur1.next
【题目】 给定一个链表的头节点head, 请判断该链表是否为回
文结构。 例如: 1->2->1, 返回true。 1->2->2->1, 返回true。
15->6->15, 返回true。 1->2->3, 返回false。
进阶: 如果链表长度为N, 时间复杂度达到O(N), 额外空间复杂
度达到O(1)。
def get_bool(head):
# 用栈进行倒序,空间复杂度O(n)
if not head:
return True
cur = head
stack = []
while cur:
stack.append(cur)
cur = cur.next
cur = head
while cur:
if cur == stack.pop():
cur = cur.next
else:
return False
return True
用栈进行倒序,空间复杂度O(n)
或者找到中点,前半段压入栈中,再出栈和后半段进行比较,额外空间复杂度O(n/2)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ej4yOnDr-1588470102855)(attachment:image.png)]
按上图改变链表结构后,从两个头开始进行比对(奇数),额外空间复杂度O(1)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F3v7Y7oH-1588470102860)(attachment:image.png)]
指针指到null时 结束,最后数据结构还原
【题目】 给定一个单向链表的头节点head, 节点的值类型是整型, 再给定一个
整 数pivot。 实现一个调整链表的函数, 将链表调整为左部分都是值小于 pivot
的节点, 中间部分都是值等于pivot的节点, 右部分都是值大于 pivot的节点。
除这个要求外, 对调整后的节点顺序没有更多的要求。 例如: 链表9->0->4->5-
1, pivot=3。 调整后链表可以是1->0->4->9->5, 也可以是0->1->9->5->4。 总
之, 满 足左部分都是小于3的节点, 中间部分都是等于3的节点(本例中这个部
分为空) , 右部分都是大于3的节点即可。 对某部分内部的节点顺序不做 要求。
进阶: 在原问题的要求之上再增加如下两个要求。
在左、 中、 右三个部分的内部也做顺序要求, 要求每部分里的节点从左 到右的
顺序与原链表中节点的先后次序一致。 例如: 链表9->0->4->5->1, pivot=3。
调整后的链表是0->1->9->4->5。 在满足原问题要求的同时, 左部分节点从左到
右为0、 1。 在原链表中也 是先出现0, 后出现1; 中间部分在本例中为空, 不再
讨论; 右部分节点 从左到右为9、 4、 5。 在原链表中也是先出现9, 然后出现4,
最后出现5。
如果链表长度为N, 时间复杂度请达到O(N), 额外空间复杂度请达到O(1)。
# 额外空间复杂度达到O(n)
def Nrther_land(head, num):
arr = []
cur = head
while cur:
arr.append(cur)
cur = cur.next
quick_sort(arr,num,0,len(arr)-1)
for i in range(len(arr)-1):
arr[i].next = arr[i+1]
arr[-1].next = None
def quick_sort(arr,num,first,last):
less = first - 1
more = last - 1
cur = first
while cur < more:
if arr[cur].val == num:
cur += 1
elif arr[cur].val < num:
less += 1
arr[less], arr[cur] = arr[cur], arr[less]
cur += 1
elif arr[cur].val > num:
more -= 1
arr[more], arr[cur] = arr[cur], arr[more]
def get_result(head,num):
if not head:
return False
cur = head
less_head = None
equal_head = None
more_head = None
while cur:
if cur.val == num:
if not equal_head:
equal_head = Node(num)
equal = equal_head.next
else:
equal = Node(num)
equal = equal.next
if cur.val < num:
if not less_head:
less_head = Node(num)
less = less_head.next
else:
less = Node(num)
less = less.next
if cur.val > num:
if not more_head:
more_head = Node(num)
more = more_head.next
else:
more = Node(num)
more = more.next
cur = cur.next
# 判断less more equal 是否为空 最后拼接
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oQ042CJa-1588470102864)(attachment:image.png)]
第一次拿到less eq more 节点,再次遍历查找下一个这三种节点(less节点碰到一样的去下一个),最后拿到三个链表,再串在一起。
注意空节点
【题目】 一种特殊的链表节点类描述如下:
public class Node { public int value; public Node next; public
Node rand;
public Node(int data) { this.value = data; }
} N
ode类中的value是节点值, next指针和正常单链表中next指针的意义
一 样, 都指向下一个节点, rand指针是Node类中新增的指针, 这个指
针可 能指向链表中的任意一个节点, 也可能指向null。 给定一个由
Node节点类型组成的无环单链表的头节点head, 请实现一个 函数完成
这个链表中所有结构的复制, 并返回复制的新链表的头节点。 进阶:
不使用额外的数据结构, 只用有限几个变量, 且在时间复杂度为 O(N)
内完成原问题要实现的函数。
哈希表 python字典, dic = {old:clone}
dic[old].next = dic[old.next]
dic[old].random = dic[old.random]
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
if not head:
return None
cur = head
dic = {}
while cur:
clone = Node(cur.val)
dic[cur] = clone
cur = cur.next
for old in dic.keys():
if old.next in dic:
dic[old].next = dic[old.next]
if old.random in dic:
dic[old].random = dic[old.random]
return dic[head]
不用哈希表最后再分离链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2NLvaJh8-1588470102869)(attachment:image.png)]
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
if not head:
return None
cur = head
while cur:
# 复制链表 Node(cur.val)
tmp = cur.next
cur.next = Node(cur.val)
cur.next.next = tmp
cur = tmp
cur = head
while cur:
tmp = cur.next
if cur.random:
tmp.random = cur.random.next
cur = tmp.next
new_head = head.next
cur = head
while cur:
cur_next = cur.next.next
cur_copy = cur.next
cur.next = cur_next
cur_copy.next = cur_next.next if cur_next else None
cur = cur_next
return new_head
【题目】 在本题中, 单链表可能有环, 也可能无环。 给定两个
单链表的头节点 head1和head2, 这两个链表可能相交, 也可能
不相交。 请实现一个函数, 如果两个链表相交, 请返回相交的
第一个节点; 如果不相交, 返回null 即可。 要求: 如果链表1
的长度为N, 链表2的长度为M, 时间复杂度请达到 O(N+M), 额外
空间复杂度请达到O(1)。
查看是否有环
使用哈希表visited,遍历链表,如果 node in visited,则有环,且node为如环结点
不使用哈希表,快指针和慢指针,快指针一次两步,慢指针一次一步,当相遇时,证明有环。此时将快指针重置到头节点,
快指针步数变为一步,当再次相遇时,为入环结点
# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if not head:
return False
visited = set()
cur = head
while cur:
if cur not in dic:
visited.add(cur)
else:
return True
cur = cur.next
return False
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if not head or not head.next or not head.next.next:
return False
slow = head.next
fast = head.next.next
while slow != fast:
# 此处判断的应该是fast指针的下个和下下个
if not fast.next or not fast.next.next:
return False
slow = slow.next
fast = fast.next.next
fast = head
while slow != fast:
slow = slow.next
fast = fast.next
return slow
查看是否相交:
(1)如果都无环,将head1的链表全部放入visited中,遍历head2链表,如果遇到相同的则相交
不用哈希表
记录两个链表的长度吗m,n,及end结点,查看两个结点的内存地址是否相同,如果相同,长的链表先走m-n步,再和
短链表一起走,碰到的第一个相同的结点(内存地址)即为相交的第一个结点
(2) 不肯能存在一个有环一个无环
(3) 两个都有环
head1 head2
loop1 loop2(end 结点的内存)
loop1 = loop2 情况2
loop1 != loop2
分情况1和3
遍历head1 看loop2是否出现,出现则相交,且为相交结点,否则不相交
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O3oJq780-1588470102873)(attachment:image.png)]