给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
示例 1:
输入: [3,2,3]
输出: 3
示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2
解法1
注意最多的元素出现的次数大于数组长度的一半,所以使用如下的代码,在最极端的情况下,最后的count都会大于0,cand就是所要找的元素
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
cand = nums[0]
count = 1
for i in nums[1:]:
if count == 0:
cand, count = i, 1
else:
if i == cand:
count = count + 1
else:
count = count - 1
return cand
解法2:用sort方法
class Solution:
def majorityElement(self, nums: List[int]) -> int:
return sorted(nums)[len(nums)//2]
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [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]
示例 2:
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
解法
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
nums[:] = nums[n - k:] + nums[:n - k]
给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。
示例 1:
输入: [1,2,3,1]
输出: true
示例 2:
输入: [1,2,3,4]
输出: false
示例 3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true
解法:利用set不能保存重复元素的特性,判断前后两个数组长度是否相同即可。
class Solution:
def containsDuplicate(self, nums: List[int]) -> bool:
list_len = len(nums)
set_len = len(set(nums))
if list_len == set_len:
return False
else:
return True
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。
示例 1:
输入: nums = [1,2,3,1], k = 3
输出: true
示例 2:
输入: nums = [1,0,1,1], k = 1
输出: true
示例 3:
输入: nums = [1,2,3,1,2,3], k = 2
输出: false
解法:用dict保存数组元素出现的位置,两种情况下更新
class Solution:
def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
dic = dict()
for index,value in enumerate(nums):
if value in dic and index - dic[value] <= k:
return True
dic[value] = index
return False
给定一个包含 0, 1, 2, …, n 中 n 个数的序列,找出 0 … n 中没有出现在序列中的那个数。
示例 1:
输入: [3,0,1]
输出: 2
示例 2:
输入: [9,6,4,2,3,5,7,0,1]
输出: 8
解法
class Solution:
def missingNumber(self, nums: List[int]) -> int:
n = len(nums)
return n * (n+1) //2 - sum(nums)
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
解法
遍历数组,用一个变量记录当前不为0的个数,同时也是新不为零元素插入的位置:
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
index = 0
for num in nums:
if num != 0:
nums[index] = num
index += 1
for i in range(index, len(nums)):
nums[i] = 0
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
示例 1:
输入: [3, 2, 1]
输出: 1
解释: 第三大的数是 1.
示例 2:
输入: [1, 2]
输出: 2
解释: 第三大的数不存在, 所以返回最大的数 2 .
示例 3:
输入: [2, 2, 3, 1]
输出: 1
解释: 注意,要求返回第三大的数,是指第三大且唯一出现的数。
存在两个值为2的数,它们都排第二。
解法
这里用三个值记录前三大的数字,要注意是三个不同的数字,重复的数字不记录排序,所以要注意判断条件:
class Solution:
def thirdMax(self, nums: List[int]) -> int:
max1 = max2 = max3 = float('-inf')
for num in nums:
if num > max1:
max2, max3 = max1, max2
max1 = num
elif num < max1 and num > max2:
max2, max3 = num, max2
elif num < max2 and num > max3:
max3 = num
return max1 if max3 == float('-inf') else max3
给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。
找到所有在 [1, n] 范围之间没有出现在数组中的数字。
您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。
示例:
输入:
[4,3,2,7,8,2,3,1]
输出:
[5,6]
解法
这个题就比较神奇了,注意到数组元素个数跟元素范围是一样的,所以我们可以把出现过的元素对应下标位置的数字变成负数,最后把所有正数对应的下标拿出来,就是缺失的数字。
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
for i in range(len(nums)):
index = abs(nums[i])-1
nums[index] = -abs(nums[index])
return [i+1 for i in range(len(nums)) if nums[i] > 0]
给定一个二进制数组, 计算其中最大连续1的个数。
示例 1:
输入: [1,1,0,1,1,1]
输出: 3
解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3.
注意:
输入的数组只包含 0 和1。
输入数组的长度是正整数,且不超过 10,000。
解法
class Solution:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
cnt = 0
res = 0
for i in range(len(nums)):
if nums[i] == 1:
cnt += 1
res = max(res, cnt)
else:
cnt = 0
return res
给定一个整数数组和一个整数 k, 你需要在数组里找到不同的 k-diff 数对。这里将 k-diff 数对定义为一个整数对 (i, j), 其中 i 和 j 都是数组中的数字,且两数之差的绝对值是 k.
示例 1:
输入: [3, 1, 4, 1, 5], k = 2
输出: 2
解释: 数组中有两个 2-diff 数对, (1, 3) 和 (3, 5)。
尽管数组中有两个1,但我们只应返回不同的数对的数量。
示例 2:
输入:[1, 2, 3, 4, 5], k = 1
输出: 4
解释: 数组中有四个 1-diff 数对, (1, 2), (2, 3), (3, 4) 和 (4, 5)。
示例 3:
输入: [1, 3, 1, 5, 4], k = 0
输出: 1
解释: 数组中只有一个 0-diff 数对,(1, 1)。
注意:
数对 (i, j) 和数对 (j, i) 被算作同一数对。
数组的长度不超过10,000。
所有输入的整数的范围在 [-1e7, 1e7]。
解法1
使用collections集合模块
class Solution:
def findPairs(self, nums: List[int], k: int) -> int:
if k>0:
return len(set(nums) & set(n+k for n in nums))
elif k==0:
return sum(v>1 for v in collections.Counter(nums).values())
else:
return 0
解法2
不使用collections集合模块
class Solution:
def findPairs(self, nums: List[int], k: int) -> int:
count,n=0,len(nums)
s=set(nums)
if k<0 or len(nums)<2:
return 0
if k==0:
for ele in s:
if nums.count(ele)>1:
count+=1
return count
for ele in s:
#保证数据的不重复,同时不选自己
if ele+k in s:
count+=1
return count
参考:https://blog.csdn.net/qq_41929011/article/details/88532227
给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大。
示例 1:
输入: [1,4,3,2]
输出: 4
解释: n 等于 2, 最大总和为 4 = min(1, 2) + min(3, 4).
提示:
n 是正整数,范围在 [1, 10000].
数组中的元素范围在 [-10000, 10000].
解法
就是返回排序后第1,3,5,。。2n-1小的数
class Solution:
def arrayPairSum(self, nums: List[int]) -> int:
return sum(sorted(nums)[::2])
在MATLAB中,有一个非常有用的函数 reshape,它可以将一个矩阵重塑为另一个大小不同的新矩阵,但保留其原始数据。
给出一个由二维数组表示的矩阵,以及两个正整数r和c,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的行遍历顺序填充。
如果具有给定参数的reshape操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。
示例 1:
输入:
nums =
[[1,2],
[3,4]]
r = 1, c = 4
输出:
[[1,2,3,4]]
解释:
行遍历nums的结果是 [1,2,3,4]。新的矩阵是 1 * 4 矩阵, 用之前的元素值一行一行填充新矩阵。
示例 2:
输入:
nums =
[[1,2],
[3,4]]
r = 2, c = 4
输出:
[[1,2],
[3,4]]
解释:
没有办法将 2 * 2 矩阵转化为 2 * 4 矩阵。 所以输出原矩阵。
注意:
给定矩阵的宽和高范围在 [1, 100]。
给定的 r 和 c 都是正数。
解法
将数组转换为1行,然后根据要转换的行列数进行转换
class Solution:
def matrixReshape(self, nums: List[List[int]], r: int, c: int) -> List[List[int]]:
if len(nums) * len(nums[0]) != r * c:
return nums
else:
onerow = [nums[i][j] for i in range(len(nums)) for j in range(len(nums[0]))]
return [onerow[t * c : (t+1) * c] for t in range(r)]
给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。
你找到的子数组应是最短的,请输出它的长度。
示例 1:
输入: [2, 6, 4, 8, 10, 9, 15]
输出: 5
解释: 你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。
说明 :
输入的数组长度范围在 [1, 10,000]。
输入的数组可能包含重复元素 ,所以升序的意思是<=。
解法
all_same[::-1]返回的不是从正向数的索引,返回的是以最后一个元素为0索引,倒数第二个元素为1索引的反向数列的索引值,如例子中所示,从前数有一个不需排序,从后数,有一个不需排序。
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
all_same = [a == b for (a, b) in zip(nums, sorted(nums))]
return 0 if all(all_same) else len(nums) - all_same.index(False) - all_same[::-1].index(False)