高频算法题之数组详细分析

大家好,我是程序员学长~

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:822e0583-2001-47a2-8674-9297c9da08ca

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:9908cdfe-13af-45bb-b78c-6caed288ed33

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:e12b02c4-da37-4877-8634-4cbf25b059bc

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:8d24f0b9-a9a6-4724-bc3b-34d564fb0c67

本文有点长,我已将本文制作成带目录的PDF版本,获取本文PDF版本,请私信我。

全文概览

高频算法题之数组详细分析

数组的基础知识

数组的定义及特点

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:232a8747-317b-4c7d-9b59-f89fc4e9ff78

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:a2fbc603-e11f-4b3b-b64a-f6127401044b

高频算法题之数组详细分析

数组主要有以下特点。

  1. 数组的下标是从0开始的。
  2. 连续的内存空间和相同的数据类型。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:91b1d951-28e2-4e3a-9298-1051f8c153f4

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c6f09adb-c9a9-4687-87a2-b1b0187a3316

例如要删除下标为2的元素,需要对下标2后面的元素都需要向前移动。如图所示:

高频算法题之数组详细分析

解题有妙招

二分法

如果给定的数组是有序的,我们就需要考虑是否可以使用二分法来求解(二分法的时间复杂度是O(logn))。面试中二分法是面试中常考的知识点,建议大家一定要多锻炼手撕二分的能力。

双指针法

我们可以通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。例如,当我们需要枚举数组中的两个元素时,如果我们发现随着第一个元素的递增,第二个元素是递减的,那么就可以使用双指针的方法,将枚举的时间复杂度从O(N^2)减低到O(N)。

滑动窗口

顾名思义,所谓的滑动窗口就是可以在一个序列上进行滑动的窗口。其中窗口大小有固定长度的,也有可变长度的。例如给定数组[2,2,3,4,8,99,3],窗口大小为3,求出每个窗口的元素和就是固定大小窗口的问题,如果求数组[2,2,3,4,8,99,3]的最长连续子数组就是窗口可变的问题。使用滑动窗口,我们可以减低算法是时间复杂度。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:9c124221-70b9-4b19-81fd-d1b8d2c36457

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:eb0799d5-12ce-448f-92be-fd3417e95e74

哈希表法

如果需要在数组中查找某个元素是否存在时,我们可以使用哈希表法,可以将查找元素的时间复杂度从O(n)减低到O(1)。

两数之和

问题描述

LeetCode 1. 两数之和

给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。

示例 1:

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

输出:[0,1]

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

分析问题

拿到这个问题,最简单直观的想法就是对于数组中的每个元素x,去寻找数组中是否存在target-x。

def twoSum(nums, target):
    n = len(nums)
    for i in range(n):
        #对于数组中的每个元素i
        #位于它之前的元素都已经和它匹配过了,不需要重复进行匹配
        for j in range(i + 1, n):
            if nums[i] + nums[j] == target:
                return [i, j]
    return []

我们可以很清楚的知道,这个算法的时间复杂度是O(n^2)。那我们该如何降低时间复杂度呢?可以注意到该算法复杂度高的原因在于寻找元素 target-x的时候,需要遍历一遍数组,所以我们需要对这一块进行优化。我们可以采用哈希表,将寻找元素 target-x的时间复杂度由O(n)降低到O(1)。

我们在遍历数组时,对于每个元素x,我们首先查询哈希表中是否存在target-x,如果存在,将匹配到的结果直接返回,如果不存在,我们把x插入到哈希表中。

高频算法题之数组详细分析

Tips: 我们这里使用字典来代替哈希表,当插入的元素重复时,我们覆盖就好了,这样可以保证查找的时间复杂度为O(1)。为什么这里可以覆盖呢,因为题目要求是找两个数和等于target,当有两个元素重复时,我们认为它们是等价的,所以我们只需要保留一个就好了。

def twoSum(nums, target):
    hash_table = dict()
    for i, num in enumerate(nums):
        if hash_table.__contains__(target-num):
            return [hash_table[target - num], i]
        hash_table[nums[i]] = i
    return []

nums = [2,7,11,15]
target = 9
print(twoSum(nums,target))

我们可以看到该算法的时间复杂度是O(n),空间复杂度也是O(n)。

优化

当我们需要枚举数组中的两个元素时,如果我们发现随着第一个元素的递增,第二个元素是递减的,那么就可以使用双指针的方法,将枚举的时间复杂度从O(N^2)减低到O(N)。 所以我们可以采用双指针法来求解。首先,我们先对数组进行排序,然后用left和right指针分别指向数组的左边和右边,此时sum=nums[left]+nums[right],根据sum和target的大小关系,我们来移动指针。

  1. 如果sum>target,右指针左移,减小sum的值,即right=right-1。
  2. 如果sum

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:5cceb20d-bff3-4476-85b8-07fdf60f312b

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:5ec06cd9-e568-4939-8b35-92190fcf32f3

def twoSum(nums, target):
    nums=sorted(nums)
    left=0
    right=len(nums)-1
    while left < right:
        sum=nums[left]+nums[right]
        if sum>target:
            right=right-1
        elif sum<target: left="left+1" else: return [left,right] < code></target:>

利用sorted进行排序,时间复杂度是O(nlogn),空间复杂度是O(n)。所以该算法的时间复杂度是O(nlogn),空间复杂度是O(n)。

最长无重复子数组

问题描述

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

给定一个数组arr,返回arr的最长无重复元素子数组的长度,无重复指的是所有数字都不相同。子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组。

示例

输入:[2,2,3,4,8,99,3]

返回值:5

说明:[2,3,4,8,99]是最长子数组

分析问题

在开始之前,我们首先介绍一下什么是滑动窗口。顾名思义,所谓的滑动窗口就是可以在一个序列上进行滑动的窗口。如图所示,假设,我们的序列为abcabcbb,我们这里定义了一个固定大小为3的窗口在序列上滑来滑去。

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:acd5b227-83e7-4067-bedc-322fcc45f9ff

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:0450c670-a960-44b1-a7d8-76d94b6e0b2e

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:e1a36bad-da79-4cd2-b8ea-2b24bd2beec4

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:163c95c0-11d3-4931-958b-3e75315ce604

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:5dc53db9-3e44-40bd-a1db-d81d3007e6dc

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c7490a4c-9477-44e0-877c-307de8346a77

  1. 开始时2不在窗口中,所以扩大窗口。

高频算法题之数组详细分析
  1. 下一个元素2在窗口中出现,所以我们要将 出现过的元素及其左边的元素统统移出窗口,即2。

高频算法题之数组详细分析
  1. 接下来的元素3、4、8、99都没在窗口中出现过,所以我们把它们都加入到窗口中。

高频算法题之数组详细分析
  1. 下一个元素3在窗口出现过,所以我们要移除 出现过的元素及其左边的元素,即2,3。

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:b10c415d-3792-4837-a8bb-07e0e5f1574a

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:3b5c475e-3818-4a20-9ec9-8c42e9fe6420

    if not s:
        return 0
    left = 0
    # &#x8BB0;&#x5F55;&#x6BCF;&#x4E2A;&#x5B57;&#x7B26;&#x662F;&#x5426;&#x51FA;&#x73B0;&#x8FC7;
    window = set()
    n = len(s)
    max_len = 0
    for i in range(n):
        #&#x5982;&#x679C;&#x51FA;&#x73B0;&#x8FC7;&#xFF0C;&#x79FB;&#x9664;&#x91CD;&#x590D;&#x5143;&#x7D20;&#x53CA;&#x5176;&#x5DE6;&#x8FB9;&#x7684;&#x5143;&#x7D20;
        while s[i] in window:
            window.remove(s[left])
            left += 1
        #&#x6CA1;&#x51FA;&#x73B0;&#x8FC7;&#xFF0C;&#x52A0;&#x5165;window
        window.add(s[i])

        max_len = max(len(window),max_len)

    return max_len

该算法的时间复杂度是O(n)。

合并两个有序数组

问题描述

LeetCode 88. 合并两个有序数组

给你两个按 非递减顺序排列的整数数组nums1和nums2,另有两个整数m和n,分别表示nums1和nums2中的元素数目。请你合并nums2到nums1中,使合并后的数组同样按 非递减顺序排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组nums1中。为了应对这种情况,nums1的初始长度为m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例:

输入:nums1 = [1,2,3,0,0,0], m = 3,nums2 = [2,5,6],n = 3

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

解释:需要合并 [1,2,3] 和 [2,5,6] 。合并结果是 [1,2,2,3,5,6] 。

分析问题

最简单暴力的方法就是直接把nums2放入nums1的后n个位置,然后直接对nums1进行排序就好了。我们这里就不在赘述。

def merge(nums1, m, nums2, n):
    nums1[m:] = nums2
    nums1.sort()

nums1 = [1,2,3,0,0,0]
m = 3
nums2 = [2,5,6]
n = 3
merge(nums1,m,nums2,n)
print(nums1)

那么既然给定的两个数组是有序的,那我们何不把这个条件利用起来,来优化代码。所以,我们可以使用两个指针p1和p2分别指向两个数组的起始位置,然后比较大小,将较小的放入结果中,然后指针后移,直到将所有元素都排好序。

高频算法题之数组详细分析

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:2d0dd394-da43-438f-b0a1-cf282367f78d

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c6b3dfe6-bc64-492c-ba2d-5b26927ba90a

def merge(nums1, m, nums2, n):
    #&#x6682;&#x65F6;&#x5B58;&#x653E;&#x6392;&#x597D;&#x5E8F;&#x7684;&#x5143;&#x7D20;
    sorted = []
    p1, p2 = 0, 0
    #&#x6CA1;&#x6709;&#x904D;&#x5386;&#x5B8C;&#x6570;&#x7EC4;&#x65F6;
    while p1 < m and p2 < n:
        #p1&#x5143;&#x7D20;&#x904D;&#x5386;&#x5B8C;
        if nums1[p1] <= nums2[p2]: sorted.append(nums1[p1]) p1 +="1" else: sorted.append(nums2[p2]) p2 if m: for x in nums2[p2:]: sorted.append(x) nums1[p1:m]: nums1[:]="sorted" nums1="[1,2,3,0,0,0]" m="3" nums2="[2,5,6]" n="3" merge(nums1,m,nums2,n) print(nums1) < code></=>

