leetcode刷题之链表

2. Add Two Numbers

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Example:
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

python 解答

  • 思路:
    利用一个变量来控制进位,不断从两个链表中取数据到连接到新的链表当中。
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        add_num = 0
        new_list = ListNode(0)
        cur = new_list
        cur1 = l1
        cur2 = l2
        while cur1 and cur2:
            value = cur1.val + cur2.val + add_num
            cur.next = ListNode(value%10)
            add_num = 0
            if value > 9:
                add_num = 1
            cur = cur.next
            cur1 = cur1.next
            cur2 = cur2.next
        if cur1 == None and cur2 != None:
            while cur2:
                value = add_num + cur2.val
                cur.next = ListNode(value%10)
                add_num = 0
                if value > 9:
                    add_num = 1
                cur = cur.next
                cur2 = cur2.next
        
        if cur1 != None and cur2 == None:
            while cur1:
                value = add_num + cur1.val
                cur.next = ListNode(value%10)
                add_num = 0
                if value > 9:
                    add_num = 1
                cur = cur.next
                cur1 = cur1.next
        if cur1 == None and cur2 == None:
            if add_num == 1:
                cur.next = ListNode(add_num)
            cur = cur.next
        return new_list.next
  • 思路二:
    不需要分情况考虑,直接将所有的情况放在一个循环中进行操作。代码量虽然减少了,但是并没有减少空间和时间复杂度。
		add_num = 0
        new_list = ListNode(0)
        cur = new_list
        cur1 = l1
        cur2 = l2
        while cur1 or cur2:
            if cur1 and cur2:
                value = cur1.val + cur2.val + add_num
            elif cur1:
                value = cur1.val + add_num
            elif cur2:
                value = cur2.val + add_num
                
            cur.next = ListNode(value % 10)
            add_num = 0
            if value > 9:
                add_num = 1
            cur = cur.next
            if cur1:
                cur1 = cur1.next
            if cur2:
                cur2 = cur2.next
            if cur1 == None and cur2 == None and add_num:
                cur.next = ListNode(add_num)
                cur = cur.next
        return new_list.next

23. Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6

python 解答:

  • 思路: 先将所有节点放在一个list中,之后使用归并排序进行排序后连接成新的链表
    不过一直显示我超出时间限制,感觉用的时间不会太长呀。。。
def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        def mergesort(lists):
            length = len(lists)
            if length < 2:
                return lists
            middle = int(math.floor(length / 2))
            # print(middle)
            left = lists[ :middle]
            right= lists[middle: ]
            return merge(mergesort(left), mergesort(right))
    
        def merge(left, right):
            result = []
            len_left = len(left)
            len_right = len(right)
            i = j = 0
            while i<len_left and j<len_right:
                if left[i].val >= right[j].val:
                    result.append(right[j])
                    j += 1
                elif left[i].val < right[j].val:
                    result.append(left[i])
                    i += 1
            if i == len_left and len_right > j:
                for k in right[j:]:
                    result.append(k)
        #        result.append(right[j:])
            if i < len_left and len_right == j:
                for m in left[i:]:
                    result.append(m)
        #        result.append(left[i:])
            return result
        # dict1 = dict()
        if len(lists) == 0:
            return None   
        list_1 = []
        i = 0
        for list_node in lists:
            if list_node == None:
                continue
            cur = list_node
            while cur:
                # dict1[cur] = cur.val
                list_1.append(cur)
                cur = cur.next
        result = mergesort(list_1)
        # for value in result:
        #     print(value.val)
        for i in range(len(result)-1):
            result[i].next = result[i+1]
        if len(result) == 0:
            return None
        return result[0]
  • 采用了python自带的sort发现效果很好,以后碰到排序还是直接用python自带的吧。。
        def take_val(node):
            return node.val
        
        if len(lists) == 0:
            return None   
        result = []
        i = 0
        for list_node in lists:
            if list_node == None:
                continue
            cur = list_node
            while cur:
                # dict1[cur] = cur.val
                result.append(cur)
                cur = cur.next
        result.sort(key=take_val)
        # for value in list_1:
        #     print(value.val)
        for i in range(len(result)-1):
            result[i].next = result[i+1]
        if len(result) == 0:
            return None
        return result[0]

