Leetcode——中级部分——链表部分——Python实现

两数相加

给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。

你可以假设除了数字 0 之外,这两个数字都不会以零开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

我的解答:

这里将l1和l2的每一位依次计算,将计算的结果直接插入到ListNode中。

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

class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        temp = ListNode(0)
        res = temp
        tempNum = 0
        while True:
            if l1:
                tempNum = l1.val+tempNum
                l1 = l1.next
            if l2:
                tempNum = l2.val+tempNum
                l2 = l2.next
            #下面考虑下是否进位
            temp.val = tempNum % 10 #node.val
            tempNum = int(tempNum / 10) #进位值(下一次循环的初始tempNum)
            #下面进行链表val、next操作
            if (l1 == None) and (l2 == None) and (tempNum == 0):
                break
            else:
                temp.next = ListNode(0)
                temp = temp.next #temp指向下一个结点
        return res

奇偶链表

给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。

示例 1:

输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL

示例 2:

输入: 2->1->3->5->6->4->7->NULL 
输出: 2->3->6->7->1->5->4->NULL

说明:

  • 应当保持奇数节点和偶数节点的相对顺序。
  • 链表的第一个节点视为奇数节点,第二个节点视为偶数节点,以此类推。

我的解答:

我们可以使用两个指针来做:

(1)odd指向奇节点,even指向偶节点

(2)让奇节点的next指向偶节点的next,同时奇节点往后平移,同理,让偶节点的next指向奇节点的next,同时偶节点向后平移

(3)重复以上操作,直至到达链表尾部,最后让奇节点的next指向第一个偶节点即可

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

class Solution:
    def oddEvenList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if head == None or head.next == None:
            return head
        odd = head
        even = head.next
        t = even
        while even != None and even.next != None:
            odd.next = even.next
            odd = odd.next #现在这里的odd已经指向了下一个奇数结点
            even.next = odd.next #所以这里even的下一个结点就是现在的odd的下一个结点
            even = even.next #现在这里的even已经指向了下一个偶数结点
        odd.next = t #最后一个奇数结点指向第一个偶数结点
        return head

相交链表

编写一个程序,找到两个单链表相交的起始节点。

例如,下面的两个链表

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

在节点 c1 开始相交。

注意:

  • 如果两个链表没有交点,返回 null.
  • 在返回结果后,两个链表仍须保持原有的结构。
  • 可假定整个链表结构中没有循环。
  • 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

我的解答:

(1)双指针法,指针p、q分别指向链表A和B的首节点。遍历链表A,记录其长度lengthA,遍历链表B,记录其长度lengthB。因为两个链表的长度可能不相同,比如题目所给的case,lengthA=5,lengthB=6,则作差得到lengthB-lengthA=1,将指针q从链表B的首节点开始走1步,即指向了第二个节点,p指向链表A首节点,然后它们同时走,每次都走一步,当它们相等时,就是交集的节点。
(2)时间复杂度O(lengthA+lengthB),空间复杂度O(1)

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

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """      
        p = headA
        q = headB
        #计算链表A和B的长度
        countA = 0
        countB = 0
        while p != None:
            p = p.next
            countA = countA + 1
        while q != None:
            q = q.next
            countB = countB + 1
        #判断链表A和链表B的长度
        p = headA
        q = headB
        #情况1:A>B
        if countA > countB:
            sub = countA - countB
            for i in range(sub):
                p = p.next
        #情况2:A<B
        elif countA < countB:
            sub = countB - countA
            for i in range(sub):
                q = q.next
        #开始寻找交点
        while p != None:
            if p == q:
                return p
            else:
                p = p.next
                q = q.next
        return None



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值