每日刷题

链表

创建链表

class ListNode:
	def __init__(self, val, next = None):
		self.val = val 
		self.next = next
# [1, 2, 3] => 1->2->3
def gen_list(nums):
	if not nums:
		return None
	head = ListNode(nums[0])
	pre = head
	for i in range(1, len(nums)):
		node = ListNode(nums[i])
		pre.next = node
		pre = node
	return node

反转链表

在这里插入图片描述
链表的通用解法,先存、后断

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

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        pre = None
        cur = head
        while cur:
            nextnode = cur.next
            cur.next = pre
            pre = cur
            cur = nextnode
        return pre

合并两个有序链表

在这里插入图片描述

# 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, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        per = ListNode(0)
        cur = pre
        while l1 and l2:
        	if le.val <= l2.val:
        		cur.next = l1
        		l1 = l1.next
        	else:
        		cur.next = l2
        		l2 = l2.next
        	cur = cur.next
        cur.next = l1 or l2
        return pre.next

相交链表

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

如下面的两个链表
在这里插入图片描述
思想:两个指针,分别从头开始遍历,两个链表,找到值相等,切后续节点都相等的点。但问题是两个链表长度不一样。所以有一下步骤
1、求两个链表长度插值idff
2、较长的链表先走diff 步
3、两个链表一起移动,找到交点(只需找到整个node 完全相等的点)

# 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
        """
       	if headA is None or headB is None:
       		return None 
       	# 计算长度
       	len1 = 0
       	cura = headA
       	while cura:
       		len1 += 1
       		cura = cura.next
       	len2 = 0
       	curb = headB
       	while curB:
       		len2 += 1
       		curb = curb.next
       	diff = abs(len1 - len2)
       	if len1 > len2:
       		for _ in range(diff):
       			headA = headA.next
       	else:
       		for _ in range(diff):
       			headB = headB.next
       	while headA and headB:
       		if headA == headB:
       			return headA
       		headA = headA.next
       		headB = headB.next
       	return None 	

环形链表

给定一个链表,判断链表中是否有环。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle
在这里插入图片描述
思想1:快慢指针,指针 i 每次移动1, 指针 j 每次移动2。若无环,指针2 会先一步None。若有环,指针2则会和指针1重叠。

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

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if not head or head.next == None:
            return False
        i, j = head, head
        while j:
            if j.next:
                j = j.next.next
                i = i.next
                if i == j:
                    return True
            else:
                return False

两数相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

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

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers

思想1:只需考虑两种异常情况。第一种。l1 ,l2 长度不一样,第二种l1 , l2 之间发生了进位。
那么可以将两个链表中的值取出,放到数组里,然后对数组进行按位相加。
这里用了https://leetcode-cn.com/problems/add-two-numbers/solution/zui-zhi-bai-de-xie-fa-by-meng-zhi-hen-n-2/这里的想法。用s存储每一个节点相加的结果,通过取余和 取整 来实现进为操作。

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

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        head = ListNode(None)
        num1 = []
        s = 0
        while l1 or l2 or s:
            s += (l1.val if l1 else 0) + (l2.val if l2 else 0)
            num1.append(s % 10)
            s //= 10
            l1 = l1.next if l1 else None
            l2 = l2.next if l2 else None
        head = ListNode(num1[0])
        pre = head
        for i in range(1, len(num1)):
            node = ListNode(num1[i])
            pre.next = node
            pre = node
        return head

思想2:同上,只不过直接将l1 l2 的val相加,存到新的链表中。同样用梦之痕大佬的进位思想。

class Solution(object):
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        head = ListNode(None)
        pre = head
        s = 0
        while l1 or l2 or s:
            s += (l1.val if l1 else 0) + (l2.val if l2 else 0)
            pre.next = ListNode(s % 10)
            pre = pre.next
            s //= 10
            l1 = l1.next if l1 else None
            l2 = l2.next if l2 else None
        return head.next
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值