LeetCode刷题计划_1

关于数组和链表的几个必知必会的代码实现

数组

实现一个支持动态扩容的数组

实现一个大小固定的有序数组,支持动态增删改操作

实现两个有序数组合并为一个有序数组

链表

实现单链表、循环链表、双向链表,支持增删操作

实现单链表反转

实现两个有序的链表合并为一个有序链表

实现求链表的中间结点

对应的 LeetCode 练习题(@Smallfly 整理)

数组

Three Sum(求三数之和)
英文版:https://leetcode.com/problems/3sum/

中文版:https://leetcode-cn.com/problems/3sum/

Majority Element(求众数)
英文版:https://leetcode.com/problems/majority-element/

中文版:https://leetcode-cn.com/problems/majority-element/

Missing Positive(求缺失的第一个正数)
英文版:https://leetcode.com/problems/first-missing-positive/

中文版:https://leetcode-cn.com/problems/first-missing-positive/

链表

Linked List Cycle I(环形链表)
英文版:https://leetcode.com/problems/linked-list-cycle/

中文版:https://leetcode-cn.com/problems/linked-list-cycle/

Merge k Sorted Lists(合并 k 个排序链表)
英文版:https://leetcode.com/problems/merge-k-sorted-lists/

中文版:https://leetcode-cn.com/problems/merge-k-sorted-lists/

解答过程及代码

Three Sum (求三数之和)

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例

给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

排序+双指针
先对数组进行排序,然后使用双指针从两头逼近,注意避免重复情况

源代码

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        nums.sort()
        if not nums or n < 3:
            return []
        res = []
        for i in range(n-1):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            l, r = i + 1, n - 1
            while l < r:
                s = nums[i] + nums[l] + nums[r]
                if s > 0:
                    r = r - 1
                elif s < 0:
                    l = l +1
                else:
                    res.append((nums[i], nums[l], nums[r]))
                    while l < r and nums[l] == nums[l + 1]:
                        l += 1
                    while l < r and nums[r] == nums[r - 1]:
                        r = r - 1
                    l = l + 1
                    r = r - 1
        return res

Majority Element(求众数)

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例1

输入: [3,2,3]
输出: 3

示例2

输入: [2,2,1,1,1,2,2]
输出: 2

思路

法1:使用python的内建函数,统计数组中的元素及出现的个数,然后返回出现次数最多的元素;
法2:对数组排序,中间位置的数一定是众数

源代码1

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        counts = collections.Counter(nums)
        return max(counts.keys(), key = counts.get)

源代码2

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
    	nums.sort()
    	# 中间的位置一定是众数
    	return(mums[len(nums)//2]

Missing Positive(求缺失的第一个正数)

给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
示例1

输入: [1,2,0]
输出: 3

示例2

输入: [3,4,-1,1]
输出: 2

示例3

输入: [7,8,9,11,12]
输出: 1

思路

循环判断 1-n 是否在数组中,若在则继续找下一个,不在则返回
注意:return与break语句的区别与联系

源代码

class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        n = len(nums)
        if not nums:
            return 1
        # 酷酷的代码
        # i 不在说明就是最小正整数
        for i in range(1, n+1):
            if i not in nums:
                return i
             #if 语句下不需要加break语句吗???
             # 测试结果是加不加都可以通过
        return n+1

Linked List Cycle I(环形链表)

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

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

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

思路

快慢指针方法:设定快慢指针,快指针每次移动两个元素,慢指针移动一个元素。若有环,慢指针一定会与快指针相遇,否则无环。
注意:快慢指针的设定方法,书写规范

源代码

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

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        slow = head
        fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return True
        return False

Merge k Sorted Lists(合并 k 个排序链表)

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下: [ 1->4->5, 1->3->4, 2->6 ] 将它们合并到一个有序链表中得到。 1->1->2->3->4->4->5->6

示例 2:

输入:lists = []
输出:[]

示例 3:

输入:lists = [[]]
输出:[]

思路

分治思想,递归调用

源代码

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        n = len(lists)
        if n == 0: return None
        if n == 1: return lists[0]
        if n == 2: return self.mergeTwoLists(lists[0], lists[1])

        mid = n // 2
        # 这一句写错了无数次,不是多写字母就是大小写不太对
        return self.mergeTwoLists(self.mergeKLists(lists[:mid]), self.mergeKLists(lists[mid:n]))
        
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        res = ListNode(0)
        c1, c2, c3 = l1, l2, res
        while c1 or c2:
            if c1 and c2:
                if c1.val < c2.val:
                    c3.next = ListNode(c1.val)
                    c1 = c1.next
                else:
                    c3.next = ListNode(c2.val)
                    c2 = c2.next
                c3 = c3.next
            elif c1:
                c3.next = c1
                break
            else:
                c3.next = c2
                break
        return res.next
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值