关于链表的常见面试题一 (python详解)

关于链表的常见面试题一 (python详解)

1.链表与数组的区别?
  • 存储:数组是一种顺序存储的线性表,所有元素的内存地址是连续的;链表是一种链式存储的线性表,所有元素的内存地址不一定连续;
  • 访问:数组通过下标可“随机访问”,时间复杂度为O(1),链表需要从第一个元素“顺序访问”,时间复杂度为O(n),
  • 当插入或删除元素时数组需要移动大量元素,链表只需修改元素的指针
2.翻转链表(递归、迭代方法)
根据数组创建一个链表,将链表输出
#定义单链表节点
class ListNode:
	def __init__(self,x):
		self.val=x
		self.next=None
#根据数组创建一个单链表
def creat_ListNode(nums):
	head=pre=ListNode(nums[0])
	for num in nums[1:]:
		pre.next=ListNode(num)
		pre=pre.next
	return head
#将链表输出为数组
def print_ListNode(head):
	list_node=[]
	while head:
		list_node.append(head.val)
		head=head.next
	return list_node
   # 反转一个单链表
   # 输入: 1->2->3->4->5->NULL
   # 输出: 5->4->3->2->1->NULL
   #定义单链表节点
   class ListNode:
   	def  __init__(self,x):
   		self.val=x
   		self.next=None
   #反转链表:双指针迭代
   def reverse_ListNode(head):
   	if not head:
   		return 
   	pre,cur=None,head
   	while cur:
   		tmp=cur.next
   		cur.next=pre
   		pre=pre.next
   		cur=tmp
   	return pre
   #递归
  def recursion_reverse(head):
    	#递归终止条件
       if not head or not head.next:
           return head
       #此时的cur为最后一个节点
       cur=self.recursion_reverse(head.next)
       #翻转当前节点
       head.next.next=head
       # 防止链表循环,将head.next设为空
       head.next=None
       #每次递归返回最后一个节点
       return cur
2.链表中是否有环?环的起点?
创建一个带环的链表
#创建一个带环的链表
class ListNode:
	def __init__(self,x):
		self.val=x
		self.next=None
head = ListNode(0)
p1 = ListNode(1)
p2 = ListNode(2)
p3 = ListNode(3)
p4 = ListNode(4)
p5 = ListNode(5)
head.next = p1
p1.next = p2
p2.next = p3
p3.next = p4
p4.next = p5
p5.next = p2
快慢指针法:快指针每走两步,慢指针走一步,若相遇则存在环
def exit_loop(head):	
	#定义两个指针
	fast=slow=head
	while fast.next.next and slow,next:
		fast=fast.next.next
		slow=slow.next
		if fast==slow:
			return True
	return False
寻找环的起点:两指针一个从起点出发,一个指针从第一次相遇点出发,两指针再次相遇点即为环的起点
def start_loop(head):
	fast=slow=head
	while fast.next.next and slow.next:
		fast=fast.next.next
		slow=slow.next
	#找到第一次相遇点
		if fast==slow:
			break
 #一个指针从起点出发,另一个从相遇点出发
 	fast=head
 	while fast.next and slow.next:
 		fast,slow=fast.next,slow.next
 		if fast==slow:
 			return slow.val
3.移除链表中的节点
1)移除链表中的指定节点
def remove_node(head,val):
	if not head:
		return head
	if head.val==val:
		return head.next
	pre,cur=head,head.next
	#找到删除节点的位置(cur指针所指的位置)
	while cur and cur.val!=val:
		pre,cur=pre.next,cur.next
	#在遍历链表结束前,找到删除位置
	if cur:
		pre.next=cur.next
	return head
2)移除顺序链表中的重复节点
def remove_repeat(head):
	if not head:
		return head
	pre,post=head,head.next
	while post:
	#若两指针节点值相等,删除
		if pre.val==post.val:
			pre.next=post.next
			post=post.next
		#不相等,两指针分别后移
		else:
			pre,post=pre.next,post.next
	return head
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
链表是一种常见数据结构,用于存储一系列的元素。相比于数组,链表的插入和删除操作更加高效。在Python中,可以使用类来实现链表。 一个链表由一个个节点组成,每个节点包含两个部分:数据和指向下一个节点的指针。 下面是一个简单的链表的示例: ```python class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None def append(self, data): new_node = Node(data) if self.head is None: self.head = new_node else: current = self.head while current.next is not None: current = current.next current.next = new_node def insert(self, data, position): if position < 0 or position > self.length(): raise ValueError("Invalid position") new_node = Node(data) if position == 0: new_node.next = self.head self.head = new_node else: current = self.head for _ in range(position - 1): current = current.next new_node.next = current.next current.next = new_node def remove(self, data): if self.head is None: raise ValueError("LinkedList is empty") if self.head.data == data: self.head = self.head.next else: current = self.head while current.next is not None: if current.next.data == data: current.next = current.next.next return current = current.next raise ValueError("Data not found") def length(self): count = 0 current = self.head while current is not None: count += 1 current = current.next return count def print_list(self): current = self.head while current is not None: print(current.data, end=" ") current = current.next print() ``` 上述代码中,`Node`类表示链表中的节点,包含`data`和`next`两个属性。`LinkedList`类表示链表,包含`head`属性作为链表的头节点。 `append`方法用于向链表末尾添加一个节点。如果链表为空,新节点将成为头节点;否则,遍历链表直到找到末尾节点,将新节点添加在其后。 `insert`方法用于在指定位置插入一个节点。如果位置为0,新节点将成为头节点;否则,遍历链表到达指定位置,将新节点插入在当前节点之后。 `remove`方法用于删除链表中的某个节点。如果要删除的节点是头节点,将头节点指向下一个节点;否则,遍历链表直到找到要删除的节点,将当前节点的`next`指针指向要删除节点的下一个节点。 `length`方法用于计算链表的长度。 `print_list`方法用于打印链表中的所有元素。 可以使用以下代码创建一个链表并进行操作: ```python # 创建链表 my_list = LinkedList() # 添加元素 my_list.append(1) my_list.append(2) my_list.append(3) # 插入元素 my_list.insert(4, 1) # 打印链表 my_list.print_list() # 输出: 1 4 2 3 # 删除元素 my_list.remove(2) # 打印链表 my_list.print_list() # 输出: 1 4 3 # 计算链表长度 print(my_list.length()) # 输出: 3 ``` 这是链表的基本实现,你可以根据需要进行扩展和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值