链表荟萃二:
回文链表
题目:回文链表给定一个链表,判断该链表是否是回文链表,要求O(n)
时间复杂度,O(1)
空间复杂度。
Given a singly linked list, determine if it is a palindrome.
Example 1:
Input: 1->2
Output: false
Example 2:
Input: 1->2->2->1
Output: true
列表解法
O(n)
时间复杂度,O(n)
空间复杂度。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
result = []
cur = head
while(cur):
result.append(cur.val)
cur = cur.next
return result == result[::-1]
#Note:result = [] result == result.reverse() --> False
O(1)空间复杂度
该解法来自于[2]:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
# rev records the first half, need to set the same structure as fast, slow, hence later we have rev.next
rev = None
# initially slow and fast are the same, starting from head
slow = fast = head
while fast and fast.next:
# fast traverses faster and moves to the end of the list if the length is odd
fast = fast.next.next
# take it as a tuple being assigned (rev, rev.next, slow) = (slow, rev, slow.next), hence the re-assignment of slow would not affect rev (rev = slow)
rev, rev.next, slow = slow, rev, slow.next
if fast:
# fast is at the end, move slow one step further for comparison(cross middle one)
slow = slow.next
# compare the reversed first half with the second half
while rev and rev.val == slow.val:
slow = slow.next
rev = rev.next
# if equivalent then rev become None, return True; otherwise return False
return not rev
去除有序链表里的重复元素
时间/空间复杂度均为O(n)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def middleNode(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
tmp = head
while tmp and tmp.next:
head = head.next
tmp = tmp.next.next
return head
时间O(n)空间O(1)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteDuplicates(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head is None or head.next is None:
return head
cur = head
while(cur and cur.next):
if cur.val == cur.next.val:
cur.next = cur.next.next
else:
cur = cur.next
return head # 不是return cur, cur只是一个移动的指针,指向其中一个元素
判断单链表是否有环
题目:给定单链表,判断该单链表是否有环
Leetcode题目传送门
time:O(n) space:O(1)
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if head is None or head.next is None:
return False
cur = head
fast = head
while(fast and fast.next): # fast and fast.next 不是 cur and fast.next
cur = cur.next
fast = fast.next.next
if(cur == fast):
return True
return False
判断两个单链表的交叉点
题目: 给定两个单链表,判断其交叉起始位置
Leetcode传送门
Ref:
1、回文链表
2、回文链表O(1)空间解法
3、删除已排序列表中的重复元素
4、判断链表是否有环
5、判断两个单链表相交起始点