LeetCodePractice-20210611

Posted Circle-C

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCodePractice-20210611相关的知识,希望对你有一定的参考价值。

剑指 Offer 03. 数组中重复的数字

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

示例 1:

输入:

[2, 3, 1, 0, 2, 5, 3]

输出:2 或 3

限制:

2 <= n <= 100000

链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof

Solution1

nums = [2, 3, 1, 0, 2, 5, 3]
ans = set([n for n in nums if nums.count(n) > 1])
ans
hashTable = [0] * 100000
for n in nums:
    hashTable[n] += 1
    if hashTable[n] > 1:
        print(n)
        break

剑指 Offer 04. 二维数组中的查找

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

现有矩阵 matrix 如下:

[

[1, 4, 7, 11, 15],

[2, 5, 8, 12, 19],

[3, 6, 9, 16, 22],

[10, 13, 14, 17, 24],

[18, 21, 23, 26, 30]

]

给定 target = 5,返回 true。

给定 target = 20,返回 false。

限制:

0 <= n <= 1000

0 <= m <= 1000

链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof

matrix = [
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]
matrix = [
  [-5,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
]
matrix = [[-5]]
matrix = [[]]
target = -5
target = -2
target = 5
target = 11
target = 8
target = 22
target = 25

Solution1

i = len(matrix) - 1
j = 0
while i >= 0 and j < len(matrix[0]):
    if target > matrix[i][j]: 
        j += 1
    elif target < matrix[i][j]: 
        i -= 1
    else: 
        print(True)
        break
print(False)

Solution2

[j for i in matrix for j in i]
target in [j for i in matrix for j in i]
bool([])
bool([[]])

剑指 Offer 06. 从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例 1:

输入:head = [1,3,2]

输出:[2,3,1]

限制:

0 <= 链表长度 <= 10000

链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof

Solution1-递归

from typing import List
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def reversePrint(self, head: ListNode) -> List[int]:
        if head != None:
            return self.reversePrint(head.next) + [head.val]
        else:
            return []
head = ListNode(2)
head.next = ListNode(3)
Solution().reversePrint(head)

Solution2-Stack

class Solution2:
    def reversePrint(self, head: ListNode) -> List[int]:
        array = []
        while head:
            array.append(head.val)
            head = head.next
        return array[::-1]
Solution2().reversePrint(head)

剑指 Offer 10- I. 斐波那契数列

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:

F(0) = 0,   F(1) = 1

F(N) = F(N - 1) + F(N - 2), 其中 N > 1.

斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2

输出:1

示例 2:

输入:n = 5

输出:5

提示:

0 <= n <= 100

链接:https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof

class Solution:
    def fib(self, n: int) -> int:
        if n == 0:
            return 0
        if n == 1:
            return 1
        return self.fib(n - 1) + self.fib(n - 2)
Solution().fib(1)
0 1 1 2 3 5 
class Solution2:
    def fib(self, n: int) -> int:
        if n == 0:
            return 0
        if n == 1:
            return 1
        a, b = 0, 1
        for _ in range(n):
            a, b = b, a + b
            print(a)
        return a
Solution2().fib(45)

53. 最大子序和

https://leetcode-cn.com/problems/maximum-subarray/

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]

输出:6

解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]

输出:1

示例 3:

输入:nums = [0]

输出:0

示例 4:

输入:nums = [-1]

输出:-1

示例 5:

输入:nums = [-100000]

输出:-100000

提示:

1 <= nums.length <= 3 * 104

-105 <= nums[i] <= 105

进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

通过次数526,186提交次数969,361

链接:https://leetcode-cn.com/problems/maximum-subarray

nums = [-2,1,-3,4,-1,2,1,-5,4]

方法一:贪心

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b8ozfbgV-1623416063944)(images\\最大子序列和-贪心.png)]

  • 时间复杂度: O(N),只遍历一次数组
  • 空间复杂度: O(1),只使用了常数空间
