3.2.1 LeetCode数组类题目选做(1)—— First Missing Positive & Majority Element & Product of Array Except Self

数组题目概述

数组的题目很多很重要,一般和其他知识点综合应用。包括Two pointer,Binary Search,Dynamic Programming,Greedy,Backtracking 等,各类算法都将分别选做一些题目学习交流总结。

这一系列选择出一些非应用上述知识点,而是一些奇思妙想的、套路很深的数组的题目,总结后扩展思路,领悟一些可能会再次遇见的套路,也许可以处理类似的问题。

Array 类题目选做之一

41. First Missing Positive

Given an unsorted integer array, find the smallest missing positive integer.

Example 1:

Input: [1,2,0]
Output: 3

Example 2:

Input: [3,4,-1,1]
Output: 2

Note:

Your algorithm should run in O(n) time and uses constant extra space.

解析:

比较难的一道题,hard,鄙人只先想到了空间复杂度O(n)的算法(当然就是用数组把数字排好了),那么不占用另一个数组怎么办?其实就是在nums上原地交换,交换的限制条件和终止条件是算法的难点。相比之下268题 Missing Number就简单多了。

class Solution:
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        for i in range(len(nums)):
            # swap nums[i] to i - 1 then use nums[i - 1] as new target to swap
            while nums[i] > 0 and nums[i] <= len(nums) and nums[nums[i] - 1] != nums[i]:
                nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]                
        
        for i in range(len(nums)):
            if nums[i] != i + 1:
                return i + 1        
        return len(nums) + 1

229. Majority Element II

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times.

Note: The algorithm should run in linear time and in O(1) space.

解析:

同样,这道题用O(n)space又是很easy的,后面给出的许多解答也都是这样的,一行代码解决问题,还速度超快:

from collections import Counter
return [k for k,v in Counter(nums).items() if v > len(nums)//3]

用O(1)的算法,是一个很有趣很值得细细品味的算法,总结起来就是“活到最后”,要求频率大于 n/3,因此结果最多有两个,设置两个候选数字,遍历数组,是的话count加1,都不是,都减1,等于0了就下台(换个数)。细细品味,最终剩下的一定是最多的两个,但是count不一定能记录真正的频率,因此第二遍遍历计数。代码如下:

class Solution:
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        n = len(nums)
        num1, num2 = 0, 1
        cn1, cn2 = 0, 0
        res = []
        for num in nums:
            if num == num1:
                cn1 += 1
            elif num == num2:
                cn2 += 1
            elif not cn1:
                num1 = num
                cn1 += 1
            elif not cn2:
                num2 = num
                cn2 += 1
            else:
                cn1 -= 1
                cn2 -= 1
        cn1, cn2 = 0, 0
        for num in nums:
            if num == num1:
                cn1 += 1
            elif num == num2:
                cn2 += 1
        if cn1 > n//3:
            res.append(num1)
        if cn2 > n//3:
            res.append(num2)
        return res

当然,有了这道题,169题找出过半的数字,就如出一辙了。


238. Product of Array Except Self

Given an array nums of n integers where n > 1,  return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].

Note: Please solve it without division and in O(n).

Follow up:
Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.)

解析:

关键是不用除法,O(n)时间,分析每个结果的组成,由它之前的数的乘积和它之后的数的乘积组成,因此作出如下算法,建立output数组,遍历第一遍,依次乘每个元素,output每个位置存放它前面的数字的乘积,再从后向前遍历,output每个位置乘上它后面的数字的乘积,注意对应关系即可。代码如下,很简洁:

class Solution:
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        output = [1]
        prod = 1
        for num in nums[:-1]:
            prod *= num
            output.append(prod)
        
        prod = 1
        for i in range(len(nums), 0, -1):
            output[i-1] *= prod
            prod *= nums[i-1]
        
        return output

相当于总结了五道题,没有什么通用的思路,多找规律,下面一节继续选几道题学习总结~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值