86. Partition List

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
Example:
Input: head = 1->4->3->2->5->2, x = 3
Output: 1->2->2->4->3->5

  • 思路
    建立两个链表,将小的放在less_head中,大的放在more_head中,最后合并两个链表

  • 解答

    class Solution(object):
        def partition(self, head, x):
            """
            :type head: ListNode
            :type x: int
            :rtype: ListNode
            """
            less_head = ListNode(0)
            more_head = ListNode(0)
            cur = head
            cur_less = less_head
            cur_more = more_head
            while cur:
                if cur.val < x:
                    cur_less.next = cur
                    cur = cur.next
                    cur_less = cur_less.next
                else:
                    cur_more.next = cur
                    cur = cur.next
                    cur_more = cur_more.next
            cur_more.next = None
            cur_less.next = more_head.next
            return less_head.next

142. Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.
Note: Do not modify the linked list.
Example 1:
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.
在这里插入图片描述

题目描述的有点问题,返回的应该是环的初始地址而不是初始地址的index

  • 思路一:
    使用set合集,head地址存放到set中,如果发现了set中有相同的地址则说明有环并输出地址。
class Solution(object):
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        d = set()
        cur = head
        i = 0
        while cur:
            # print(cur.val)
            if cur in d:
                return cur
            d.add(cur)
            # i += 1
            cur = cur.next
        return None
  • 思路二:
    解题思路:分两个步骤,首先通过快慢指针的方法判断链表是否有环;接下来如果有环,则寻找入环的第一个节点。具体的方法为,首先假定链表起点到入环的第一个节点A的长度为a【未知】,到快慢指针相遇的节点B的长度为(a + b)【这个长度是已知的】。现在我们想知道a的值,注意到快指针p2始终是慢指针p走过长度的2倍,所以慢指针p从B继续走(a + b)又能回到B点,如果只走a个长度就能回到节点A。但是a的值是不知道的,解决思路是曲线救国,注意到起点到A的长度是a,那么可以用一个从起点开始的新指针q和从节点B开始的慢指针p同步走,相遇的地方必然是入环的第一个节点A。 文字有点绕,画个图就一目了然了
		fast = head
        slow = head

        while fast != None and fast.next != None:
            fast = fast.next.next
            slow = slow.next
            if fast == slow:
                break
        if fast == None or fast.next == None:
            return None

        while head != slow:
            head = head.next
            slow = slow.next


        return head

138. Copy List with Random Pointer

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.

python实现:

  • 思路
    方法一: 将label和random分别按照顺序保存在两个dict中,之后进行遍历和连接
if head == None:
            return None
        cur = head
        i = 0
        d1 = dict()
        d2 = dict()
        while cur:
            d1[cur] = i
            d2[i] = RandomListNode(cur.label)
            i += 1
            cur = cur.next
        d2[i] = RandomListNode(0)
        cur = head
        i = 0
        while cur:
            print(d2[i].label)
            d2[i].next = d2[i+1]
            if cur.random == None:
                cur = cur.next
                i += 1
                continue
            id1 = d1[cur.random]
            d2[i].random = d2[id1]
            cur = cur.next
            i += 1
        cur = d2[0]
        while cur.next.next:
            cur = cur.next
        cur.next = None
        return d2[0]
  • 方法二: 思想和方法一一样,改进方法是利用了迭代器,更简单明了一些,使用迭代器连接node,然后random能够索引到指定节点的位置。
 if head == None:
            return None
        def fun(cur):
            while cur:
                yield(cur, RandomListNode(cur.label))
                cur = cur.next
        dict1 = {k:v for k, v in fun(head)}
        
        cur = head
        for k, v in dict1.items():
            if k.next:
                v.next = dict1[k.next]
            if k.random:
                v.random = dict1[k.random]
        return dict1[head]

21. Merge Two Sorted Lists

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
Example:
Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4

  • 解题思路
    新建一个表头,当两个链表都有的时候按照大小进行排序添加到表头的尾部,到其中一个链表为空时则插入另一个链表的剩余部分。
class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        cur1 = l1
        cur2 = l2
        head = ListNode(0)
        cur3 = head
        while cur1 and cur2:
            if cur1.val <= cur2.val:
                cur3.next = cur1
                cur3 = cur3.next
                cur1 = cur1.next
            elif cur1.val > cur2.val:
                cur3.next = cur2
                cur3 = cur3.next
                cur2 = cur2.next
        if cur1 == None and cur2 != None:
            cur3.next = cur2
        elif cur1 != None and cur2 == None:
            cur3.next = cur1
        return head.next
                

猜你喜欢

转载自blog.csdn.net/m0_37327467/article/details/87341219