我们可以知道这里的时间复杂度是O(m+n),空间复杂度也是O(m+n)。

优化

在使用双指针法时,我们从前往后遍历数组,如果直接使用nums1存储合并结果的话,nums1 中的元素可能会在取出之前被覆盖。所以我们引入了一个临时变量sorted来存储。那有什么办法可以避免nums1中的元素被覆盖呢?既然从前往后不可以,那么我们能从后往前吗?因为nums1的后半部分是空的,可以直接覆盖而不会影响结果,所以这里引入了逆向双指针法。

高频算法题之数组详细分析

高频算法题之数组详细分析

我们来看一下代码实现。

def merge(nums1, m, nums2, n):
    #&#x6307;&#x5411;&#x6570;&#x7EC4;&#x7684;&#x672B;&#x5C3E;&#x5143;&#x7D20;
    p1 = m -1
    p2 = n - 1
    tail = m + n - 1
    while p1 >= 0 or p2 >= 0:
        #&#x8868;&#x793A;nums1&#x904D;&#x5386;&#x5B8C;&#x6210;
        if p1 == -1:
            nums1[tail] = nums2[p2]
            p2 -= 1
        #&#x8868;&#x793A;nums2&#x904D;&#x5386;&#x5B8C;&#x6210;
        elif p2 == -1:
            nums1[tail] = nums1[p1]
            p1 -= 1
        #&#x5C06;&#x5927;&#x7684;&#x5143;&#x7D20;&#x5408;&#x5E76;
        elif nums1[p1] >= nums2[p2]:
            nums1[tail] = nums1[p1]
            p1 -= 1
        else:
            nums1[tail] = nums2[p2]
            p2 -= 1
        tail -= 1

该算法的时间复杂度是O(m+n),空间复杂度是O(1)。

螺旋矩阵

问题描述

LeetCode 54. 螺旋矩阵

给你一个 mn 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例:

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

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

高频算法题之数组详细分析

分析问题

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:57cf40e6-f55a-4dd4-ace2-0260a42d6493

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:a7dc94ae-268a-43e7-b0f9-9a32293f772e

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c6fb8fe4-707a-4f58-bce3-70fc9c260a0d

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:6f867283-2dba-48a4-a71b-0e67e6809d3f

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:771aff3b-bbcb-426b-bc9a-0234a50b5a3a

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:2538d031-daa0-4910-a968-31d326a1c92e

def spiralOrder(matrix):
    #&#x77E9;&#x9635;&#x4E3A;&#x7A7A;&#xFF0C;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;
    if not matrix or not matrix[0]:
        return []
    rows=len(matrix)
    columns=len(matrix[0])
    visited = [[False for _ in range(columns)] for _ in range(rows)]
    #&#x603B;&#x5143;&#x7D20;&#x7684;&#x4E2A;&#x6570;
    count=rows*columns
    result=[0]*count
    #&#x4EE3;&#x8868;&#x65B9;&#x5411;&#xFF0C;&#x5373;&#x4ECE;&#x5DE6;&#x5230;&#x53F3;&#x3001;&#x4ECE;&#x4E0A;&#x5230;&#x4E0B;&#x3001;&#x4ECE;&#x53F3;&#x5230;&#x5DE6;&#x3001;&#x4ECE;&#x4E0B;&#x5230;&#x4E0A;
    directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
    row, column = 0, 0
    #&#x4ECE;&#x5DE6;&#x4E0A;&#x89D2;&#x5F00;&#x59CB;&#x904D;&#x5386;
    directionIndex = 0
    for i in range(count):
        result[i] = matrix[row][column]
        #&#x5C06;&#x8BBF;&#x95EE;&#x8FC7;&#x7684;&#x5143;&#x7D20;&#x8FDB;&#x884C;&#x6807;&#x8BB0;
        visited[row][column] = True
        nextRow, nextColumn = row + directions[directionIndex][0], column + directions[directionIndex][1]
        #&#x4E0D;&#x8D8A;&#x754C;&#xFF0C;&#x5E76;&#x4E14;&#x5DF2;&#x7ECF;&#x88AB;&#x8BBF;&#x95EE;&#x8FC7;&#x4E86;&#xFF0C;&#x987A;&#x65F6;&#x9488;&#x8C03;&#x6574;&#x65B9;&#x5411;
        if not (0 <= 0 4 nextrow < rows and columns not visited[nextrow][nextcolumn]): directionindex="(directionIndex" + 1) % row column return result code></=>

由于创建了一个和原始矩阵一样大小的矩阵来表示元素是否被访问过,所以该算法的空间复杂度是O(m _n)。矩阵中的元素都会被遍历一次,所以该算法的时间复杂度也是O(m_n)。

优化

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c4c4c4ac-a9a9-478e-b5fd-ea527e8d381c

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:7d2f547c-ef8e-43d7-bcdd-cdbfd72e66a4

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:07d168c2-53da-4f2c-a9ec-4589dafc61bc

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c7c6a192-e009-4cac-8c02-4c187dfd4630

高频算法题之数组详细分析
def spiralOrder(matrix):
    # &#x77E9;&#x9635;&#x4E3A;&#x7A7A;&#xFF0C;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;
    if not matrix or not matrix[0]:
        return []
    rows = len(matrix)
    columns = len(matrix[0])
    result=[]
    #&#x5F00;&#x59CB;&#x65F6;&#xFF0C;&#x5DE6;&#x3001;&#x53F3;&#x3001;&#x4E0A;&#x3001;&#x4E0B;&#x8FB9;&#x754C;
    left=0
    right=columns-1
    up=0
    down=rows-1
    while True:
        #&#x4ECE;&#x5DE6;&#x5230;&#x53F3;
        for i in range(left,right+1):
            result.append(matrix[up][i])
        #&#x4E0A;&#x8FB9;&#x754C;&#x8C03;&#x6574;
        up=up+1
        #&#x8D8A;&#x754C;&#xFF0C;&#x9000;&#x51FA;
        if up>down:
            break
        #&#x4ECE;&#x4E0A;&#x5230;&#x4E0B;
        for i in range(up,down+1):
            result.append(matrix[i][right])
        #&#x53F3;&#x8FB9;&#x754C;&#x8C03;&#x6574;
        right=right-1
        # &#x8D8A;&#x754C;&#xFF0C;&#x9000;&#x51FA;
        if right<left: break #从右到左 for i in range(right,left-1,-1): result.append(matrix[down][i]) #下边界调整 down="down-1" if down<up: #从下到上 range(down,up-1,-1): result.append(matrix[i][left]) left="left+1">right:
            break
    return result
</left:>

该算法的时间复杂度是O(m*n),空间复杂度是O(1)。

数组中和为 0 的三个数

问题描述

LeetCode 剑指 Offer II 007. 数组中和为 0 的三个数

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

示例:

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

输出:[[-1,-1,2],[-1,0,1]]

分析问题

这道题目算是二数之和的升级版,所以我们也可以采用双指针法来求解。那三个数如何采用双指针法呢,其实很简单,我们先把一个数固定下来,然后另外两个数再使用双指针去寻找不就好了。按照惯例,我们首先对数组进行排序,然后固定第一个数first,假设为nums[i],然后再使用双指针法在数组中寻找两数之和等于-nums[i]即可。由于题目要求所求的三元组是不重复的,所以需要判断去掉重复解。重复解主要有以下两种情况。

  1. nums[first]=nums[first-1],由于我们已经把第一个元素是 nums[first-1]的三元组已经求解过了,所以没必要重复求解。
  2. nums[first]+nums[left]+nums[right]=0时,如果 nums[left]=nums[left+1]或者 nums[right]=nums[right+1],会导致重复解,所以需要去掉。

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:aaf11892-52fc-42bc-a8d1-d0ec32ac8ceb

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:6521e259-f267-4be5-b9fc-83c5fb32979e

def threeSum(nums):
    n=len(nums)
    result=[]
    if n<3: return result nums="sorted(nums)" print(nums) #遍历数组 for i in range(n): #固定第一个数 first="nums[i]" #第一个数大于0,由于第二个、第三个数都大于第一个数 #所以不可能相加等于0 if>0:
            break
        #&#x5DF2;&#x7ECF;&#x67E5;&#x627E;&#x8FC7;&#x4E86;&#xFF0C;&#x6240;&#x4EE5;&#x4E0D;&#x9700;&#x8981;&#x518D;&#x7EE7;&#x7EED;&#x5BFB;&#x627E;&#xFF0C;&#x76F4;&#x63A5;&#x8DF3;&#x8FC7;
        if i>0 and first==nums[i-1]:
            continue
        #&#x7B2C;&#x4E09;&#x4E2A;&#x6570;&#xFF0C;&#x5F00;&#x59CB;&#x65F6;&#x6307;&#x5411;&#x6700;&#x6570;&#x7EC4;&#x7684;&#x6700;&#x53F3;&#x7AEF;
        target=-first
        right=n-1
        left=i+1
        while left<right: if nums[left]+nums[right]="=target:" result.append([nums[i],nums[left],nums[right]]) #如果left和left+1对于的元素相同,由于left已经添加到result中了 #为了避免重复,我们跳过相同的元素 while left<right and nums[left]="=nums[left+1]:" left="left+1" #同理,跳过和right相同的元素 nums[right]="=nums[right-1]:" right="right-1" elif>target:
                right=right-1
            else:
                left=left+1
    return result

nums=[-1,0,1,2,-1,-4]
print(threeSum(nums))
</right:></3:>

数组中出现次数超过一半的数字

问题描述

