日渐头秃的代码日记 -- 第315场周赛划水

112 阅读3分钟

这是我参与『掘金日新计划·10月更文挑战』的第3天。 划水一天

一、与对应负数同时存在的最大正整数

给你一个 不包含 任何零的整数数组 nums ,找出自身与对应的负数都在数组中存在的最大正整数 k 。

返回正整数 k ,如果不存在这样的整数,返回 -1 。

 

示例 1:

输入: nums = [-1,2,-3,3]
输出: 3
解释: 3 是数组中唯一一个满足题目要求的 k 。

示例 2:

输入: nums = [-1,10,6,7,-7,1]
输出: 7
解释: 数组中存在 1 和 7 对应的负数,7 的值更大。

示例 3:

输入: nums = [-10,8,6,7,-2,-3]
输出: -1
解释: 不存在满足题目要求的 k ,返回 -1 。

 

提示:

  • 1 <= nums.length <= 1000
  • -1000 <= nums[i] <= 1000
  • nums[i] != 0

解析

第一题比较简单,数组长度最多才1000,直接遍历就行了,需要注意的是,k是正整数,因此只需要遍历正数即可。

代码

class Solution:
    def findMaxK(self, nums: List[int]) -> int:
        new_nums = sorted(nums)[::-1]
        new_nums = [n for n in new_nums if n > 0]
        for num in new_nums:
            if -num in nums:
                return num
        return -1

二、反转之后不同整数的数目

给你一个由  整数组成的数组 nums 。

你必须取出数组中的每个整数,反转其中每个数位,并将反转后得到的数字添加到数组的末尾。这一操作只针对 nums 中原有的整数执行。

返回结果数组中 不同 整数的数目。

 

示例 1:

输入: nums = [1,13,10,12,31]
输出: 6
解释: 反转每个数字后,结果数组是 [1,13,10,12,31,1,31,1,21,13] 。
反转后得到的数字添加到数组的末尾并按斜体加粗表示。注意对于整数 10 ,反转之后会变成 01 ,即 1 。
数组中不同整数的数目为 6(数字 1、10、12、13、21 和 31)。

示例 2:

输入: nums = [2,2,2]
输出: 1
解释: 反转每个数字后,结果数组是 [2,2,2,2,2,2] 。
数组中不同整数的数目为 1(数字 2)。

 

提示:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^6

解析

按照题目模拟就行,就集合来处理

代码

class Solution:
    def countDistinctIntegers(self, nums: List[int]) -> int:
        nums = set(nums)
        x = copy.copy(nums)
        for num in nums:
            y = int(str(num)[::-1])
            x.add(y)
        print(len(x))
        return len(x)

三、反转之后的数字和

给你一个 非负 整数 num 。如果存在某个 非负 整数 k 满足 k + reverse(k) = num  ,则返回 true ;否则,返回 false 。

reverse(k) 表示 k 反转每个数位后得到的数字。

 

示例 1:

输入: num = 443
输出: true
解释: 172 + 271 = 443 ,所以返回 true

示例 2:

输入: num = 63
输出: false
解释: 63 不能表示为非负整数及其反转后数字之和,返回 false

示例 3:

输入: num = 181
输出: true
解释: 140 + 041 = 181 ,所以返回 true 。注意,反转后的数字可能包含前导零。

 

提示:

  • 0 <= num <= 10^5

解析

num最大只有一万,直接遍历即可

代码

class Solution:
    def sumOfNumberAndReverse(self, num: int) -> bool:
        if num == 0:
            return True
        for n in range(num):
            x = n
            y = int(str(n)[::-1])
            if x + y == num:
                return True
        return False

四、统计定界子数组的数目

给你一个整数数组 nums 和两个整数 minK 以及 maxK 。

nums 的定界子数组是满足下述条件的一个子数组:

  • 子数组中的 最小值 等于 minK 。
  • 子数组中的 最大值 等于 maxK 。

返回定界子数组的数目。

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

 

示例 1:

输入: nums = [1,3,5,2,7,5], minK = 1, maxK = 5
输出: 2
解释: 定界子数组是 [1,3,5][1,3,5,2]

示例 2:

输入: nums = [1,1,1,1], minK = 1, maxK = 1
输出: 10
解释: nums 的每个子数组都是一个定界子数组。共有 10 个子数组。

 

提示:

  • 2 <= nums.length <= 10^5
  • 1 <= nums[i], minK, maxK <= 10^6

解析

数组长度上万,暴力枚举会超时,果不其然,暴力方法48个case通过了45个。

首先对nums进行一个简单的预处理,把不符合要求的数字段落都去掉,分割成若干子区间,再对每一个子区间计算定界子数组的数目,求和之后得到最终结果。

对于一个子区间,我们从左到右遍历每一个数字,将此时以该数字为结尾的数组的定界子数组数目加起来,就是总体子区间的定界子数组的数目了,而以它自己结尾的定界子数组数目,就是它左边离它最近的那组minK和maxK左边还剩下的数字个数。

代码

class Solution:
    def countSubarrays(self, nums: List[int], minK: int, maxK: int) -> int:
        if len(set(nums)) == 1 and nums[0] == minK and minK == maxK:
            return int((1 + len(nums)) * len(nums) / 2)
        if min(nums) > minK or max(nums) < maxK:
            return 0
        self.minK = minK
        self.maxK = maxK
        all_candidates_list = []
        temp_list = []
        min_found = False
        max_found = False
        for i in range(len(nums)):
            if nums[i] < minK or nums[i] > maxK:
                if min_found and max_found:
                    all_candidates_list.append(temp_list)
                    temp_list = []
                    min_found = False
                    max_found = False
                else:
                    temp_list = []
                    min_found = False
                    max_found = False
            else:
                if nums[i] == minK:
                    min_found = True
                if nums[i] == maxK:
                    max_found = True
                temp_list.append(nums[i])
        if min_found and max_found:
            all_candidates_list.append(temp_list)
        # print(all_candidates_list)
        count = 0
        for candidates in all_candidates_list:
            min_index = -1
            max_index = -1
            for index, num in enumerate(candidates):

                if num == minK:
                    min_index = index+1
                if num == maxK:
                    max_index = index+1
                count += max(0, min(min_index, max_index))

        return count