这是我参与『掘金日新计划·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] <= 1000nums[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^51 <= 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^51 <= 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