【LeetCode】链表相关问题

1.翻转链表

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # write code here
        last = None
        while pHead:
            tmp = pHead.next  #保存当前节点的下一个节点
            pHead.next = last  #当前节点的next域指向上一个节点
            last = pHead
            pHead = tmp

        return last

2.两个排序链表

class Solution1:
    # 返回合并后列表
    def Merge(self, pHead1, pHead2):
        # write code here
        if pHead1 == None:
            return pHead2
        if pHead2 == None:
            return pHead1
        if pHead1.val < pHead2.val:
            pHead1.next = self.Merge(pHead1.next,pHead2)
            return pHead1
        else:
            pHead2.next = self.Merge(pHead1,pHead2.next)
            return pHead2

3.链表倒数第K个节点

'''
* 思路
 * 1. 编写一个方法,接受head节点,同时接收一个index
 * 2. index表示是倒数第index节点
 * 3. 先把链表从头到尾遍历,得到总的长度getLength
 * 4. 得到size后,我们从链表的第一个开始遍历(size-index)个,就可以得到
 * 5. 如果找到返回该节点,否则返回null

'''
class Listnode(object):
    def __init__(self,data,next=None):
        self.data=data
        self.next=next

    def getSingleLinkedListNodeCount(self,node):
        if node == None:
            return 0
        if node.next == None:
            return 1

        p = node
        count = 0
        while p:
            count += 1
            p = p.next
        return count

    def FindLastIndexNode(self,node,k):
        length = self.getSingleLinkedListNodeCount(node)

        num = length - k
        if k <= 0 or k > length:
            return None
        p = node
        while p and num >0:
            p = p.next
            num -= 1
        return p.data

4.链表中环的入口

    def EntryNodeOfLoop1(self, pHead):
        # write code here
        #遍历链表,环的存在,遍历遇见的第一个重复的即为入口节点
        tempList = []
        p = pHead
        while p:
            if p in tempList:
                return p
            else:
                tempList.append(p)
            p = p.next

5.单链表排序

class Solution:
    def sortList(self, head):
        if not head or not head.next: return head # termination.
        # cut the LinkedList at the mid index.
        slow, fast = head, head.next
        while fast and fast.next:
            fast, slow = fast.next.next, slow.next
        mid, slow.next = slow.next, None # save and cut.
        # recursive for cutting.
        left, right = self.sortList(head), self.sortList(mid)
        # merge `left` and `right` linked list and return it.
        h = res = ListNode(0)
        while left and right:
            if left.val < right.val:
                h.next, left = left, left.next
            else:
                h.next, right = right, right.next
            h = h.next
        h.next = left if left else right
        return res.next


class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next:
            return head

        temp = head
        node_list = []
        while head:
            node_list.append(head.val)
            head = head.next

        node_list.sort()
        head = temp
        i = 0
        while head:
            head.val = node_list[i]
            head = head.next
            i += 1

        return temp

6.链表带环
'''
判断链表是否带环:
思路:设定快慢指针,快指针一次走2步,慢指针一次走一步,当快指针=慢指针则带环
循环链表: 最后一个节点指向 头节点
'''
# 链表带环
class Listnode(object):
    def __init__(self,data,next=None):
        self.next = next
        self.data = data

class Solution(object):
    def Iscycle(self,head):
        if not head:
            return None
        slow = fast = head

        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next

            if slow == fast:
                print("存在循环链表,节点为:",slow.data)
                return True
                
        print("不存在循环链表")

        return False

7.链表的中间节点
'''
查找链表的中间节点:
思路:设定快慢指针,快指针一次走2步,慢指针一次走一步,当快指针走到尾部,慢指针所指向的位置就是中间节点
首先,我们初始化一个节点类,表示链表中的元素,它的属性应该有两个,当前节点的值,和下一个节点的地址
'''
class Listnode(object):
    def __init__(self,data,next=None):
        self.data=data
        self.next=next


class Solution(object):
    def middleNode(self, head):
        if head is None:
            return None
        slow = fast = head  # 初始化两个指针
        while fast and fast.next: #while fast.next and fast.next.next则偶数长度,返回第一个中间节点
            slow = slow.next  # 走一步
            fast = fast.next.next  # 走两步
        return slow.data

8.删除链表中的重复节点
'''
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 
例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

值得注意的是,本题是不保留重复节点,而在 LeetCode 85题中,保留一个元素。
'''

class Solution3:
    def deleteDuplication(self, pHead):
        # write code here
        if not pHead:
            return None
        a_list = []
        while pHead:
            a_list.append(pHead.val)   #把所有节点值都存到链表中
            pHead = pHead.next
        new_list = [i for i in a_list if a_list.count(i)==1]  #去掉重复节点
        if new_list:
            root = pHead = ListNode(new_list[0]) #初始化头节点
            for i in range(1,len(new_list)):
                pHead.next = ListNode(new_list[i]) #组成链表
                pHead = pHead.next
            return root
        else:
            return None

9.两个链表的第一个公共节点
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        p1 = pHead1
        p2 = pHead2

        if pHead1 == pHead2 == None:
            return pHead1

        length1 = 0
        length2 = 0

        while p1:
            length1 += 1
            p1 = p1.next

        while p2:
            length2 += 1
            p2 = p2.next

        if length1 < length2:
            pHead1,pHead2 = pHead2,pHead1   #始终让pHead1为长链表.

        distance = abs(length1-length2)
        # 让长的先走k步
        for i in range(distance):
            pHead1 = pHead1.next
        while pHead1 != pHead2:
            pHead1 = pHead1.next
            pHead2 = pHead2.next

        return pHead1

10.不用加减乘除做乘法
'''
第一步:相加各位的值,不算进位,二进制每位相加就相当于各位做异或操作;
第二步:计算进位值,相当于各位做与操作,再向左移一位。
第三步重复上述两步, 各位相加 ,计算进位值。进位值为0,跳出循环。
'''
class Solution:
    def Add(self, num1, num2):
        # write code here
        result = num1 ^ num2
        carry = (num1 & num2) <<1
        while carry:
            num1 = result
            num2 = carry
            result = (num1 ^ num2)
            carry = (num1 & num2)<<1
        return result

11.K个一组反转链表
class Solution(object):
    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        res = []
        while head:
            res.append(head.val)
            head = head.next

        num = len(res) // k   #确定是几组k
        num_res = len(res) % k #判断是是否有余数

        tmp = []
        for i in range(num):
            s = res[k*i:k*(i+1)][::-1]
            tmp += s
        if num_res == 0:
            tmp = tmp   #为零的话则不需要
        else:
            tmp = tmp + res[-num_res:] #如果余数不为零则需要考虑

        root = ListNode(0)
        head = root
        for i in tmp:
            node = ListNode(i)
            head.next = node
            head = head.next
        return root.next
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值