牛客-链表-栈

本文详细介绍了链表的各种操作,包括从尾到头打印列表、反转链表、合并两个有序链表、找到两个链表的第一个公共节点、查找链表中倒数第K个节点以及删除重复节点。此外,还探讨了如何使用栈实现队列功能以及设计最小值栈。通过实例解析,帮助读者深入理解链表和栈的数据结构及其应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、从头到尾打印列表

题解:列表的插值法

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param listNode ListNode类 
# @return int整型一维数组
#
class Solution:
    def printListFromTailToHead(self , listNode: ListNode) -> List[int]:
        # write code here
        result = []
        while listNode:
            result.insert(0,listNode.val)
            listNode = listNode.next
        return result

2、反转链表

解题思路:三个指针改变链表的指向

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        prev = None 
        curr = pHead
        next = pHead
        while next:
            next = curr.next
            curr.next = prev
            prev = curr
            curr = next 
        return prev
        # write code here

3、合并两个有序链表

解题思路:首先判断两个链表是否为空,不为空则使用递归的方法,首先定义一个空指针,然后判断两个链表谁的头指针比较小,就把它赋给空指针,剩下的一直递归。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回合并后列表
    def Merge(self, pHead1, pHead2):
        # write code here
        if not pHead1:
            return pHead2
        if not pHead2:
            return pHead1
        PMergeHead = None
        if pHead1.val<pHead2.val:
            PMergeHead = pHead1
            PMergeHead.next = self.Merge(pHead1.next, pHead2)
        else:
            PMergeHead = pHead2
            PMergeHead.next = self.Merge(pHead1, pHead2.next)
        return PMergeHead

4、两个链表的第一个公共结点

解题思路:先判断是否有链表为空链表。然后两个链表拼接起来,pHead1连接在pHead2之后,pHead2连接在pHead1之后,然后用两个指针分别遍历两个链表,若指针值相等,则返回。

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

#
# 
# @param pHead1 ListNode类 
# @param pHead2 ListNode类 
# @return ListNode类
#
class Solution:
    def FindFirstCommonNode(self , pHead1 , pHead2 ):
        if pHead1 == None or pHead2 == None:
            return None
        cur1,cur2 = pHead1,pHead2
        while cur1 != cur2:
            cur1 = cur1.next if cur1!= None else pHead2
            cur2 = cur2.next if cur2!= None else pHead1
        return cur1
        
        # write code here

5、链表中倒数最后K个结点

解题思路:双指针前后遍历

# @param pHead ListNode类 
# @param k int整型 
# @return ListNode类
#
class Solution:
    def FindKthToTail(self , pHead , k ):
        cur1 = pHead
        cur2 = pHead
        for i in range(0,k):
            if cur1 == None:
                return None
            cur1 = cur1.next
        while cur1 != None:
            cur1 = cur1.next
            cur2 = cur2.next   
        return cur2
        # write code here
       

5.1 、删除链表中倒数第K个结点

解题思路:我们可以定义两个指针。第一个指针从链表的头指针开始遍历向前走k-1,第二个指针保持不动;从第k步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点。我们可以定义两个指针。第一个指针从链表的头指针开始遍历向前走k-1,第二个指针保持不动;从第k步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点。


# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
 
class Solution:
    def FindKthToTail(self, head, k):
        # write code here
        if head == None or k == 0:
            return None
        phead = head
        pbehind = head
        for i in range(k-1):
            if phead.next == None:
                return None
            else:
                phead = phead.next
        while phead.next != None:
            phead = phead.next
            pbehind = pbehind.next
        return pbehind

6、删除链表中重复的节点

解题思路:删除重复结点,只需要记录当前结点前的最晚访问过的不重复结点pPre、当前结点pCur、指向当前结点后面的结点pNext的三个指针即可。如果当前节点和它后面的几个结点数值相同,那么这些结点都要被剔除,然后更新pPre和pCur;如果不相同,则直接更新pPre和pCur。

需要考虑的是,如果第一个结点是重复结点我们该怎么办?这里我们分别处理一下就好,如果第一个结点是重复结点,那么就把头指针pHead也更新一下。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteDuplication(self, pHead):
        pPrev = None
        pCur = pHead
        pNext  = None
        while pCur != None:
            if pCur.next != None and pCur.val == pCur.next.val:
                pNext = pCur.next
                while pNext.next!= None and pCur.val == pNext.next.val:
                    pNext = pNext.next
                if pCur == pHead:
                    pHead = pNext.next
                else:
                    pPrev.next = pNext.next
                pCur = pNext.next
            else:
                pPrev = pCur
                pCur = pCur.next
        return pHead

7、用两个栈实现一个队列

解题思路:栈是先进后出,队列是先进先出,建两个栈S,
和s2,给s1加入z,x,c三个值,然后依次弹出加入s2,此时s2中的值为c,x,z,此时依次弹出栈中的值,则为z,x,c.

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.stack1 = []
        self.stack2 = []
    def push(self, node):
        # write code here
        self.stack1.append(node)
    def pop(self):
        if len(self.stack2) == 0:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2.pop()
        # return xx

8、最小min函数的栈

解题思路:建两个栈。一个数据栈,一个辅助栈,辅助栈用来存放最小值,push操作:首元素入栈,同时将其压入数据栈和辅助栈,第二个元素入栈时,先压入数据栈,然后将其与辅助栈的栈顶元素比较,若小于辅助栈栈顶元素,则将其压入辅助栈,若大于,则将辅助栈栈顶元素入栈。pop操作:同时弹出数据栈和辅助栈的栈顶元素,(因为若多次弹出数据栈的元素,可能会导致辅助站中存放数据栈中么有的元素,导致获取最小值错误)。获取最小值:得到辅助栈的栈顶元素即可,

# -*- coding:utf-8 -*-
# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.Data = []
        self.Min = []

    def push(self, node):
        # write code here
        self.Data.append(node)
        if self.Min:
            if self.Min[-1] > node:
                self.Min.append(node)
            else:
                self.Min.append(self.Min[-1]) 
        else:
            self.Min.append(node)

    def pop(self):
        # write code here
        self.Min.pop()
        return self.Data.pop()
    def top(self):
        # write code here
        if self.Data == []:
            return None
        return self.Data[-1]
    def min(self):
        # write code here
        if self.min == []:
            return None
        return self.Min[-1]

9、栈的压入,弹出序列

解题思路:借助辅助栈,遍历pushV,加入辅助栈,判断其和pop

# -*- coding:utf-8 -*-
class Solution:
    def IsPopOrder(self, pushV, popV):
        # write code here
        if len(pushV) == 0:
            return False
        stackData = []
        for i in pushV:
            stackData.append(i)
            while len(stackData)  and stackData[-1] == popV[0]:
                stackData.pop()
                popV.pop(0)
        if len(stackData):
            return False
        return True

字符串

10、连续子数组的最大和

解题思路:

class Solution:
    def FindGreatestSumOfSubArray(self, array):
        # write code here
        if len(array) == 0:
            return 0
        maxsum = array[0]
        cursum = array[0]
        for i in array[1:]:
            if cursum <= 0:
                cursum = i
            else:
                cursum += i
            if cursum > maxsum:
                    maxsum = cursum
        return maxsum

11、反转单词序列

class Solution:
    def ReverseSentence(self,s):
        s1 = s.split(' ')
        return ' '.join(s1[::-1])

文章参考:https://github.com/Jack-Cherish/LeetCode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值