知识储备--基础算法篇-数组

1.学习

2.数组

2.1第53题-最大子数组和

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

子数组是数组中的一个连续部分。

心得:一直在纠结这个连续的事情,最后发现根本没必要管,因为如果前一个数与当前数相加小于当前数,前面的部分就会直接被舍弃,如果相加大于当前数则会一直叠加。

python 复制代码
class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        dp = copy.deepcopy(nums)
        max_ = dp[0]
        for i in range(1,len(nums)):
            dp[i] = max(dp[i-1]+nums[i], dp[i])
            if max_ < dp[i]:
                max_ = dp[i]

        return max_

时间和内存占用太多,根本没必要再生成一个dp数组,直接用nums数组更新就行。

python 复制代码
class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        # dp = copy.deepcopy(nums)
        max_ = nums[0]
        for i in range(1,len(nums)):
            nums[i] = max(nums[i-1]+nums[i], nums[i])
            if max_ < nums[i]:
                max_ = nums[i]

        return max_

2.2第56题-合并区间

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

示例 1:

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

示例 2:

复制代码
输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
python 复制代码
class Solution(object):
    def merge(self, intervals):
        """
        :type intervals: List[List[int]]
        :rtype: List[List[int]]
        """
        new_int = []
        a = []
        intervals.sort()
        for i in range(1,len(intervals)):
            # 前一个end大于后一个start
            if intervals[i-1][1] > intervals[i][0]:
                # 前一个end小于后一个end
                if intervals[i-1][1] <= intervals[i][1]:
                    intervals[i] = [intervals[i-1][0], intervals[i][1]]
                else:
                    intervals[i] = intervals[i-1]
            elif intervals[i-1][1] == intervals[i][0]:
                intervals[i] = [intervals[i-1][0], intervals[i][1]]
            else:
                new_int.append(intervals[i-1])

        new_int.append(intervals[-1])
        
        return new_int

2.3第189题-轮转数组

给定一个整数数组 nums,将数组中的元素向右轮转 k个位置,其中 k是非负数。

示例 1:

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
python 复制代码
class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        # if k == 0:
        #     return nums
        nums1 = copy.deepcopy(nums)
        k = k % len(nums)
        start = len(nums)-k
        # nums2 = []
        # nums1 = nums[:start]
        # nums2 = nums[start:]
        
        for i in range(len(nums)):
            if i < k:
                nums[i] = nums[start+i]
            else:
                nums[i] = nums1[i-k]

感觉不用深拷贝整个数组

python 复制代码
class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        k = k % len(nums)
        start = len(nums)-k
        nums1 = nums[:start]
        nums2 = nums[start:]
        for i in range(len(nums2)):
            nums[i] = nums2[i]
        for j in range(len(nums1)):
            nums[j+k] = nums1[j]

看了答案,发现我最早想出的方法就是最简单的答案,nums[:]=nums[start:]+nums[:start],但是发现一直不能修改nums的值,看了答案发现nums忘记加[:]了,吐了。

python 复制代码
class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        k = k % len(nums)
        start = len(nums)-k
        nums[:] = nums[start:] + nums[:start]

2.4除自身以外数组的乘积

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

不要使用除法, 且在 O(n) 时间复杂度内完成此题。

示例 1:

输入: nums = [1,2,3,4]
输出: [24,12,8,6]

先用最简单的遍历法,果然超时。

python 复制代码
class Solution(object):
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        len_ = len(nums)
        answer = [1]*len_
        for i in range(len_):
            for j in range(len_):
                if j != i:
                    answer[i] = answer[i]*nums[j]
                
        return answer

然后把数组分为i点的前半部分和后半部分相乘来计算,这样的话减少很多重复计算的时间。

python 复制代码
class Solution(object):
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        # 可以把乘积分为前半部分和后半部分
        len_ = len(nums)
        answer = [1]*len_
        forward = [1]*len_
        back = [1]*len_
        for i in range(1,len_):
            forward[i] = forward[i-1]*nums[i-1]
        
        for j in reversed(range(len_-1)):
            back[j] = back[j+1]*nums[j+1]
        
        for k in range(len_):
            answer[k] = forward[k]*back[k]
        return answer

看了答案,知道了左边的乘积其实可以动态的变化

python 复制代码
class Solution(object):
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        # 可以把乘积分为前半部分和后半部分
        len_ = len(nums)
        answer = [1]*len_
        back = 1
        for i in range(1,len_):
            answer[i] = answer[i-1]*nums[i-1]
        
        for j in reversed(range(len_)):
            answer[j] = answer[j]*back
            back = back * nums[j]

        return answer

2.5第41题-缺失的第一个正数

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

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

示例 1:

复制代码
输入:nums = [1,2,0]
输出:3

用最朴素的方法来寻找,不出所料,超时。

python 复制代码
class Solution(object):
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        for i in range(len(nums)-1):
            j = 0
            while j < len(nums)-1-i:
                if nums[j] > nums[j+1]:
                    temp = nums[j]
                    nums[j] = nums[j+1]
                    nums[j+1] = temp
                j = j + 1
        
        # print(nums)
        if nums[-1] <= 0:
            return 1
        
        index_1 = 0
        for j in range(len(nums)):
            if nums[j] > 0:
                if nums[j] != 1:
                    return 1
                else:
                    index_1 = j
                    break
        a = 1
        # print(index_1)
        for k in range(index_1+1,len(nums)):
            a = a + 1
            if nums[k] == a:
                continue
            elif nums[k] == a-1:
                a = a - 1
                continue
            else:
                return a

        return a + 1

看了解析,知道当nums长度为N时,正数的数目肯定在[1,N]范围内,这时候就可以用哈希表来查找,内存占用多但速度快。把nums中的数都放在哈希表中,然后遍历[1,N],如果有哈希表中不存在则返回i,若都存在则返回i+1。

python 复制代码
class Solution(object):
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        hash_table = set(nums)
        n = len(nums)
        a = 0
        for i in range(1,n+1):
            if i in hash_table:
                a = i
                continue
            else:
                return i
        
        return a + 1
相关推荐
游是水里的游26 分钟前
【算法day19】回溯:分割与子集问题
算法
不想当程序猿_26 分钟前
【蓝桥杯每日一题】分糖果——DFS
c++·算法·蓝桥杯·深度优先
南城花随雪。1 小时前
单片机:实现FFT快速傅里叶变换算法(附带源码)
单片机·嵌入式硬件·算法
dundunmm1 小时前
机器学习之scikit-learn(简称 sklearn)
python·算法·机器学习·scikit-learn·sklearn·分类算法
古希腊掌管学习的神1 小时前
[机器学习]sklearn入门指南(1)
人工智能·python·算法·机器学习·sklearn
波音彬要多做1 小时前
41 stack类与queue类
开发语言·数据结构·c++·学习·算法
程序员老冯头3 小时前
第十五章 C++ 数组
开发语言·c++·算法
AC使者8 小时前
5820 丰富的周日生活
数据结构·算法
cwj&xyp8 小时前
Python(二)str、list、tuple、dict、set
前端·python·算法
xiaoshiguang312 小时前
LeetCode:222.完全二叉树节点的数量
算法·leetcode