概述
文章目录
- 题目
- 解题思路与代码详情
- 【题1】977. 有序数组的平方
- 【题2】268. 丢失的数字
- 【题3】1877. 数组中最大数对和的最小值
- 【题4】950. 按递增顺序显示卡牌
- 【题5】1464. 数组中两元素的最大乘积
- 【题6】1636. 按照频率将数组升序排序
- 【题7】1287. 有序数组中出现次数超过25%的元素
- 【题8】436. 寻找右区间
- 参考文献
题目
- 977. 有序数组的平方
- 268. 丢失的数字
- 1877. 数组中最大数对和的最小值
- 950. 按递增顺序显示卡牌
- 1464. 数组中两元素的最大乘积
- 1636. 按照频率将数组升序排序
- 1287. 有序数组中出现次数超过25%的元素
- 436. 寻找右区间
解题思路与代码详情
【题1】977. 有序数组的平方
977. 有序数组的平方: 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
题目解析: 求由给定数组中元素的平方形成的新数组,并按升序顺序排列。
解题思路: 遍历数组元素求平方,进行排序。
# python3
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
n=len(nums)
ret=[0]*n
for i in range(n):
ret[i]=(nums[i])*(nums[i])
ret.sort()
return ret
//C
int cmp(const void *p1, const void *p2) {
return *(int*)p1-*(int*)p2;
}
int* sortedSquares(int* nums, int numsSize, int* returnSize){
*returnSize = numsSize;
int* ret = (int*)malloc(sizeof(int)*numsSize);
for(int i=0;i<numsSize;i++){
ret[i]=nums[i]*nums[i];
}
qsort(ret, numsSize, sizeof(int), cmp);
return ret;
free(ret);
}
【题2】268. 丢失的数字
268. 丢失的数字: 给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。
题目解析: 数组中的元素由该数组长度内的自然整数构成,同时数组中包含整数0,所以题中数组是由0到数组长度(假设为n)这
n
+
1
n+1
n+1个整数中的
n
n
n个整数组成,需要找出这
n
+
1
n+1
n+1个整数中没在数组中的那一个元素。
解题思路: 方法1:遍历数组中元素,如果元素不是数组中元素,则返回;若遍历完未找到缺失元素,则缺失元素为数组长度。方法2:先排序再查找。
#python3
#暴力查找
class Solution:
def missingNumber(self, nums: List[int]) -> int:
n=len(nums)
ret=0
for i in range(n+1):
if i not in nums:
ret=i
return ret
#先排序再查找
class Solution:
def missingNumber(self, nums: List[int]) -> int:
n=len(nums)
nums.sort()
for i in range(n):
if i!=nums[i]:
return i
return n
//C
int cmp(const void* p1, const void* p2){
return *(int*)p1-*(int*)p2;
}
int missingNumber(int* nums, int numsSize){
qsort(nums, numsSize, sizeof(int), cmp);
for(int i=0;i<numsSize;i++){
if(i!=nums[i]){
return i;
}
}
return numsSize;
}
【题3】1877. 数组中最大数对和的最小值
1877. 数组中最大数对和的最小值: 一个数对 (a,b) 的 数对和 等于 a + b 。最大数对和 是一个数对数组中最大的 数对和。
比方说,如果我们有数对 (1,5) ,(2,3) 和 (4,4),最大数对和为 max(1+5, 2+3, 4+4) = max(6, 5, 8) = 8 。
给你一个长度为 偶数 n 的数组 nums ,请你将 nums 中的元素分成 n / 2 个数对,使得:
nums 中每个元素 恰好 在 一个 数对中,且
最大数对和 的值 最小 。
请你在最优数对划分的方案下,返回最小的 最大数对和 。
题目解析: 数组中元素两两组成数对,求最小的最大数对和。
解题思路: 对数组元素进行升序排序,最小元素与最大元素构成数对,次小元素与次优元素构成数对,以此类推,从而产生最小的数对和,从所构成的数对和中选择最大值。
#python3
class Solution:
def minPairSum(self, nums: List[int]) -> int:
n=len(nums)
nums.sort()
#ret=[0]*(n//2)
maxret=-1
for i in range(n//2):
#ret.append(nums[i]+nums[n-1-i])
#ret[i]=nums[i]+nums[n-1-i]
maxret=max(maxret,nums[i]+nums[n-1-i])
return maxret
#return max(ret)
//C
int cmp(const void* p1, const void* p2){
return *(int*)p1-*(int*)p2;
}
int minPairSum(int* nums, int numsSize){
int max = 0;
qsort(nums, numsSize, sizeof(int), cmp);
for(int i=0;i<numsSize/2;i++){
max=fmax(max,nums[i]+nums[numsSize-1-i]);
}
return max;
}
【题4】950. 按递增顺序显示卡牌
950. 按递增顺序显示卡牌: 牌组中的每张卡牌都对应有一个唯一的整数。你可以按你想要的顺序对这套卡片进行排序。
最初,这些卡牌在牌组里是正面朝下的(即,未显示状态)。
现在,重复执行以下步骤,直到显示所有卡牌为止:
1.从牌组顶部抽一张牌,显示它,然后将其从牌组中移出。
2.如果牌组中仍有牌,则将下一张处于牌组顶部的牌放在牌组的底部。
3.如果仍有未显示的牌,那么返回步骤 1。否则,停止行动。
返回能以递增顺序显示卡牌的牌组顺序。
答案中的第一张牌被认为处于牌堆顶部。
题目解析: 求能使卡牌按升序顺序显示出来的卡牌放置顺序。
解题思路: 模拟抓牌过程。 以样例 [17,13,11,2,3,5,7]
为例,首先将数组元素升序排列得到[2,3,5,7,11,13,17]
,然后将排序后的数组元素依次按下列操作重新放置。
#python3
class Solution(object):
def deckRevealedIncreasing(self, deck):
'''
创建双向队列
import collections
d = collections.deque()
'''
n = len(deck)
deck.sort()
index = collections.deque(range(n))#生成序号
ret = [0] * n
for card in deck:
ret[index.popleft()] = card
#popleft(获取最左边一个元素,并在队列中删除)间隔排放元素
if index:
index.append(index.popleft())
return ret
//C
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int cmp(const void* p1, const void* p2){
return *(int*)p1-*(int*)p2;
}
int* deckRevealedIncreasing(int* deck, int deckSize, int* returnSize){
*returnSize = deckSize;
int* ret = (int*)malloc(sizeof(int)*deckSize);
int* index = (int*)malloc(sizeof(int)*deckSize);
qsort(deck, deckSize, sizeof(int), cmp);
for(int i=0;i<deckSize;i++){
index[i]=i;
}
for(int i=1;i<deckSize;i++){
index[i-1]=index[i-1];
int temp = index[i];
for(int j=i;j<deckSize-1;j++){
index[j]=index[j+1];
}
index[deckSize-1]=temp;
}
for(int i=0;i<deckSize;i++){
ret[index[i]]=deck[i];
}
return ret;
free(ret);
free(index);
}
【题5】1464. 数组中两元素的最大乘积
1464. 数组中两元素的最大乘积: 给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值。
请你计算并返回该式的最大值。
题目解析: 求数组中两个较大元素减一后的乘积。
解题思路: 排序求积。
class Solution:
def maxProduct(self, nums: List[int]) -> int:
#n=len(nums)
nums.sort(reverse=1)
return (nums[0]-1)*(nums[1]-1)
int cmp(const void* p1, const void* p2){
return *(int*)p2-*(int*)p1;
}
int maxProduct(int* nums, int numsSize){
qsort(nums, numsSize, sizeof(int),cmp);
return (nums[0]-1)*(nums[1]-1);
}
【题6】1636. 按照频率将数组升序排序
1636. 按照频率将数组升序排序: 给你一个整数数组 nums ,请你将数组按照每个值的频率 升序 排序。如果有多个值的频率相同,请你按照数值本身将它们 降序 排序。
请你返回排序后的数组。
**题目解析:**以输出频率从多到少输出数组元素。
**解题思路:**对数组元素同时按频率升序,数值降序顺序输出。
class Solution:
def frequencySort(self, nums: List[int]) -> List[int]:
return sorted(nums, key=lambda x: (nums.count(x), -x))
【题7】1287. 有序数组中出现次数超过25%的元素
1287. 有序数组中出现次数超过25%的元素: 给你一个非递减的 有序 整数数组,已知这个数组中恰好有一个整数,它的出现次数超过数组元素总数的 25%。
请你找到并返回这个整数。
题目解析: 找出出现次数超过总数25%的那个唯一元素。
解题思路: 排序,累积次数。
class Solution:
def findSpecialInteger(self, arr: List[int]) -> int:
n=len(arr)
#listarr=collections.Counter(arr)
ret=sorted(arr,key=lambda x:(arr.count(x)))
#ret=sorted(arr, key=lambda x: (arr.count(x), -x))
return ret[n-1]
#for value in listarr:
#if listarr[value]*100//n>25:
# return value
【题8】436. 寻找右区间
436. 寻找右区间: 给你一个区间数组 intervals ,其中 intervals[i] = [starti, endi] ,且每个 starti 都 不同 。
区间 i 的 右侧区间 可以记作区间 j ,并满足 startj >= endi ,且 startj 最小化 。
返回一个由每个区间 i 的 右侧区间 在 intervals 中对应下标组成的数组。如果某个区间 i 不存在对应的 右侧区间 ,则下标 i 处的值设为 -1
题目解析: 每个区间的y坐标同其他区间的x坐标相比较,其他区间中存在x坐标值大于该区间的y坐标值,找出符合要求的最小的其他区间的x坐标值,若存在这样的x坐标值,返回该x坐标值的小区间的索引值,若找不到,返回-1.
解题思路: 排序+二分。按所有区间内的x坐标值的大小排序取索引值,如果小区间的y坐标值大于x坐标的最大值或小于x坐标最小值,那么返回-1,二分查找最接近当前区间的y坐标值的x坐标的索引值。
#法1超时
class Solution:
def findRightInterval(self, intervals: List[List[int]]) -> List[int]:
n=len(intervals)
ret=[0]*n
if n==1:
ret[0]=-1
return ret
else:
for i in range(n):#遍历每个区间
mins=10000
for j in range(n):
if j==i:
continue
if intervals[j][0]>=intervals[i][1]:
mins = min(mins, intervals[j][0])
if mins == intervals[j][0]:
ret[i]=j
#print(temp)
if mins==10000:
ret[i]=-1
return ret
#排序+二分
class Solution:
def findRightInterval(self, intervals: List[List[int]]) -> List[int]:
n = len(intervals)
s = sorted(range(n), key=lambda x: intervals[x][0])
ans = []
minx, maxx = intervals[s[0]][0], intervals[s[n-1]][0]
for x, y in intervals:
if y < minx or y > maxx:
ans.append(-1)
else:
left, right = 0, n - 1
while left < right:
mid = (left + right) // 2
if y > intervals[s[mid]][0]:
left = mid + 1
else:
right = mid
ans.append(s[left])
return ans
参考文献
- https://blog.csdn.net/WhereIsHeroFrom/article/details/124550030
- https://blog.csdn.net/WhereIsHeroFrom/article/details/125109551
最后
以上就是奋斗小刺猬为你收集整理的力扣----排序题目解题思路与代码详情参考文献的全部内容,希望文章能够帮你解决力扣----排序题目解题思路与代码详情参考文献所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复