Q-List
160.相交链表
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA
= 2, skipB = 3 输出:Reference of the node with value = 8 输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为
[5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。示例 2:
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3,
skipB = 1 输出:Reference of the node with value = 2 输入解释:相交节点的值为 2
(注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A
中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。示例 3:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB
= 2 输出:null 输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。 解释:这两个链表不相交,因此返回 null。注意:
如果两个链表没有交点,返回 null. 在返回结果后,两个链表仍须保持原有的结构。 可假定整个链表结构中没有循环。 程序尽量满足 O(n)
时间复杂度,且仅用 O(1) 内存。
我用的是比较长度,先让长的链表走到和短的链表一样长后再判断节点位置
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
if not headA: return headA
if not headB: return headB
node_a = headA
node_b = headB
len_a = 0
while node_a:
node_a = node_a.next
len_a += 1
len_b = 0
while node_b:
node_b = node_b.next
len_b += 1
d_len = len_a - len_b
node_a = headA
node_b = headB
if d_len < 0: #B先走
steps = abs(d_len)
while steps:
node_b = node_b.next
steps -= 1
if d_len > 0: #A先走
steps = d_len
while steps:
node_a = node_a.next
steps -= 1
while node_a and node_b and node_a != node_b:
node_a = node_a.next
node_b = node_b.next
return node_a
评论里有个大神的解法很秀,可是我没看懂,贴在这里记录一下,供各位参考(万一有一天我能看懂呢 滑稽)
203.移除链表元素
删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def removeElements(self, head, val):
"""
:type head: ListNode
:type val: int
:rtype: ListNode
"""
if not val or not head: return head
node = head
while node and node.val == val: #先处理表头开始有值等于val的情况,直接删掉
node = node.next
if not node: return node
head = node #此时的head一定是不等于val的
tmp_node = node
while node and tmp_node:
node = tmp_node.next
while node and node.val == val: #因为会有连续的几个node值等于val的情况,所以这里要用while
node = node.next
tmp_node.next = node
tmp_node = tmp_node.next
return head
206.反转链表
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
第一次用时只击败了4%,第二次93%,服了……
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next: return head
node = head #这里如果我写成node = head.next tmp = head的话就会超时。也不知道是为什么
tmp = None
while node:
new = node.next
node.next = tmp
tmp = node
node = new
return tmp
234.回文链表
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:输入: 1->2->2->1
输出: true
我用的快慢指针的思想,然后在慢指针走的时候把前半截链表反转,然后相当于两个链表,比较值是否相等
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if not head or not head.next: return True
fast = head.next
slow = node = head
tmp = None
if not fast.next: #只有两个值的时候
if fast.val == slow.val: return True
else: return False
flag = 0 #记录一下奇数链和偶数链
while fast:
slow = slow.next
try:
fast = fast.next.next #当fast走完的时候slow也是中点
except:
fast = fast.next
flag = 1
new = node.next #反转前半段链表
node.next = tmp
tmp = node
node = new
left = tmp #这个地方的index注意调整一下就好
right = slow if flag else slow.next
while left:
if left.val != right.val: return False
left = left.next
right = right.next
return True