算法通关村第一关-白银-其他链表经典问题

一、判断链表是否为回文序列

LeetCode234

判断一个链表是否为回文链表

 输入:head = [1,2,2,1] 输出:true

思路分析:

方法1:栈

遍历链表,将元素存入栈中;完成后,再次遍历链表,一边遍历一边出栈,比较元素是否一致

方法2:基于方法1优化

优化点:节省一半空间

先遍历第一遍,获取链表长度
再次遍历,一边遍历,一边压栈;到达链表一半长度时,不再压栈,一边遍历,一边出栈,一边比较,只要有元素不相等,就不是回文链表

方法3:基于方法2优化

第一遍遍历,一边遍历,一边压栈;第二遍遍历,只比较一半的元素

方法4:反转链表法

先创建一个链表,将原始链表的元素逆序保存到新列表中;
遍历两个链表,比较元素值

方法5:基于方法4优化

只反转一半的元素。
先遍历第一遍,获取链表长度
重新遍历,到达一半位置后不再反转,开始比较两个链表

方法6:基于方法5优化

使用双指针快慢指针,fast一次走两步,slow一次走一步,fast到达表尾的时候,slow正好到达一半的位置。

代码实现

方法1:栈

# 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 isPalindrome(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        # 实现方法1:数据结构栈
        node_list = []
        length = 0
        node = head
        while node:
            node_list.append(node)
            length += 1
            node = node.next
        
        node = head
        index = length-1
        while node and index >= 0:
            if node.val != node_list[index].val:
                return False
            index -= 1
            node = node.next
        return True

方法2:基于方法1优化

# 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 isPalindrome(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        # 实现方法2:数据结构栈(基于方法1优化)
        # 获取链表长度
        length = 0
        node = head
        while node:
            length += 1
            node = node.next
        
        # 一边遍历,一边压栈
        node = head
        node_list = []
        index = 0
        while index < length//2:
            node_list.append(node)
            node = node.next
            index += 1
        
        # 奇数处理
        if length % 2 == 1:
            node = node.next

        # 一边遍历,一边出栈
        while index > 0:
            if node.val != node_list[index-1].val:
                return False
            index -= 1
            node = node.next
        return True
        

二、合并有序列表

LeetCode21 合并两个升序列表

解题思路:

方法1:新建一个链表,分别遍历两个链表,每次都选最小的节点接到新链表上

方法2:遍历其中一个链表,将链表元素逐个插入到另一个链表中

代码实现:

# 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 mergeTwoLists(self, list1, list2):
        """
        :type list1: Optional[ListNode]
        :type list2: Optional[ListNode]
        :rtype: Optional[ListNode]
        """
        # 新建链表
        phead = ListNode(0)
        p = phead    
        # 遍历链表
        while list1 and list2:
            if list1.val < list2.val:
                p.next = list1
                list1 = list1.next
            else:
                p.next = list2
                list2 = list2.next
            p = p.next
        if list1:
            p.next = list1
        if list2:
            p.next = list2
        
        return phead.next




你可能感兴趣的:(算法,链表,数据结构)