LeetCode 剑指 Offer 39. 数组中出现次数超过一半的数字

给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。

示例:

输入:[1,2,3,2,2,2,5,4,2]

输出:2

分析问题

哈希表法

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:d5d0e0d7-cb93-41b6-a36a-9d63260bd2f0

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:d49abe2d-9242-40df-ad00-f0629479873a

def majorityElement(nums):
    #&#x7528;&#x5B57;&#x5178;&#x6765;&#x4FDD;&#x5B58;&#x6BCF;&#x4E2A;&#x6570;&#x5B57;&#x51FA;&#x73B0;&#x7684;&#x6B21;&#x6570;
    data_count = {}
    for x in nums:
        if x in data_count:
            data_count[x] = data_count[x] + 1
        else:
            data_count[x] = 1
    max_value=0
    max_key=0
    #&#x904D;&#x5386;&#x5B57;&#x5178;&#xFF0C;&#x53D6;&#x51FA;&#x6B21;&#x6570;&#x6700;&#x5927;&#x7684;
    #&#x56E0;&#x4E3A;&#x9898;&#x76EE;&#x8BF4;&#x7ED9;&#x5B9A;&#x7684;&#x6570;&#x7EC4;&#x4E00;&#x5B9A;&#x5B58;&#x5728;&#x4F17;&#x6570;
    #&#x6240;&#x4EE5;&#x6700;&#x5927;&#x7684;&#x6B21;&#x6570;&#x5C31;&#x662F;&#x4F17;&#x6570;
    for key in data_count:
        value=data_count[key]
        if value>max_value:
            max_value=value
            max_key=key
    return max_key

data=[1,2,3,2,2,2,5,4,2]
print(majorityElement(data))

该算法的时间复杂度是O(n),空间复杂度也是O(n)。

排序算法

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:48bb2510-2fd2-4f1d-9da5-50b2f392107a

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:260e522d-ca5c-4723-9e80-7016e6d09d4b

