算法练习Day4 (Leetcode/Python-链表)

24. Swap Nodes in Pairs

Given a linked list, swap every two adjacent nodes and return its head. You must solve the problem without modifying the values in the list's nodes (i.e., only nodes themselves may be changed.)
Input: head = [1,2,3,4]
Output: [2,1,4,3]

思路:

元素互换关键就是修改对应node.next的指向。

每次互换两个Nodes(比如node1和node2),其实涉及三个Node,node1, node2, node2.next(的地址)。为了方便指代第一个node,再加一个dummy_head。那么总共就是要记住四个Node:dummy_head,node1,node2,node2.next(的地址)。node1和node2.next都先用temp1和temp记住。第一次赋值,直接用dummy_head.next = dummy_head.next.next也就使用完了node2的地址。接下来再用temp和temp1记住的地址赋值来实现互换即可。

同时,这也可以写成【迭代法】。但是迭代法就不设置dummy_head了,每组node1和node2互换后,node1才是继续接下一组的node,node1.next也才是每轮迭代的output。具体实现看代码。

Solution:

class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        dummy_head = ListNode(next=head)
        current = dummy_head
        
        while current.next and current.next.next: # cur 1 2 3 4 -> cur 2 1 3 4
            temp = current.next # temp = ori1
            temp1 = current.next.next.next # temp2 = ori3
            
            current.next = current.next.next # cur ori2 ori2 ori3 ori4
            temp.next = temp1 # ori1.next = ori3
            current.next.next = temp #cur new2 ori1

            current = current.next.next
        return dummy_head.next 
# 迭代法
class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if head is None or head.next is None:
            return head
        
        # pre and cur are two nodes to swap 
        pre = head
        cur = head.next
        next = head.next.next 

        cur.next = pre # swap cur and pre

        pre.next = self.swapPairs(next) #将以next为head 的后续链表两两交换
        return cur 
        

Time complexity: O(n)

Space complexity: O(1)

19. Remove Nth Node From End of List

Given the head of a linked list, remove the nth node from the end of the list and return its head.

Input: head = [1,2,3,4,5], n = 2
Output: [1,2,3,5]

Solution:

思路:brute force: 先看整个链表的总长,减去n,即为要被移除的元素的index。但更简单的方法是用快慢指针,这样不用遍历两次链表。那就是让快指针比慢指针快n个元素,然后快指针再和慢指针一块出发知道快指针指向最后一个元素,那时慢指针指向的元素的下一个就是要被移除的。

注意!这里写for循环时应该是让快指针先走n步,所以是range(n+1)不是range(n),算不清楚的时候举个具体的例子。具体见代码里的comment。

注意!本题中写while的时候,不要写fast.next。具体如下。

while fast: # 注意!不是fast.next!!!! 如果是fast.next的话,在最后一次进入while时,fast=fast.next=None.对Nonetype.next是没有意义的会报错!!!
            slow = slow.next
            fast = fast.next

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        dummy_head = ListNode(0, next=head) # Example: dummy_head 1th 2th 3th(3th from end) 4th(2th from end) 5th(1th from end) 
        fast,slow = dummy_head,dummy_head 
        for i in range(n+1): # if n = 2 # 是n还是n+1,举个简单的例子推导一下。
            fast = fast.next
        # fast = 3th

        while fast: # 注意!不是fast.next!!!! 如果是fast.next的话,在最后一次进入while时,fast=fast.next=None.对Nonetype.next是没有意义的会报错!!!
            slow = slow.next
            fast = fast.next
        # slow = 3th
        # fast = 5th
            
        slow.next = slow.next.next
        # 3th.next = 5th 

        return dummy_head.next 

面试题 02.07. 链表相交

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。题目数据 保证 整个链式结构中不存在环。

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

思路:

所谓交点,就是两个链表各自在某一个node指向了相同的next node。

如果两个链表最后有相同的部分,假设A是更长的链表,那么一定只可能是在index = len(A)-len(B)(对更长的链表记)之后的node。所以,先计算两个链表各自的长度,再算出index。对于这个index,找到对应在两个链表里的node位置,相当于两个指针,然后一起每次指向next,如果next相等,则可以merge。

Tips: A、B链表不一定谁最长,但可以假设A是最长的那个,做这种调换:

            curA, curB = curB, curA
            lengthA, lengthB = lengthB, lengthA

反正最后输出起始的相交节点即可,无所谓A、B到底是啥。

Solution:

class Solution(object):

    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        lengthA,lengthB = 0,0
        cur = headA
        while cur:
            cur = cur.next
            lengthA += 1
        cur = headB
        while cur:
            cur = cur.next
            lengthB += 1
        curA, curB = headA, headB

        if lengthB<lengthA:
            curA, curB = curB, curA
            lengthA, lengthB = lengthB, lengthA
        for _ in range(lengthB-lengthA):
            curB = curB.next
        while curA:
            if curA == curB:
                return curA
            else:
                curA = curA.next
                curB = curB.next
        return None
        

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值