leetcode链表

目录

  1. 两数相加
  2. 删除链表的倒数第N个节点
  3. 合并两个有序链表
  4. 合并K个排序链表
  5. 两两交换链表中的节点
  6. K 个一组翻转链表
  7. 旋转链表
  8. 删除排序链表中的重复元素 II
  9. 删除排序链表中的重复元素
  10. 分隔链表
  11. 反转链表 II
  12. 环形链表||
  13. 重排链表

2. 两数相加

在这里插入图片描述
代码如下:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        if l1 is None:
            return l2
        if l2 is None :
            return l1
        #设置暂存为,并赋值哑变量
        tmp =ListNode(None)     #定义一个Node节点
        res=tmp #对结果赋值
        flag=0
        while l1 or l2:
            tmp_sum=0
            if l1:
                tmp_sum=l1.val
                l1=l1.next
            if l2:
                tmp_sum +=l2.val
                l2=l2.next
            tmp_res=((tmp_sum+flag)%10)
            flag=((tmp_sum+flag)//10)
            res.next=ListNode(tmp_res)
            res=res.next
        if flag:
            res.next=ListNode(1)
        res=tmp.next    #指针回到头节点
        del tmp
        return res

19.删除链表的倒数第N个节点
在这里插入图片描述

代码如下:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        dummy=ListNode(0)
        dummy.next=head
        p1=p2=dummy
        for i in range(n):
            p1=p1.next
        while p1.next:
            p1=p1.next
            p2=p2.next
        p2.next=p2.next.next
         return dummy.next

21. 合并两个有序链表
在这里插入图片描述
解题思路:递归思想
代码如下:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        if l1==None and l2==None:   #基本情况
            return None
        if l1==None:
            return l2
        if l2==None:
            return l1
        
        if l1.val<=l2.val:
            l1.next=self.mergeTwoLists(l1.next,l2)
            return l1
        else:
            l2.next=self.mergeTwoLists(l1,l2.next)
            return l2

非递归思想:

class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        dummy =ListNode(-1)
        res=dummy
        if list1 is None and list2 is None:
            return None
        while list1 or list2:
            if list1 is None:
                res.next = list2
                break
            elif list2 is None:
                res.next =list1
                break
            elif list1.val <=list2.val:
                res.next = list1
                list1 =list1.next
            else:
                res.next = list2
                list2 =list2.next
            res=res.next
        return dummy.next

23. 合并K个排序链表

在这里插入图片描述
解题思路:
先将所有元素加入到一个普通的队列中,然后sort()排序。再对排列好的list串成一个列表。

代码如下:

class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        res=[]
        if lists is None:
            return []
        for i in lists:
            while i:
                res.append(i.val)
                i=i.next
        res.sort()
        l=ListNode(0)
        first=l
        for i in res:
            l.next=ListNode(i)
            l=l.next
        return first.next

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        if not lists or len(lists) == 0:
            return None
        import heapq                # 构造小顶堆
        heap = []
        # 首先 for 嵌套 while 就是将所有元素都取出放入堆中
        for node in lists:
            while node:
                heapq.heappush(heap, node.val)
                node = node.next
        dummy = ListNode(None)
        cur = dummy
        # 依次将堆中的元素取出(因为是小顶堆,所以每次出来的都是目前堆中值最小的元素),然后重新构建一个列表返回
        while heap:
            temp_node = ListNode(heappop(heap))
            cur.next = temp_node
            cur = temp_node
        return dummy.next

24. 两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
在这里插入图片描述

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        dummy = ListNode(0)
        dummy.next = head
        temp = dummy
        while temp.next and temp.next.next:  
            node1 = temp.next      # 奇数位置
            node2 = temp.next.next    # 偶数位置
            temp.next = node2         # 将偶数位的值赋值给奇数位
            node1.next = node2.next   # 奇数位的的下一个节点指向下一个技术位
            node2.next = node1        # 将奇数位的值赋值给偶数位
            temp = node1              # 链表指针当前奇数位,next节点为下一个奇数位
        return dummy.next

25. K 个一组翻转链表
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

示例:

给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    # 翻转一个子链表,并且返回新的头与尾
    # 1-2-3-4-5---6
    # 链表反转,把当前节点的指针指向由原来的指向后一个节点,转变成指向前一个节点
    def reverse(self, head: ListNode, tail: ListNode):
        prev = tail.next    # 节点6   
        p = head            # 节点1
        while prev != tail:    # 节点相同的含义:指针的值相同,指针的next节点也相同
            nex = p.next       # 节点2
            p.next = prev      # 节点1指向节点6   
            prev = p           # 移动已修改的链表头指针
            p = nex            #
        return tail, head

    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        dummy = ListNode(0)
        dummy.next = head
        pre = dummy
        # 前指针 pre 下一个节点nex,子链表起始指针 head
        while head:     # 链表主指针
            tail = pre    # 每次需要reverse的子链表
            # 查看剩余部分长度是否大于等于 k
            for i in range(k):
                tail = tail.next
                if not tail:
                    return dummy.next
            nex = tail.next  # 子链表后一个节点
            head, tail = self.reverse(head, tail)  # 反转head 和 tail 之间的子链表
            # 把子链表重新接回原链表
            pre.next = head     # 子链表前一个节点
            tail.next = nex
            pre = tail
            head = tail.next
        return hummy.next

反转链表

def reverseList(self, head: ListNode) -> ListNode:
    prev, curr = None, head
    while curr is not None:
        next = curr.next
        curr.next = prev
        prev = curr
        curr = next
    return prev

61. 旋转链表
在这里插入图片描述
解题思路:先统计链表节点的个数n,查看最终旋转节点个数k=k%n,然后将链表节点指针走到分界点的位置,分割链表,再重连接。

代码如下:

class Solution(object):
    def rotateRight(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        
        dummy = ListNode(0)
        dummy.next = head
        if head is None:
            return None
        
        #先数链表有几个节点
        i = head
        count = 1
        while i.next is not None:
            i = i.next
            count += 1
        #抛掉重复的转圈,也算一种算法优化吧
        k = k%count
        if (k == 0) or count == 1:
            return head
        #把链表头尾连起来
        i.next = head
 
        #从dummy开始运动
        i = dummy
        #运动到新的链表的头的上一个节点
        for _ in range(count - k):
            i = i.next
 
        j = i.next
        i.next = None
        return j

82. 删除排序链表中的重复元素 II

给定一个排序列表,删除所有含有重复数字的节点,只保留原始链表中没有重复出现的数字。
在这里插入图片描述
解题思路:

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
        """
       # 顺序表
        only_list = []
        # 哈希表
        only_dict = {}

        # 新头节点
        head2 = ListNode(0)
        p = head2
        while head:
            if head.val in only_dict:
                only_dict[head.val] += 1
            else:
                only_list.append(head.val)
                only_dict[head.val] = 1
            head = head.next
        for i in only_list:
            if only_dict[i] == 1:
                new = ListNode(i)
                p.next = new
                p = p.next
        return head2.next 

思路2:用双指针

h -> 1 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5
pre   cur

做法:始终要cur走在pre前面,我们通过判断cur.val == cur.next.val判断重复元素是否存在。

 h -> 1 -> 2    3    3    4 -> 4 -> 5
           |              |
           ----------------
          pre            cur

如果存在重复元素,pre.next==cur.next ;cur =cur.next,如果不存在重复元素,pre=cur;cur=cur.next,这里需要通过一个变量标记判断是否存在重复元素。

代码如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        dummy=ListNode(0)
        dummy.next=head
        pre=dummy
        cur=head
        # 双指针,修改指针+ 遍历指针
        while cur:
            duplicate=False    # 是否存在重复元素标记
            while cur.next and cur.val==cur.next.val:
                cur=cur.next
                duplicate=True
            if duplicate:
                pre.next=cur.next  # 空指针对应的next节点,由节点cur节点转换到cur.next
            else:
                pre=cur
            cur=cur.next
        return dummy.next

class Solution:
    def deleteDuplicates(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        head2 = ListNode(0)
        p = head2

        while head:
            if head.next and head.next.val == head.val:
                val = head.val
                while head and head.val == val:
                    head = head.next
                # 这一步是防止链表尾全部相同时,新链表尾节点的next不为空
                p.next = head
            else:
                p.next = head
                p = head
                head = head.next
        return head2.next

83. 删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
在这里插入图片描述
代码如下:

class Solution(object):
    def deleteDuplicates(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        p=head
        while p:
            while p.next and p.val==p.next.val:
                p.next=p.next.next
            p=p.next
        return head

解题思路:如果pre和cur的val值相同的话,pre.next=cur.next,然后cur=cur.next

pre cur
0   0   1   1

代码如下:

class Solution(object):
    def deleteDuplicates(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        pre = None
        cur = head
        while cur != None:
            pre = cur
            cur = cur.next
            while cur != None and cur.val == pre.val:
                pre.next = cur.next
                cur = cur.next

        return head

86. 分隔链表

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

示例:

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5

解题思路:

构建两个新链表,小于x的放在链表1,大于或等于x的放在链表2,最后将链表1的表尾指向链表2的表头即可。

代码如下:

class Solution:
    def partition(self, head, x):
        """
        :type head: ListNode
        :type x: int
        :rtype: ListNode
        """
        head1 = ListNode(0)
        head2 = ListNode(0)
        phead1 = head1
        phead2 = head2
        tmp = head
        while tmp:
            if tmp.val < x:
                phead1.next = tmp
                tmp = tmp.next
                phead1 = phead1.next
                phead1.next = None
            else:
                phead2.next = tmp
                tmp = tmp.next
                phead2 = phead2.next
                phead2.next = None
        phead1.next = head2.next
        head = head1.next
        return head

参数定义
left:左指针,始终指向左边第一个大于等于x节点的前一个位置
right:右指针,寻找右边第一个小于x的节点插到left后面
思路
left指针从左到右找到第一个大于等于x的前一个位置
right从大于等于x的位置遍历到第一个小于x的位置tmp,即tmp=right.next
原地移动:right指向tmp的后一位,right.next=tmp.next,tmp节点移动到left的下一个位置left.next=tmp,同时left移动到tmp,left.next=tmp
复杂度分析
时间复杂度:O(N)
空间复杂度:O(1)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:
        if not head:
            return 
        dummy=ListNode(0)
        dummy.next=head
        left=dummy
        while left.next and left.next.val<x:
                left=left.next 
        
        right=left.next 
        while right:                        
            while right.next and right.next.val>=x:
                right=right.next
            if not right.next:
                break
            # 原地移动
            tmp=right.next
            right.next=tmp.next  
            tmp.next=left.next
            left.next=tmp   
            left = tmp

        return dummy.next

92. 反转链表 II
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转

输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
        if m == n:
            return head
        dummy = ListNode(-1)
        dummy.next = head
        a = dummy
        for _ in range(m - 1):
            a = a.next
        d=a.next
        for _ in range(n-m):
            d = d.next
        b, c = a.next, d.next
        pre = b
        cur = pre.next
        while cur != c:
            next = cur.next
            cur.next = pre
            pre = cur
            cur = next
        a.next = d
        b.next = c
        return dummy.next

142. 环形链表||

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        fast, slow = head, head
        while True:
            if not (fast and fast.next): 
                return
            fast, slow = fast.next.next, slow.next
            if fast == slow:
                 break
        fast = head
        while fast != slow:
            fast, slow = fast.next, slow.next
        return fast

143. 重排链表

给定一个单链表 L 的头节点 head ,单链表 L 重新排列后变为:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
class Solution:
    def reorderList(self, head: ListNode) -> None:
        if not head:
            return
        vec = list()
        node = head
        while node:
            vec.append(node)
            node = node.next
        
        i, j = 0, len(vec) - 1
        while i < j:
            vec[i].next = vec[j]
            i += 1
            if i == j:
                break
            vec[j].next = vec[i]
            j -= 1
        vec[i].next = None

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值