def majorityElement(nums):
        #&#x5C06;&#x6570;&#x7EC4;&#x6392;&#x5E8F;
        nums.sort()
        #&#x8FD4;&#x56DE;&#x6392;&#x5E8F;&#x6570;&#x7EC4;&#x4E2D;&#x7684;&#x4E2D;&#x70B9;
        return nums[len(nums) // 2]

data=[1,2,3,2,2,2,5,4,2]
print(majorityElement(data))

Boyer-Moore 投票算法

这道题最经典的解法是Boyer-Moore 投票算法。Boyer-Moore 投票算法的核心思想是票数正负抵消,即遇到众数时,我们把票数+1,遇到非众数时,我们把票数-1,则所有的票数和一定是大于0的。

我们假设数组nums的众数是x,数组的长度为n。我们可以很容易的知道,若数组的前a个数字的票数和为0,那么剩余n-a个数字的票数和一定是大于0的,即后n-a个数字的众数仍然为x。

高频算法题之数组详细分析

我们记数组的首个元素是n1,数组的众数是x,遍历并统计票数。当发生票数和为0时,数组剩余元素的众数一定也是x,这是因为:

  1. 当n1等于x时,抵消的所有数字中,有一半是众数x。
  2. 当n1不等于x时,抵消的所有数字中,众数的个人最少为0,最多为一半。

所以,我们在去掉m个字符里,最多只去掉了一半的众数,所以在剩余的n-m个元素中,x仍然为众数。利用这个特性,在每次遇到票数和为0时,我们都可以缩小剩余数组区间。当遍历完成时,最后一轮假设的数字即为众数。

class Solution:
    def majorityElement(self, nums):
        #&#x7968;&#x6570;&#x548C;
        counts=0
        for num in nums:
            #&#x5982;&#x679C;&#x7968;&#x6570;&#x548C;&#x4E3A;0&#xFF0C;&#x6211;&#x4EEC;&#x5047;&#x8BBE;num&#x5143;&#x7D20;&#x4E3A;&#x4F17;&#x6570;
            if counts == 0:
                x = num
            #&#x5982;&#x679C;&#x662F;&#x4F17;&#x6570;&#x7968;&#x6570;+1&#xFF0C;&#x5426;&#x5219;&#x7968;&#x6570;-1
            if num==x:
                counts=counts+1
            else:
                counts=counts-1
        return x

该算法的时间复杂度是O(n),空间复杂度是O(1)。

合并区间

问题描述

LeetCode 56. 合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。

输入:intervals = [ [1,3],[2,6],[8,10],[15,18] ]
输出:[ [1,6],[8,10],[15,18] ]
解释:区间 [1,3] 和 [2,6] 重叠,将它们合并为 [1,6]

分析问题

对于任意两个区间A和B,它们之间的关系可以有以下6种情况。

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:d79f0aee-6d59-4f4c-b8f2-152efd83328c

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:cf40ddfe-87cf-4f27-b18c-212ee55c29ae

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:7594674b-37c6-4d89-9a30-ce0a1b262bad

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:323a9ffb-4ca7-4dc2-b0dc-92c256421c57

算法

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:5bb45ab5-3a36-4c4d-a03f-3c201b1400c6

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:0d1e5b56-3e9c-42b7-a3e8-6946b320f50a

首先,我们用数组 merged 存储最终的答案。然后我们将第一个区间加入 merged 数组中,并按顺序依次考虑之后的每个区间:

  • 如果当前区间的左端点在数组 merged 中最后一个区间的右端点之后,即上图中的第二种情况,那么它们不会重合。我们可以直接将这个区间加入数组 merged 的末尾;
  • 否则,它们是有重合部分的,即上图中的第一、三种情况,我们需要用当前区间的右端点更新数组 merged 中最后一个区间的右端点,将其置为二者的较大值。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:664a1490-147a-467d-b560-17d00f5db81d

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:94acfb2a-f03c-466e-9e42-056fdf82f4ec

class Solution:
    def merge(self, intervals):
        #&#x5C06;&#x533A;&#x95F4;&#x6570;&#x7EC4;&#x6309;&#x7167;&#x5DE6;&#x7AEF;&#x70B9;&#x8FDB;&#x884C;&#x5347;&#x5E8F;&#x6392;&#x5E8F;
        intervals.sort(key=lambda x: x[0])
        #&#x5B58;&#x653E;&#x5408;&#x5E76;&#x540E;&#x7684;&#x7ED3;&#x679C;
        merged = []
        for interval in intervals:
            #&#x5982;&#x679C;&#x5217;&#x8868;&#x4E3A;&#x7A7A;
            #&#x6216;&#x8005;&#x5F53;&#x524D;&#x533A;&#x95F4;&#x7684;&#x5DE6;&#x7AEF;&#x70B9;&#x5927;&#x4E8E;merged&#x6700;&#x540E;&#x4E00;&#x4E2A;&#x5143;&#x7D20;&#x7684;&#x53F3;&#x7AEF;&#x70B9;&#xFF0C;&#x76F4;&#x63A5;&#x6DFB;&#x52A0;
            if not merged or merged[-1][1] < interval[0]:
                merged.append(interval)
            else:
                #&#x5426;&#x5219;&#x7684;&#x8BDD;&#xFF0C;&#x6211;&#x4EEC;&#x5C31;&#x53EF;&#x4EE5;&#x4E0E;&#x4E0A;&#x4E00;&#x533A;&#x95F4;&#x8FDB;&#x884C;&#x5408;&#x5E76;
                #&#x4FEE;&#x6539;merged&#x6700;&#x540E;&#x4E00;&#x4E2A;&#x5143;&#x7D20;&#x7684;&#x53F3;&#x7AEF;&#x70B9;&#x4E3A;&#x4E24;&#x8005;&#x7684;&#x6700;&#x5927;&#x503C;
                merged[-1][1] = max(merged[-1][1], interval[1])
        return merged

该算法的时间复杂度是O(nlogn),其中n是区间的数量,除去排序的开销,我们只需要一次线性扫描,所以主要的时间开销是排序的 O _(_n logn)。空间复杂度是O(logn)。

在两个长度相等的排序数组中找到上中位数

问题描述

LeetCode 4. 寻找两个正序数组的中位数

给定两个递增数组arr1和arr2,已知两个数组的长度都为N,求两个数组中所有数的上中位数。上中位数:假设递增序列长度为n,为第n/2个数。

要求:时间复杂度 O (n),空间复杂度 O(1)。

进阶:时间复杂度为O(logN),空间复杂度为O(1)。

示例:

输入:[1,2,3,4],[3,4,5,6]

返回值:3

说明:总共有8个数,上中位数是第4小的数,所以返回3。

分析问题

这道题最直观的想法就是,使用归并排序的方式,将两个有序数组合并成一个大的有序数组。大的有序数组的上中位数为第n/2个数。我们可以知道该算法的时间复杂度是O(N),空间复杂度也是O(N),显然不符合题目要求的O(1)的空间复杂度。其实,我们也不需要合并两个有序数组,我们只需要找到上中位数的位置即可。对于给定两个长度为N的数组,我们可以知道其中位数的位置为N,所以我们维护两个指针,初始时分别指向两个数组的下标0的位置,每次将指向较小值的指针后移一位(如果一个指针已经到达数组的末尾,则只需要移动另一个数组的指针),直到到达中位数的位置。

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:de6eef48-626a-41a2-8156-ea2812885453

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:2ad2a444-6c3f-46cd-9eb4-249f56132cec

class Solution:
    def findMedianinTwoSortedAray(self , arr1 , arr2 ):
        # write code here
        #&#x6570;&#x7EC4;&#x7684;&#x957F;&#x5EA6;
        N=len(arr1)
        #&#x5B9A;&#x4E49;&#x4E24;&#x4E2A;&#x6307;&#x9488;&#xFF0C;&#x6307;&#x9488;&#x4E24;&#x4E2A;&#x6570;&#x7EC4;&#x7684;&#x5F00;&#x59CB;&#x4F4D;&#x7F6E;
        p1=p2=0
        ans=0
        while p1+p2<n: #移动较小元素的指针位置 if arr1[p1]<="arr2[p2]:" ans="arr1[p1]" p1="p1+1" else: p2="p2+1" return < code></n:>

该算法的时间复杂度是O(n),空间复杂度是O(1)。

进阶

下面我们来看一下如何把时间复杂度降低为O(logN)。我们这里可以采用二分查找的思想来求解。

对于长度为N的数组arr1和arr2来说,它的上中位数是两个有序数组的第N个元素。所以,我们把这道题目可以转换成寻找两个有序数组的第k小的元素,其中k=N。

要找到第N个元素,我们可以比较arr1[N/2-1]和arr2[N/2-1],其中”/”代表整数除法。由于arr1[N/2-1]和arr2[N/2-1]的前面分别有arr1[0…N/2-2]和arr2[0…N/2-2],即N/2-1个元素。对于arr1[N/2-1]和arr2[N/2-1]的较小值,最多只会有N/2-1+N/2-1=N-2个元素比它小,所以它不是第N小的元素。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:dcb5837e-6c99-4fdf-80db-bcd79e9b9935

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:f76491c0-5f7b-405c-86ab-f95c792faa89

  • 如果arr1[N/2-1] < arr2[N/2-1],则比arr1[N/2-1] 小的数最多只有 arr1的前N/2-1个数和arr2的前N/2-1个数,即比arr1[N/2-1] 小的数最多只有N-2个,因此arr1[N/2-1]不可能是第N个数,arr1[0]到arr1[N/2-1]也都不可能是第N个数,所以可以删除。
  • 如果arr1[N/2-1] > arr2[N/2-1],则可以排除arr2[0]到arr2[N/2-1]。
  • 如果arr1[N/2-1]==arr2[N/2-1],可以归为第一种情况进行处理。

可以看到,经过一轮比较后,我们可以排查N/2个不可能是第N小的数,查找范围缩小了一半。同时,我们将在排除后的新数组上继续进行二分查找,并且根据我们排除数的个数,减少 N 的值,这是因为我们排除的数都不大于第 N 小的数。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:1de3dfdd-ac99-4e1c-86fa-46ae609cf821

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:d6c94a29-8286-4024-a758-d8446a16a6f0

高频算法题之数组详细分析

高频算法题之数组详细分析
class Solution:
    def findMedianSortedArrays(self, arr1, arr2):
        N = len(arr1)
        #&#x5982;&#x679C;N=1,&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#x4E24;&#x4E2A;&#x6570;&#x7EC4;&#x7684;&#x9996;&#x5143;&#x7D20;&#x7684;&#x6700;&#x5C0F;&#x503C;&#x5373;&#x53EF;
        if N==1:
            return min(arr1[0],arr2[0])

        index1, index2 = 0, 0
        #&#x4E2D;&#x4F4D;&#x6570;&#x4F4D;&#x7F6E;&#x4E3A;N,&#x4E0D;&#x8FC7;&#x8D85;&#x8FC7;&#x5206;&#x533A;&#x6570;&#x7EC4;&#x7684;&#x4E0B;&#x6807;
        k=N
        while k>1:

            new_index1 = index1 +  k // 2 - 1
            new_index2 = index2 +  k // 2 - 1
            data1, data2 = arr1[new_index1], arr2[new_index2]
            #&#x9009;&#x62E9;&#x8F83;&#x5C0F;&#x503C;&#xFF0C;&#x540C;&#x65F6;&#x5C06;&#x524D;k//2&#x4E2A;&#x5143;&#x7D20;&#x5220;&#x9664;
            if data1 <= 1 data2: k="k-k//2" #删除前k 2个元素 index1="new_index1+1" else: index2="new_index2" + return min(arr1[index1],arr2[index2]) < code></=>

加餐

如果给定的两个有序数组大小不同,即给定两个大小分别为 mn 的正序(从小到大)数组 nums1nums2。请你找出并返回这两个正序数组的 中位数

根据中位数的定义,当m+n为奇数时,中位数是两个有序数组的第(m+n+1)/2个元素。当m+n为偶数时,中位数是两个有序数组的第(m+n)/2和(m+n)/2+1个元素的平均值。因此这道题我们可以转化成寻求两个有序数组的第k小的数,其中k为(m+n)/2或者(m+n)/2+1。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:a14e7738-a5cb-4808-ac19-20e2fcea678e

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:ada4a850-4213-488a-9584-3a82ab679415

  • 如果nums1[k/2-1]或者nums[k/2-1]越界,那么我们需要选择对应数组的最后一个元素,即min(k/2-1,m-1)或者min(k/2-1,n-1)。
  • 如果一个数组为空,我们可以直接返回另一个数组中第 k 小的元素。
  • 如果k=1,我们只需要返回两个数组首元素的最小值即可。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:774a1420-f384-43d2-a2d1-8e8de3248f1f

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:d2fda56b-dffc-470f-955d-aaca95b35ad5

高频算法题之数组详细分析

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:5c814ea5-bd51-4327-a52e-afd52398f3b4

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c4ed27db-e5c6-464a-9b29-4578359a6e9a

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        #&#x83B7;&#x53D6;&#x7B2C;k&#x5C0F;&#x7684;&#x5143;&#x7D20;
        def getKthElement(k):
            #&#x8868;&#x793A;&#x4E24;&#x4E2A;&#x6709;&#x5E8F;&#x6570;&#x7EC4;&#x7684;&#x4E0B;&#x6807;&#x4F4D;&#x7F6E;
            index1, index2 = 0, 0
            while True:
                #&#x5982;&#x679C;&#x4E00;&#x4E2A;&#x6570;&#x7EC4;&#x904D;&#x5386;&#x5B8C;&#x6210;&#xFF0C;&#x5219;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#x53E6;&#x4E00;&#x4E2A;&#x6570;&#x7EC4;&#x7684;&#x7B2C;k&#x5C0F;&#x5143;&#x7D20;
                if index1 == m:
                    return nums2[index2 + k - 1]
                if index2 == n:
                    return nums1[index1 + k - 1]
                #&#x5982;&#x679C;k&#x4E3A;1&#xFF0C;&#x8FD4;&#x56DE;&#x4E24;&#x4E2A;&#x6709;&#x5E8F;&#x6570;&#x7EC4;&#x9996;&#x5143;&#x7D20;&#x7684;&#x6700;&#x5C0F;&#x503C;
                if k == 1:
                    return min(nums1[index1], nums2[index2])

                #&#x9632;&#x6B62;&#x6570;&#x7EC4;&#x8D8A;&#x754C;&#xFF0C;&#x6240;&#x4EE5;&#x53D6;index1 + k // 2 - 1&#x548C;m - 1&#x7684;&#x6700;&#x5C0F;&#x503C;
                new_index1 = min(index1 + k // 2 - 1, m - 1)
                #&#x540C;&#x7406;&#xFF0C;&#x53D6;index2 + k // 2 - 1&#x548C; n - 1&#x7684;&#x6700;&#x5C0F;&#x503C;
                new_index2 = min(index2 + k // 2 - 1, n - 1)
                data1, data2 = nums1[new_index1], nums2[new_index2]
                #&#x5982;&#x679C;data1<data2 1 2 if data1 <="data2:" #使k的值减少new_index1 - index1 + 1多个元素 k #移除元素 else: #使k的值减少new_index2 index2 m, n="len(nums1)," len(nums2) #两个数组的长度 lens="m" #如果为奇数,则中位数是第(lens+1) #如果为偶数,则中位数是lens 2和lens 2+1的平均值 % 1: return getkthelement((lens 1) 2) (getkthelement(lens getkthelement(lens 1)) 2.0 code></data2>

该算法的时间复杂度是 O(log(m+ n)),空间复杂度是O(1)。

缺失的第一个正整数

问题描述

LeetCode 41. 缺失的第一个正数

给你一个无重复元素未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为O(n)并且只使用常数级别额外空间的解决方案。

示例:

输入:nums = [1,2,0]

输出:3

分析问题

对于一个无重复元素、长度为N的数组,其中没有出现的最小整数只能在[1,N+1]中,这是因为如果[1,N]在数组中都出现了,说明这N个数已经把数组填满了,那么答案是N+1,否则就是[1,N]中没有出现的最小整数。所以,我们可以申请一个辅助数组temp,大小为N,我们通过遍历原数组,将属于[1,N]范围内的数,放入辅助数组中相应的位置,使得temp[i-1] = i 成立。在遍历完成后,temp中第一个不满足temp[i-1] = i 条件的就是最小的正整数,如果都满足,那么最小正整数就是N+1。

高频算法题之数组详细分析

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:0525107c-b2f4-4442-8501-685069e4dcfa

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:426b5eea-c532-4330-9a95-8d08505b3324

class Solution:
    def firstMissingPositive(self, nums):
        n = len(nums)
        #&#x7533;&#x8BF7;&#x4E00;&#x4E2A;&#x4E34;&#x65F6;&#x6570;&#x7EC4;&#xFF0C;&#x5B58;&#x653E;&#x6570;&#x7EC4;&#x4E2D;&#x7684;&#x5143;&#x7D20;
        temp = [0]*n
        for i in range(n):
            #&#x5982;&#x679C;&#x6574;&#x6570;&#x4E0D;&#x5728;[1,N]&#x7684;&#x8303;&#x56F4;&#x5185;&#xFF0C;&#x4E0D;&#x505A;&#x5904;&#x7406;
            if nums[i] <= 0 or nums[i]> n:
                continue
            else:
                #&#x5426;&#x5219;&#x628A;&#x6574;&#x6570;&#x653E;&#x5165;temp&#x7684;&#x76F8;&#x5E94;&#x4F4D;&#x7F6E;
                temp[nums[i]-1]=nums[i]

        #&#x904D;&#x5386;temp,&#x627E;&#x5230;&#x7B2C;&#x4E00;&#x4E2A;&#x4E0D;&#x6EE1;&#x8DB3;temp[i]!=i+1&#x7684;&#x6574;&#x6570;
        #&#x5C31;&#x662F;&#x4EE3;&#x8868;&#x6570;&#x7EC4;&#x4E2D;&#x4E0D;&#x5B58;&#x5728;&#x7684;&#x6700;&#x5C0F;&#x6574;&#x6570;
        for i in range(n):
            if temp[i]!=i+1:
                return i+1
        #&#x5982;&#x679C;&#x90FD;&#x5B58;&#x5728;&#xFF0C;&#x8FD4;&#x56DE;N+1
        return n+1
</=>

我们可以知道该算法的时间复杂度和空间复杂度都是O(n),显然空间复杂度不满足题目要求,那我们该如何降低算法的空间复杂度呢?通过观察,我们可以发现辅助数组和原数组大小一样,那么我们能否复用原数组nums呢?答案显然是可以的。我们在遍历数组的过程中,假设遍历到的元素值为x,如果x属于[1,N],我们将元素x和nums[x-1]的元素进行互换,使得x出现在正确的位置上,否则不做处理。当遍历完成后,nums中第一个不满足nums[i-1] = i 条件的就是最小的正整数,如果都满足,那么最小正整数就是N+1。

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:08665535-e629-49e2-9f90-2df9d7ddf4c4

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:60592749-1812-4f2f-b7bf-a5a90cf7b49e

class Solution:
    def firstMissingPositive(self, nums):
        #&#x6570;&#x7EC4;&#x7684;&#x957F;&#x5EA6;
        n = len(nums)
        #&#x904D;&#x5386;&#x6570;&#x7EC4;&#xFF0C;&#x5C06;&#x5143;&#x7D20;&#x653E;&#x5230;&#x6B63;&#x786E;&#x7684;&#x4F4D;&#x7F6E;
        for i in range(n):
            #&#x5982;&#x679C;nums[i]&#x5728;[1,n]&#x7684;&#x8303;&#x56F4;&#x5185;&#xFF0C;&#x5E76;&#x4E14;nums[i]&#x4E0D;&#x5728;&#x6B63;&#x786E;&#x7684;&#x4F4D;&#x7F6E;&#x4E0A;&#xFF0C;&#x6211;&#x4EEC;&#x8FDB;&#x884C;&#x4E92;&#x6362;
            #&#x5426;&#x5219;&#x4E0D;&#x505A;&#x5904;&#x7406;
            while 1 <= 1 nums[i] <="n" \ and nums[nums[i] - 1] !="nums[i]:" 1], #找到数组中第一个不满足nums[i] + 1条件的 #就是数组中的最小正整数 for i in range(n): if 1: return #如果都满足,最小的整数就是n+1 n code></=>

该算法的时间复杂度是O(n),空间复杂度是O(1)。

顺时针旋转数组

问题描述

LeetCode 面试题 01.07. 旋转矩阵

有一个 NxN 整数矩阵,请编写一个算法,将矩阵顺时针旋转90度。

要求:时间复杂度O(N2),空间复杂度是O(N2)。

进阶:时间复杂度是O(N^2),空间复杂度是O(1)

示例:

[                                                       [
  [ 5, 1, 9,11],                &#x65CB;&#x8F6C;90&#x5EA6;&#x540E;                  [15,13, 2, 5],
  [ 2, 4, 8,10],              ============>                [14, 3, 4, 1],
  [13, 3, 6, 7],                                           [12, 6, 8, 9],
  [15,14,12,16]                                            [16, 7,10,11]
]                                                        ]

分析问题

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:3dd3e1dd-134b-494f-a870-6edac1e79124

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:14ed23b3-564c-4ef9-a98d-643d6054fd23

高频算法题之数组详细分析

并且,第一行的第 i 个元素在旋转后恰好是倒数第一列的第 i 个元素。对于第二行的元素也是如此,在旋转后变成倒数第二列的元素,并且第二行的第i个元素在旋转后恰好是倒数第二列的第i个元素。所以,我们可以得出规律,对于矩阵中第 i 行的第 j 个元素,在旋转后,它出现在倒数第 i 列的第 j 个位置,即对于矩阵中的 matrix[i] [j] 元素,在旋转后,它的新位置为 matrix [j] [n-i-1]。

所以,我们申请一个大小为 n * n 的新矩阵,来临时存储旋转后的结果。我们通过遍历matrix中的所有元素,根据上述规则将元素存放到新矩阵中的对应位置。在遍历完成后,再将新矩阵中复制到原矩阵即可。下面我们来看一下代码实现。

class Solution(object):
    def rotate(self, matrix):
"""
        :type matrix: List[List[int]]
        :rtype: None Do not return anything, modify matrix in-place instead.

"""
        #&#x77E9;&#x9635;&#x7684;&#x5927;&#x5C0F;
        n = len(matrix)
        #&#x7533;&#x8BF7;&#x4E00;&#x4E2A;&#x8F85;&#x52A9;&#x77E9;&#x9635;
        temp = [[0] * n for _ in range(n)]
        #&#x904D;&#x5386;&#x77E9;&#x9635;&#x4E2D;&#x7684;&#x6240;&#x6709;&#x5143;&#x7D20;&#xFF0C;&#x653E;&#x5230;&#x8F85;&#x52A9;&#x77E9;&#x9635;&#x7684;&#x76F8;&#x5E94;&#x4F4D;&#x7F6E;&#x4E2D;
        for i in range(n):
            for j in range(n):
                temp[j][n - i - 1] = matrix[i][j]

        #&#x5C06;&#x8F85;&#x52A9;&#x77E9;&#x9635;&#x590D;&#x5236;&#x7ED9;&#x77E9;&#x9635;
        matrix[:] = temp

该算法的时间复杂度是O(N2),空间复杂度O(N2)。

进阶

那我们如何在不使用辅助空间的情况下,实现矩阵的原地旋转呢?我们来看一下方法一中为什么要引入辅助空间,对于matrix中的元素,我们使用公式 temp[j] [n – i – 1] = matrix[i] [j]进行旋转,如果不申请辅助矩阵,我们直接把元素 matrix[i] [j],放到矩阵 matrix[j] [n – i – 1]位置,原矩阵中的 matrix[j] [n – i – 1]元素就被覆盖了,这显然不是我们要的结果。

高频算法题之数组详细分析

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:b25095e3-90cc-499a-98b6-cc1b6fea4d4e

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:75cf83e3-efbb-4e1e-9bd3-a055ce8d437a

  1. 当n为偶数时,我们需要选取 n^2 / 4 = (n/2) * (n/2)个元素进行原地交换操作,可以将该图形分为四块,可以保证不重复、不遗漏旋转所有元素;
  2. 当n为奇数时,由于中心的位置经过旋转后位置不变,我们需要选取 (n^2-1)/4=(n-1)/2 * (n+1) /2个元素进行原地交换操作,我们以5*5的矩阵为例,可以按照以下方式划分,进而保证不重复、不遗漏的旋转所有元素。

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:6c0aa075-dfbd-4779-848d-c1b434bdfc73

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:4fa496cc-f8f9-45a2-a996-0fab47cf5ad4

class Solution(object):
    def rotate(self, matrix):
        #&#x77E9;&#x9635;&#x7684;&#x5927;&#x5C0F;
        n = len(matrix)
        for i in range(n // 2):
            for j in range((n + 1) // 2):
                #&#x8FDB;&#x884C;&#x4E00;&#x8F6E;&#x539F;&#x5730;&#x65CB;&#x8F6C;&#xFF0C;&#x65CB;&#x8F6C;4&#x4E2A;&#x5143;&#x7D20;
                temp = matrix[i][j]
                matrix[i][j] = matrix[n - j - 1][i]
                matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1]
                matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1]
                matrix[j][n - i - 1] = temp

该算法的时间复杂度是O(n^2),空间复杂度是O(1)。

数组中的最长连续子序列

问题描述

LeetCode128. 最长连续序列

给定无序数组arr,返回其中最长的连续子序列的长度(要求值连续,位置可以不连续,例如 3,4,5,6为连续的自然数)。请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例:

输入:[100,4,200,1,3,2]

输出:4

说明:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。

分析问题

因为给定的数组是无序的,所以我们最直观的想法就是遍历数组中的每个元素,然后考虑以其为起点,不断的在数组中寻找x+1,x+2,…,x+n是否存在,如果最长匹配到了x+n,那么就表明以x为起点的最长连续序列为x,x+1,x+2,…,x+n,其长度为n+1。因为在数组中寻找一个数是否存在,是需要O(n)的时间复杂度;而在哈希表中判断一个数是否存在只需要O(1)的时间复杂度,所以我们可以通过引入一个哈希表,来减低该算法的时间复杂度。

在最坏的情况下,该算法的时间复杂度是O(n^2)(即外层需要枚举n个数,内层也需要匹配n次),无法满足题目的要求,那我们如何来进行优化呢?

我们来分析一下算法的执行过程,如果我们已经知道了数组中存在有一个x,x+1,x+2,…,x+n的连续序列,那么我们就没有必要再继续以x+1,x+2,….,x+n为起点去数组中寻找连续序列了,因为得到的结果肯定不会优于以x为起点的连续序列。所以,我们在外层循环中如果碰到这种情况直接跳过就好。

具体做法是,我们在遍历的元素x时,去判读其前驱数x-1是否存在,如果存在的话,就不需要执行后面的逻辑,因为从x-1进行匹配的结果是优于从x进行匹配的,所以跳过x。

高频算法题之数组详细分析

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:03d0e5e8-3300-4979-b69d-bfcf5ed08f9f

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:5e8f51a4-c1fa-4f86-85e4-c16269b4bf43

class Solution:
    def longestConsecutive(self, nums):
        #&#x8BB0;&#x5F55;&#x6700;&#x957F;&#x5B50;&#x5E8F;&#x5217;&#x7684;&#x957F;&#x5EA6;
        length = 0

        #&#x5C06;&#x6570;&#x7EC4;&#x4E2D;&#x7684;&#x5143;&#x7D20;&#x653E;&#x5165;set&#x4E2D;
        num_set = set(nums)

        for num in num_set:
            #&#x5224;&#x65AD;num-1&#x662F;&#x5426;&#x5B58;&#x5728;&#x4E8E;&#x54C8;&#x5E0C;&#x8868;&#x4E2D;&#xFF0C;&#x5982;&#x679C;&#x5B58;&#x5728;&#xFF0C;&#x76F4;&#x63A5;&#x8DF3;&#x8FC7;
            if num - 1 not in num_set:
                currentdata = num
                currentlength = 1
                #&#x7EE7;&#x7EED;&#x5BFB;&#x627E;
                while currentdata + 1 in num_set:
                    currentdata += 1
                    currentlength += 1
                #&#x53D6;&#x6700;&#x5927;&#x503C;
                length = max(currentlength, length)

        return length

该算法的时间复杂度是O(n),空间复杂度也是O(n)。

寻找峰值

问题描述

LeetCode 162. 寻找峰值

峰值元素是指其值严格大于左右相邻值的元素。给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。你可以假设 nums[-1] = nums[n] = -∞ 。你必须实现时间复杂度为 O(log n) 的算法来解决此问题。

示例:

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

输出:3 是峰值元素,你的函数应该返回其索引 2。

分析问题

峰值是指其值严格大于左右相邻值的元素,那么很显然数组中的最大值一定是一个峰值,因为它肯定大于它左右两侧的元素。所以,我们可以对数组进行一次遍历,然后求出其最大值的位置即可。该算法的时间复杂度是O(n),是不满足题目要求的。那我们如何进行优化呢。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:7442143d-e03d-4057-97df-e00658ace4ec

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:18d143b7-9244-4be9-b849-e13a99a5d98f

因此,我们首先在 [0, n) 的范围内随机一个初始位置 i,随后根据nums[i-1],nums[i],nums[i+1]三者的关系决定向哪个方向走。

  • 如何nums[i-1] < nums[i] > nums[i+1],那么位置i就是峰值的位置,我们直接返回i。
  • 如果nums[i-1] < nums [i] < nums[i+1] , 那么位置i处于上坡位置,要想找到峰值,需要往右走,即i=i+1。
  • 如果nums[i-1] > nums[i] > nums[i+1],那么位置i处于下坡位置,要想找到峰值,需要往左走,季i=i-1。
  • 如果nums[i-1] > nums[i] < nums[i+1],此时i处于坡底,要想找到峰值,两个方向都可以,我们假设这种情况需要往右边走。

综上所述,当i不是峰值时。

  • 如果nums[i] > nums[i+1] , i需要往左走,即执行i=i-1。
  • 如果nums[i] < nums[i+1],i需要往右走,即执行i=i+1。
import random
class Solution:
    def findPeakElement(self, nums):
        #&#x6570;&#x7EC4;&#x7684;&#x957F;&#x5EA6;
        n = len(nums)
        #&#x968F;&#x673A;&#x521D;&#x59CB;&#x5316;&#x4E00;&#x4E2A;&#x4F4D;&#x7F6E;
        idx = random.randint(0, n - 1)

        #&#x65B9;&#x4FBF;&#x5904;&#x7406;nums[-1] &#x4EE5;&#x53CA; nums[n]&#x7684;&#x8FB9;&#x754C;&#x60C5;&#x51B5;
        def get_value(i):
            if i == -1 or i == n:
                return float('-inf')
            return nums[i]
        #&#x5F53;i&#x4E0D;&#x662F;&#x5CF0;&#x503C;&#x65F6;&#xFF0C;&#x5982;&#x679C;nums[i] < nums[i+1],&#x6B64;&#x65F6;&#x9700;&#x8981;&#x5411;&#x53F3;&#x8D70;&#xFF0C;&#x5373;i=i+1
        #&#x5426;&#x5219;&#x9700;&#x8981;&#x5411;&#x5DE6;&#x8D70;&#xFF0C;&#x5373;i=i-1
        while not (get_value(idx - 1) < get_value(idx) > get_value(idx + 1)):
            if get_value(idx) < get_value(idx + 1):
                idx = idx + 1
            else:
                idx = idx - 1

        return idx

在最坏的情况下,假设nums是单调递增的,并且我们是从0开始出发的,那这样就需要一直向右走到数组的最后一个位置,该算法的时间复杂度是O(n),而题目要求的时间复杂度是O(logn),显然是不符合的,那我们该如何求解呢?对于像O(logn)这种形式的时间复杂度,我们最先想到的就是二分法,但是数组中的元素又不是排序的,那我们该如何使用二分法来求解此题呢?下面我们就来看一下。

通过分析,我们可以发现,当nums[i] < nums[i+1]时,我们需要让i向右走,即执行i=i+1,那么i和i左边的所有位置在后续的迭代中是永远不会走到的。因为假设此时在i+1的位置,要想向左走到位置i,就需要nums[i] > nums[i+1],显然是不可能的。所以我们可以设计如下算法,首先创建两个变量l、r表示可走的左、右边界,开始时l=0,r=n-1。

  1. 取区间[l,r]的中点,即mid=(l+r)/2。
  2. 如果下标mid是峰值,直接返回。
  3. 如果nums[mid] < nums[mid+1],表示峰值在mid的右边,所以抛弃区间[l,mid],在剩余的[mid+1,r]的区间内去寻找。
  4. 如果nums[mid] > nums[mid+1],表示峰值在mid的左边,所以抛弃区间[mid, r],在剩余的[l,mid-1]的区间内去寻找。

这样的话,该算法每次淘汰掉一半的元素,所以时间复杂度是O(logn)。

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:2de5a328-c64e-4d8b-8da8-d123d2471c90

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:72c1794c-e579-48c1-b212-fc23488cb40f

class Solution:
    def findPeakElement(self, nums):
        n = len(nums)
        # &#x65B9;&#x4FBF;&#x5904;&#x7406; nums[-1] &#x4EE5;&#x53CA; nums[n] &#x7684;&#x8FB9;&#x754C;&#x60C5;&#x51B5;
        def get_value(i):
            if i == -1 or i == n:
                return float('-inf')
            return nums[i]

        #l,r&#x4EE3;&#x8868;&#x533A;&#x95F4;&#x7684;&#x5DE6;&#x53F3;&#x8FB9;&#x754C;
        l=0
        r=n-1
        ans=-1
        while l <= 2 r: #取中点 mid="(l" + r) #如果是峰值,直接返回 if get_value(mid - 1) < get_value(mid)> get_value(mid + 1):
                ans = mid
                break
            #&#x5982;&#x679C;nums[mid]<nums[mid+1],代表峰值在[mid+1,r] 1 #否则在区间[l,mid-1] if get_value(mid) < get_value(mid + 1): l="mid" else: r="mid" - return ans code></nums[mid+1],代表峰值在[mid+1,r]></=>

二维数组中的查找

问题描述

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

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

示例:

现有矩阵 matrix 如下:

[
  [1, 2, 8, 9],
  [2, 4, 9, 12],
  [4, 7, 10, 13],
  [6, 8, 11, 15]
]

给定 target = 9,返回 true

给定 target = 20,返回 false

分析问题

在二维数组中去查找一个元素,我们可以遍历一遍二维数组中的每一个元素,然后去判断是否和目标值相同。该算法的时间复杂度是O(m*n),它显然不是最优的解法。我们接下来来看一下如何进行优化。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:cccea7ea-6483-4ef4-96f7-455b4799f90d

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:fbc6712d-7f3e-4ebb-9f8f-b6fdfef68690

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:b1dfdaaa-ae3b-422f-8f9b-9548c2265165

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:1167b604-a17b-4659-aa8d-36c04d746862

  • 当元素matrix [i] [j] < target,说明target在matrix [i] [j]的右方,所以向右走,即执行 j=j+1。
  • 当元素matrix [i] [j] > target,说明target在matrix [i] [j]的上方,所以向上走,即执行 i= i-1。
  • 当元素matrix [i] [j] == target,代表已经找到了目标值,直接返回true即可。

最后,当超出二维数组的边界时,表示数组中不存在该元素,直接返回false。

高频算法题之数组详细分析

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:4286e58f-8b87-4268-b0c1-e35ddeca3961

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:70baeaa8-ede8-4fc4-9629-c0530b5b2b0d

class Solution(object):
    def findNumberIn2DArray(self, matrix, target):
"""
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
"""
        m=len(matrix)
        #matrix&#x4E3A;&#x7A7A;&#x65F6;&#xFF0C;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;False
        if m==0:
            return False
        n=len(matrix[0])
        #&#x4ECE;&#x5DE6;&#x4E0B;&#x89D2;&#x5F00;&#x59CB;&#x904D;&#x5386;
        i = m - 1
        j = 0
        while i >= 0 and j <= n - 1: # 相等返回true if matrix[i][j]="=" target: return true 大于向上走 elif> target:
                i = i - 1
            # &#x5C0F;&#x4E8E;&#x5411;&#x53F3;&#x8D70;
            elif matrix[i][j] < target:
                j = j + 1
        return False
</=>

该算法的时间复杂度是O(m+n),空间复杂度是O(1)。

数组中的逆序对

问题描述

LeetCode 剑指 Offer 51. 数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。

示例:

输入:[7,5,6,4]

输出:5

分析问题

这道题最容易想到的就是暴力解法,即使用两层for循环,去逐一判断是否构成逆序关系。

class Solution:
    def reversePairs(self, nums) :
        n = len(nums)
        #&#x5982;&#x679C;&#x6570;&#x7EC4;&#x4E2D;&#x7684;&#x5143;&#x7D20;&#x7684;&#x4E2A;&#x6570;
        # &#x4E3A;0&#x6216;&#x8005;1&#x65F6;&#xFF0C;&#x8868;&#x793A;&#x6CA1;&#x6709;&#x9006;&#x5E8F;&#x5BF9;&#xFF0C;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;0
        if n < 2:
            return 0
        #&#x9006;&#x5E8F;&#x5BF9;&#x7684;&#x4E2A;&#x6570;
        res = 0
        #&#x4E24;&#x5C42;&#x5FAA;&#x73AF;&#x53BB;&#x9010;&#x4E00;&#x5224;&#x65AD;&#x662F;&#x5426;&#x662F;&#x9006;&#x5E8F;&#x5BF9;
        for i in range(0,  n - 1):
            for j in range(i + 1, n):
                if nums[i] > nums[j]:
                    res += 1
        return res

该算法的时间复杂度是O(n^2),空间复杂度是O(1)。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:3a438add-a162-49bc-9a43-703a0e19b6f1

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:7e4251b3-ec7b-4a6f-bfce-0c4c8ee6890e

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:a1bfa25f-f324-442b-b6f5-0a90a7128d73

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c4ad8d65-d93a-40a9-8741-7d3e1c4a740c

  1. 分解:假设待排序的区间为[l,r],我们令mid=(l+r)//2,将区间分成[l,mid]和[mid+1,r]两部分。
  2. 解决:使用归并排序递归的求解两个子序列,使其有序。
  3. 合并:把两个已经排好序的子序列[l,mid]和[mid+1,r]合并起来。

下面我们来看一下如何使用归并排序来求解逆序对?关键在于归并排序的合并步骤,即利用数组的部分有序性,一下子计算出一个数之前或者之后的逆序数的个数;下面我们来看一个具体的例子,假设目前有两个已经排好序的序列等待合并,分别是L=[8,17,30,45] 和 R=[10,24,27,39],如下图所示。

高频算法题之数组详细分析

我们来看一下如何把L、R合并成一个有序的数组。整体思路是将原数组拷贝到辅助数组,再使用双指针法,每次将较小的元素归并回去。

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:168e0f30-7da9-48c3-b337-53cac2041a98

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:97e4b778-7595-430b-88e0-393732f67f20

class Solution:
    def reversePairs(self, nums) :
         n = len(nums)
         #&#x6570;&#x7EC4;&#x4E2D;&#x4E2A;&#x6570;&#x5C0F;&#x4E8E;2&#x65F6;&#xFF0C;&#x4E0D;&#x5B58;&#x5728;&#x9006;&#x5E8F;&#x5BF9;&#xFF0C;&#x6240;&#x4EE5;&#x8FD4;&#x56DE;0
         if n < 2:
            return 0

         #&#x7528;&#x4E8E;&#x5F52;&#x5E76;&#x7684;&#x8F85;&#x52A9;&#x6570;&#x7EC4;
         temp = [0 for _ in range(n)]
         return self.reverse_pairs(nums, 0, n - 1, temp)

    #&#x5F52;&#x5E76;&#x6392;&#x5E8F;nums
    def reverse_pairs(self, nums, left, right, temp):
        if left == right:
            return 0
        mid = (left + right)//2
        #&#x5C06;nums&#x5206;&#x6210;&#x5DE6;&#x3001;&#x53F3;&#x4E24;&#x90E8;&#x5206;&#xFF0C;&#x9012;&#x5F52;&#x6C42;&#x89E3;
        left_pairs = self.reverse_pairs(nums, left, mid, temp)
        right_pairs = self.reverse_pairs(nums, mid + 1, right, temp)

        #&#x5B50;&#x5E8F;&#x5217;[left, mid] &#x548C; [mid + 1, right] &#x5DF2;&#x7ECF;&#x5B8C;&#x6210;&#x4E86;&#x6392;&#x5E8F;&#x5E76;&#x4E14;&#x8BA1;&#x7B97;&#x597D;&#x9006;&#x5E8F;&#x5BF9;
        reverse_pairs = left_pairs + right_pairs
        #nums[mid] <= 1 nums[mid + 1],此时[left,right]已经是有序的了 #所以不存在横跨两个区间的逆序对,直接返回reverse_pairs即可 if nums[mid] <="nums[mid" 1]: return reverse_pairs #计算跨两个区间的逆序对 cross_pairs="self.merge_and_count(nums," left, mid, right, temp) def merge_and_count(self, nums, temp): """ [left, mid] 有序,[mid 1, right] 有序,将两个有序的子序列合并成一个有序的子序列 #将nums的元素copy到辅助数组中 for i in range(left, right 1): temp[i]="nums[i]" j="mid" res="0" k #i>mid,&#x8BF4;&#x660E;left&#x90E8;&#x5206;&#x5DF2;&#x7ECF;&#x904D;&#x5386;&#x5B8C;&#xFF0C;&#x76F4;&#x63A5;&#x5C06;right&#x63D2;&#x5165;nums
            if i > mid:
                nums[k] = temp[j]
                j += 1
            #j>right,&#x8BF4;&#x660E;right&#x90E8;&#x5206;&#x5DF2;&#x7ECF;&#x904D;&#x5386;&#x5B8C;&#xFF0C;&#x76F4;&#x63A5;&#x5C06;left&#x63D2;&#x5165;nums
            elif j > right:
                nums[k] = temp[i]
                i += 1
            # &#x6B64;&#x65F6;left&#x6570;&#x7EC4;&#x5143;&#x7D20;&#x5C0F;&#xFF0C;&#x63D2;&#x5165;nums&#x4E2D;&#xFF0C;&#x4E0D;&#x8BA1;&#x7B97;&#x9006;&#x5E8F;&#x6570;
            elif temp[i] <= temp[j]: nums[k]="temp[i]" i +="1" # 此时right数组元素小,插入nums中,统计逆序对, 一次可以统计出一个区间的个数的逆序对 else: j res - 1) return < code></=></=>

该算法的时间复杂度是O(nlogn),空间复杂度是O(1)。

旋转数组

问题描述

LeetCode189. 旋转数组

一个数组A中存有 n 个整数,在不允许使用另外数组的前提下,将每个整数循环向右移 M( M >=0)个位置,即将A中的数据由(A0 A1……An-1 )变换为(An-m…… An-1 A0 A1……An-m-1)(最后 M 个数循环移至最前面的 M 个位置)。

示例:

输入:[1,2,3,4,5,6,7]

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

分析问题

这道题最直观的想法就是使用额外的数组来将每个元素放到正确的位置。我们用n来表示数组的长度,然后遍历原数组,将原数组下标为i的元素放至新数组下标为 (i+k) % n 的位置,最后将新数组拷贝到原数组即可。

class Solution:
    def rotate(self,nums,k):
        n=len(nums)
        tmp=[0]*n

        for i in range(0,n):
            #&#x5C06;&#x6570;&#x7EC4;nums[i]&#x653E;&#x5230;&#x65B0;&#x6570;&#x7EC4;&#x7684;&#x76F8;&#x5E94;&#x4F4D;&#x7F6E;
            tmp[(i+k)%n]=nums[i]
        #&#x5C06;&#x65B0;&#x6570;&#x7EC4;&#x62F7;&#x8D1D;&#x5230;&#x539F;&#x6570;&#x7EC4;
        nums[:]=tmp[:]

该算法的时间复杂度是O(n),空间复杂度也是O(n)。但是题目要求不允许使用另外的数组,显然该算法是不符合题意的。我们来观察一下数组移动前后的变化,当我们将数组的元素向右移动k次后,尾部 k mod n个元素会移动至数组的头部,其余元素向后移动k mod n 个位置。因此我们可以采用数组翻转的方法来求解。具体思路如下:首先我们将所有元素进行翻转,这样尾部k mod n个元素就被移动到数组的头部。然后我们再翻转 [0, (k mod n)-1] 区间的元素和 [k mod n, n-1]区间的元素,即能得到最后的答案。

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:3ada4bca-004e-4f4a-a738-016f6fd4dd33

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:e9a3d014-38d7-4333-9008-c5793d966258

class Solution:
    #&#x5BF9;&#x6570;&#x7EC4;&#x4E2D;&#x7684;&#x5143;&#x7D20;&#x8FDB;&#x884C;&#x7FFB;&#x8F6C;
    def reverse(self,nums,start,end):
        while start < end:
            tmp=nums[start]
            nums[start]=nums[end]
            nums[end]=tmp
            start=start+1
            end=end-1
    def rotate(self,nums,k):
        n=len(nums)
        k=k%n
        #&#x5BF9;&#x6570;&#x7EC4;&#x8FDB;&#x884C;&#x53CD;&#x8F6C;
        self.reverse(nums,0,n-1)
        #&#x5BF9;&#x533A;&#x95F4;nums[0,k-1]&#x518D;&#x8FDB;&#x884C;&#x7FFB;&#x8F6C;
        self.reverse(nums,0,k-1)
        #&#x5BF9;&#x533A;&#x95F4;nums[k,n-1]&#x518D;&#x8FDB;&#x884C;&#x7FFB;&#x8F6C;
        self.reverse(nums,k,n-1)

该算法的时间复杂度是O(n),空间复杂度是O(1)。

调整数组顺序使奇数位于偶数前面

问题描述

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:12a0501f-a865-4fee-a4bb-c375f33d7fdd

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:0cebe224-7894-4b22-af28-05c38d2af3e5

示例:

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

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

分析问题

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:fe8744b9-154a-42f4-8e30-4cf8b07dc4fd

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:ce9551ac-bdd3-4d3c-a2a4-d6b3840288c8

  1. 首先,申请两个指针i和j,分别指向数组nums的左右两端,即i=0,j=n-1。
  2. 当i所指的位置为奇数时,执行i=i+1,直到遇到偶数。
  3. 当j所指的位置为偶数时,执行j=j-1,直到遇到奇数。
  4. 然后交换nums[i]和nums[j]的值
  5. 重复上述操作,直到i==j为止。

高频算法题之数组详细分析

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:d934fd7e-3927-4e92-af76-a7f648f2dce5

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:36cf0ddd-9c4c-40c7-bb3c-049f971bb3db

class Solution(object):
    def exchange(self, nums):
        #&#x7533;&#x8BF7;&#x4E24;&#x4E2A;&#x53D8;&#x91CF;i&#x548C;j,&#x5F00;&#x59CB;&#x65F6;&#xFF0C;&#x6307;&#x5411;&#x6570;&#x7EC4;&#x7684;&#x4E24;&#x7AEF;
        i=0
        j=len(nums)-1
        while i < j:
            #&#x4ECE;i&#x5F00;&#x59CB;&#x4ECE;&#x5DE6;&#x5411;&#x53F3;&#x5BFB;&#x627E;&#xFF0C;&#x76F4;&#x5230;&#x627E;&#x5230;&#x7B2C;&#x4E00;&#x4E2A;&#x5076;&#x6570;
            while i < j and nums[i] % 2 == 1:
                i = i + 1
            #&#x4ECE;j&#x5F00;&#x59CB;&#x4ECE;&#x53F3;&#x60F3;&#x5DE6;&#x5BFB;&#x627E;&#xFF0C;&#x76F4;&#x5230;&#x627E;&#x5230;&#x7B2C;&#x4E00;&#x4E2A;&#x5947;&#x6570;
            while i < j and nums[j] % 2 == 0:
                j = j - 1
            nums[i], nums[j] = nums[j], nums[i]
        return nums

其实这道题我们还可以使用快慢指针法来求解,首先我们定义两个指针fast和slow,fast的作用是向前搜索奇数所在的位置,slow的作用是指向下一个奇数应当存放的位置。在fast向前移动的过程中,当它搜索到奇数时,将它和nums[slow]进行交换,然后让slow向前移动一个位置,重复上述操作,直到fast指向数组的末尾为止。

class Solution:
    def exchange(self, nums):
        slow = 0
        fast = 0
        #&#x5FAA;&#x73AF;&#x904D;&#x5386;&#xFF0C;&#x76F4;&#x5230;fast&#x6307;&#x5411;nums&#x7684;&#x672B;&#x5C3E;
        while fast < len(nums):
            #&#x5982;&#x679C;fast&#x6307;&#x5411;&#x5947;&#x6570;&#xFF0C;
            #&#x4EA4;&#x6362;nums[slow]&#x548C;nums[fast]
            if nums[fast] % 2 == 1:
                nums[slow], nums[fast] = nums[fast], nums[slow]
                slow=slow+1
            fast=fast+1
        return nums

该算法的时间复杂度是O(n),空间复杂度是O(1)。

矩阵乘法

问题描述

给定两个n * n 的矩阵A和B,求A * B。

示例:

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

输出:[[7,6],[13,14]]

分析问题

我们可以使用矩阵乘法规则来求解。对于n * n的矩阵A和矩阵B相乘,所得矩阵C的第i行第j列的元素可以表示为Ci,j=Ai,1* B1,j + Ai,2 * B2,j + … + Ai,n * Bn,j , 即等于A的第i行和B的第j列对应元素的乘积之和。

高频算法题之数组详细分析
class Solution:
    def solve(self , a, b):
        # write code here
        #&#x77E9;&#x9635;a&#x548C;&#x77E9;&#x9635;b&#x662F;n*n&#x7684;&#x77E9;&#x9635;
        n=len(a)
        res=[[0] * n for _ in range(n)]

        for i in range(0,n):
            for j in range(0,n):
                for k in range(0,n):
                    #C&#x7684;&#x7B2C;i&#x884C;&#x7B2C;j&#x5217;&#x7684;&#x5143;&#x7D20;&#x4E3A;
                    #A&#x7684;&#x7B2C;i&#x884C;&#x548C;B&#x7684;&#x7B2C;j&#x5217;&#x5BF9;&#x5E94;&#x5143;&#x7D20;&#x4E58;&#x79EF;&#x7684;&#x548C;
                    res[i][j] += a[i][k]*b[k][j]
        return res

该算法的时间复杂度是O(N3),空间复杂度是O(N2)。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:04f96915-7654-4fb7-ae54-f47df6b4dfbc

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:91c376ee-e75b-4c7f-a6f2-39c922d316cb

高频算法题之数组详细分析

因为操作系统加载数据到缓存中时,都是把命中数据附近的一批数据一起加载到缓存中,因为操作系统认为如果一个内存位置被引用了,那么程序很可能在不久的未来引用附近的一个内存位置。所以我们通过调整数组的读取顺序来进行优化,使得矩阵A和B顺序读取,然后相继送入CPU中进行计算,最后使得运行时间能够更快。下面我们来看一下具体做法:

class Solution:
    def solve(self , a, b):
        # write code here
        #&#x77E9;&#x9635;a&#x548C;&#x77E9;&#x9635;b&#x662F;n*n&#x7684;&#x77E9;&#x9635;
        n=len(a)
        res=[[0] * n for _ in range(n)]

        for i in range(0,n):
            for j in range(0,n):
                #&#x987A;&#x5E8F;&#x8BBF;&#x95EE;&#x77E9;&#x9635;A&#x7684;&#x5143;&#x7D20;
                temp=a[i][j]

                for k in range(0,n):
                    #&#x77E9;&#x9635;b&#x7684;&#x5143;&#x7D20;&#x4E5F;&#x662F;&#x987A;&#x5E8F;&#x8BBF;&#x95EE;&#x7684;
                    res[i][k] += temp * b[j][k]

        return res

该算法的时间复杂度是O(N3),但是该算法利用了缓存优化,顺序读取数组A和数组B中的元素,因此一般会比第一种方法运行更快。该算法的空间复杂度是O(N2)。

数字在升序数组中出现的次数

问题描述

给定一个长度为 n 的非降序数组和一个非负数整数 k ,要求统计 k 在数组中出现的次数。

示例:

输入:[1,2,3,3,3,3,4,5],3

输出:4

分析问题

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:60fd3c1a-a888-4079-b193-1929d10cb08d

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:f94d632e-8968-4383-b73d-489b50b7e54a

class Solution:
    def GetNumberOfK(self,data, k):
        n=0
        for x in data:
            if x==k:
               n=n+1
        return n

该算法的时间复杂度是O(n),空间复杂度是O(1)。

因为题目给定的数组是有序的,所以我们可以使用二分查找来求解。对于有序的数组,如果要寻找的目标值target有多个,那么他们肯定是连在一起的,所以我们可以通过二次二分查找,分别寻找目标值所在范围的上界和下界。首先,我们来看一下上界和下界的定义。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c2e0913f-f888-44d0-b026-9cb644d6e091

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:e3496843-e164-4041-878f-086613081144

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:1dea854e-0d50-494a-8da8-7abd002276c5

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:ab95730e-23a2-496e-b290-d813cb150335

高频算法题之数组详细分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:8cdb230b-96b4-4bfd-ad20-252dea79898d

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:accf585d-4a26-4db3-ba6a-fa3ea9958b37

class Solution:
    def GetNumberOfK(self,data, k):
        l=0
        r=len(data)-1

        #&#x4E8C;&#x5206;&#x6CD5;&#x5BFB;&#x627E;&#x4E0B;&#x754C;
        while l<r: 1 2 mid="(r+l)" if data[mid] < k: l="mid" + else: r="mid" left="l" #寻找上界 while l<r: right="l" return - code></r:>

该算法的时间复杂度是O(logN),空间复杂度是O(1)。

三个数的最大乘积

问题描述

给定一个长度为 n 的无序数组 A ,包含正数、负数和 0 ,请从中找出 3 个数,使得乘积最大,返回这个乘积。

示例:

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

输出:24

分析问题

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:b018f99e-121d-410e-a5f8-aa268c4c22e7

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:53725930-477f-40fc-a37f-9146271a3555

  1. 如果数组中的元素全是非负数或者非正数,那么数组中最大的三个数相乘就是最大乘积。
  2. 如果数组中的元素既有正数也有负数,那么最大的乘积既可能是三个最大正数的乘积,也可能是两个最小负数(绝对值最大)和最大正数的乘积。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:040f62cb-e197-4eb0-a343-fdcea453ed07

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:1921a16c-bd11-4d83-8e6c-b1a8e7816d0d

class Solution:
    def maximumProduct(self,nums):
        nums=sorted(nums)
        n=len(nums)
        return max(nums[0] * nums[1] * nums[n-1], nums[n - 3] * nums[n - 2] * nums[n-1])

该算法的时间复杂度是O(nlogn),其中n为数组的长度。排序需要O(nlogn)的时间。

空间复杂度是O(logn),主要是排序的开销。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:23b79487-571b-4904-a6ad-48056c03fd73

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:6302a52f-9a52-4708-ad5a-904705aabd61

import sys
class Solution:
    def maximumProduct(self,nums):
        #&#x6700;&#x5C0F;&#x548C;&#x7B2C;&#x4E8C;&#x5C0F;
        min1=min2=sys.maxsize
        #&#x6700;&#x5927;&#x3001;&#x7B2C;&#x4E8C;&#x5927;&#x3001;&#x7B2C;&#x4E09;&#x5927;
        max1=max2=max3=-sys.maxsize-1
        for x in nums:
            if x < min1:
                min2=min1
                min1=x
            elif x<min2: min2="x" if x>max1:
                max3=max2
                max2=max1
                max1=x
            elif x>max2:
                max3=max2
                max2=x
            elif x>max3:
                max3=x

        return max(max1*max2*max3,max1*min1*min2)
</min2:>

该算法的时间复杂度是O(n),空间复杂度是O(1)。

最后

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c287eb03-5871-4559-99ec-94f7a4c822d1

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:cf8154f6-0649-4ea3-9dc6-27911163faa0

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:b8f098cd-b343-47ca-aa42-d2e86d6de9a5

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:fc4e6233-e9e5-43b3-af3c-02b38b47e74c

Original: https://www.cnblogs.com/cxyxz/p/15525429.html
Author: 算法推荐管
Title: 高频算法题之数组详细分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/562443/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球