def maxSubArray(nums):
    if not nums: return -214783648
    cur_sum = max_sum = nums[0]
    for i in range(1, len(nums)):
        cur_sum = max(nums[i], cur_sum + nums[i])
        max_sum = max(cur_sum, max_sum)
    return max_sum
maxSubArray(nums)

方法二:动态规划

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xegLYlSC-1623416063950)(images\\最大子序列和-动态规划.png)]

def maxSubArray(nums):
    if not nums: return -214783648
    for i in range(1, len(nums)):
        if nums[i-1] > 0:
            nums[i] = nums[i-1] + nums[i]
    max_sum = max(nums)
    return max_sum
maxSubArray(nums)

1282. 用户分组

有 n 位用户参加活动,他们的 ID 从 0 到 n - 1,每位用户都 恰好 属于某一用户组。给你一个长度为 n 的数组 groupSizes,其中包含每位用户所处的用户组的大小,请你返回用户分组情况(存在的用户组以及每个组中用户的 ID)。

你可以任何顺序返回解决方案,ID 的顺序也不受限制。此外,题目给出的数据保证至少存在一种解决方案。

示例 1:

输入:groupSizes = [3,3,3,3,3,1,3]

输出:[[5],[0,1,2],[3,4,6]]

解释:

其他可能的解决方案有 [[2,1,6],[5],[0,4,3]] 和 [[5],[0,6,2],[4,3,1]]。

示例 2:

输入:groupSizes = [2,1,3,3,3,2]

输出:[[1],[0,5],[2,3,4]]

提示:

groupSizes.length == n

1 <= n <= 500

1 <= groupSizes[i] <= n

链接:https://leetcode-cn.com/problems/group-the-people-given-the-group-size-they-belong-to

groupSizes = [3,3,3,3,3,1,3]
groupSizes = [2,1,3,3,3,2]
def groupThePeople(groupSizes):
    group_index = 0
    ans = [[]]
    d = {}
    for i, size in enumerate(groupSizes):
        if size not in d.keys():
            d[size] = [i]
        else:
            if
            d[size].append(i)
def groupThePeople(groupSizes):
    ans = [] # 存放各组的用户下标
    group_index = {} # 记录用户组ans所在的下标
    index = 0 # 组的个数(下标)
    # 从头遍历每个元素
    for i, size in enumerate(groupSizes):
#         print(size, group_index, ans)
        # 如果用户组大小没有记录,则新建一组,将其下标存到该组
        if size not in group_index.keys():
            group_index[size] = index
            ans.append([])
            ans[group_index[size]].append(i)
            index += 1
        # 如果用户组大小有记录
        else:
            # 且该组用户没有满
            if len(ans[group_index[size]]) < size:
                ans[group_index[size]].append(i)
            # 且该组用户已满
            else:
                # 新建一组
                group_index[size] = index
                ans.append([])
                ans[group_index[size]].append(i)
                index += 1
    return ans
groupThePeople(groupSizes)

1. 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9

输出:[0,1]

解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6

输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6

输出:[0,1]

提示:

2 <= nums.length <= 104

-109 <= nums[i] <= 109

-109 <= target <= 109

只会存在一个有效答案

进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?

链接:https://leetcode-cn.com/problems/two-sum

nums = [2,7,11,15]
target = 9
nums = [3,2,4]
target = 6
nums = [3,3]
target = 6

方法一:暴力求解

def twoSum(nums, target):
    for i, e1 in enumerate(nums):
        for j, e2 in enumerate(nums[i+1:]):
            if e1 + e2 == target:
                return [i, i+j+1]
twoSum(nums, target)

方法二:查找表法

思路及算法

注意到方法一的时间复杂度较高的原因是寻找 target - x 的时间复杂度过高。因此,我们需要一种更优秀的方法,能够快速寻找数组中是否存在目标元素。如果存在,我们需要找出它的索引。

使用哈希表,可以将寻找 target - x 的时间复杂度降低到从 O(N)O(N) 降低到 O(1)O(1)。

这样我们创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。

复杂度分析

时间复杂度:O(N)O(N),其中 NN 是数组中的元素数量。对于每一个元素 x,我们可以 O(1)O(1) 地寻找 target - x。

空间复杂度:O(N)O(N),其中 NN 是数组中的元素数量。主要为哈希表的开销。

def twoSum(nums, target):
    hashTable = {}
    for i, e in enumerate(nums):
        if target - e not in hashTable.keys():
            hashTable[e] = i
        else:
            return [hashTable[target - e], i]
twoSum(nums, target)

15. 三数之和

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

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

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:

输入:nums = []
输出:[]
示例 3:

输入:nums = [0]
输出:[]

提示:

0 <= nums.length <= 3000
-105 <= nums[i] <= 105

链接:https://leetcode-cn.com/problems/3sum

nums = [-1,0,1,2,-1,-4]
nums = [0,0,0,0]
nums = [-2,0,1,1,2]

双指针法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9hX8tBjE-1623416063952)(images\\三数之和.png)]

拿这个nums数组来举例,首先将数组排序,然后有一层for循环,i从下表0的地方开始,同时定一个下表left 定义在i+1的位置上,定义下表right 在数组结尾的位置上。

依然还是在数组中找到 abc 使得a + b +c =0,我们这里相当于 a = nums[i] b = nums[left] c = nums[right]。

接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下表就应该向左移动,这样才能让三数之和小一些。

如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。

时间复杂度:O(n^2)。

def threeSum(nums):
    nums = sorted(nums)
    ans = []
    for i, e1 in enumerate(nums):
        left = i+1
        right = len(nums) - 1
        while left < right:
            e2 = nums[left]
            e3 = nums[right]
            s = e1 + e2 + e3
            if s == 0:
                if [e1, e2, e3] not in ans:
                    ans.append([e1, e2, e3])
                left += 1
            elif s < 0:
                left += 1
            else:
                right -= 1
    return ans
threeSum(nums)

3. 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: s = “abcabcbb”

输出: 3

解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

示例 2:

输入: s = “bbbbb”

输出: 1

解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。

示例 3:

输入: s = “pwwkew”

输出: 3

解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
  请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:

输入: s = “”

输出: 0

提示:

0 <= s.length <= 5 * 104

s 由英文字母、数字、符号和空格组成

链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters

s = "abcabcbb"
s = "bbbbb"
s = "pwwkew"
s = ''
s = ' '
s = "dvdf"
ans = 0
substr = ''
substr_len = 0
if s == '': ans = 0
for i in s:
    if i not in substr:
        substr_len += 1
        substr += i
    else:
        substr = substr[substr.index(i)+1:] + i
        substr_len = len(substr)
    if substr_len > ans: ans = substr_len
ans

48. 旋转图像

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]

输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]

输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

示例 3:

输入:matrix = [[1]]

输出:[[1]]

示例 4:

输入:matrix = [[1,2],[3,4]]

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

提示:

matrix.length == n

matrix[i].length == n

1 <= n <= 20

-1000 <= matrix[i][j] <= 1000

链接:https://leetcode-cn.com/problems/rotate-image

matrix = [[1,2,3],[4,5,6],[7,8,9]]
length = len(matrix)
for i in range(length):
    for j in range(length):
        if j < i:
            temp = matrix[i][j]
            matrix[i][j] = matrix[j][i]
            matrix[j][i] = temp
        
matrix
for i in range(length):
    for j in range(length//2):
        temp = matrix[i][length - j -1] 
        matrix[i][length - j -1] = matrix[i][j]
        matrix[i][j] = temp
matrix

279. 完全平方数

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

给你一个整数 n ,返回和为 n 的完全平方数的 最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

示例 1:

输入:n = 12

输出:3

解释:12 = 4 + 4 + 4

示例 2:

输入:n = 13

输出:2

解释:13 = 4 + 9
 
提示:

1 <= n <= 104

链接:https://leetcode-cn.com/problems/perfect-squares

import math
n 以上是关于LeetCodePractice-20210611的主要内容,如果未能解决你的问题,请参考以下文章