两个数组找相同元素_leetcode数组–sort排序题目汇总

  • Post author:
  • Post category:其他


884566efa164caba1cf48816ccf96e9d.png

概要:此类题目的特点是会遇到一些杂乱无序的数组,经过排序后,会更好处理。


1051. 高度检查器

学校在拍年度纪念照时,一般要求学生按照 非递减 的高度顺序排列。

请你返回能让所有学生以 非递减 高度排列的最小必要移动人数。

注意,当一组学生被选中时,他们之间可以以任何可能的方式重新排序,而未被选中的学生应该保持不动。

输入:heights = [1,1,4,2,1,3]

输出:3

解释:

当前数组:[1,1,4,2,1,3]

目标数组:[1,1,1,2,3,4]

在下标 2 处(从 0 开始计数)出现 4 vs 1 ,所以我们必须移动这名学生。

在下标 4 处(从 0 开始计数)出现 1 vs 3 ,所以我们必须移动这名学生。

在下标 5 处(从 0 开始计数)出现 3 vs 4 ,所以我们必须移动这名学生。


#思路

:先建立一个正确的顺序,然后逐个对比检查原数组

class Solution:
    def heightChecker(self, heights: List[int]) -> int:
        z=0
        for k,v in enumerate(sorted(heights)):
            if v!=heights[k]:
                z+=1
        return z


977. 有序数组的平方

给定一个按非递减顺序排序的整数数组

A

,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。


输入:

[-4,-1,0,3,10]

输出:

[0,1,9,16,100]

思路:创建一个新的数组存放平方后的元素,然后排序

class Solution:
    def sortedSquares(self, A: List[int]) -> List[int]:
        ans=[]
        for i in A:
            ans.append(i**2)   
        return sorted(ans)


561. 数组拆分 I

给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大。


输入:

[1,4,3,2]

输出:

4

解释:

n 等于 2, 最大总和为 4 = min(1, 2) + min(3, 4).


思路:

(1)对于每一组里的两个元素,小的元素会被舍弃(不加入最终的求和运算)

(2)要使Sum((a0,b0),(a1,b1)……)最大,则被舍弃的元素应该尽可能小

(3)第一组(全数组最小值,全数组次小值),第二组(全数组第三小,第四小)…


(4)升序排序,然后求和即可

class Solution:
    def arrayPairSum(self, nums: List[int]) -> int:
        nums.sort()
        ans=sum(nums[::2])
        return ans


1122. 数组的相对排序

—上海国音智能面试题类似

给你两个数组,arr1 和 arr2:arr2 中的元素各不相同;arr2 中的每个元素都出现在 arr1 中

对 arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。

输入:arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6]
输出:[2,2,2,1,4,3,3,9,6,7,19]

思路:

  1. 依次循环遍历arr2中的元素
  2. 依次从arr1中删除arr2中的元素

  3. 最后的元素用sorted排序,在组合新数组
class Solution(object):
    def relativeSortArray(self, arr1, arr2):
        res = []
        for i in arr2:
            while i in arr1:    #这里的while仔细品
                res.append(i)
                arr1.remove(i)   #list.remove(object) 用于移除列表中某个值的第一个匹配项
        return res + sorted(arr1)


1200. 最小绝对差 —

光之树科技面试题类似

给你个整数数组

arr

,其中每个元素都

不相同

。请你找到所有具有最小绝对差的元素对,并且按升序的顺序返回。

输入:arr = [4,2,1,3]
输出:[[1,2],[2,3],[3,4]]

思路:如果A,B,C是一个排序后的数组,则排序后,C-A一定是大于B-A和C-B的

class Solution:
    def minimumAbsDifference(self, arr: List[int]) -> List[List[int]]:
        if not arr:
            return []
        #列表排序
        arr.sort()
        res=[]
        #tmp:当前最小差值
        tmp=arr[1]-arr[0]
        for i in range(1,len(arr)):
            #出现更小差值后,更新结果
            if arr[i]-arr[i-1]<tmp:
                tmp=arr[i]-arr[i-1]
                res=[[arr[i-1],arr[i]]]   #括号易出错,子数组也要升序排
            #加入相同差值的数组
            elif arr[i]-arr[i-1]==tmp:
                res.append([arr[i-1],arr[i]])
            else:
                continue
        return res


leetcode1086: 前五科的均分

给你一个不同学生的分数列表,请按照学生的id顺序返回每个学生最高的五科成绩的平均分。对于每条item[i],item[i][0]为学生id, item[i][1]为学生的分数,平均分请采用整数除法计算。

input: [[1,91],[1,92],[2,93]...........]
output: [[1,87],[2,88]]

思路:

  • 信息重点,每个学生可能不止五科,但算平均分时要计算最高的五科。
  • 先用集合set找出来有多少个学生,将其id保存为id_list
  • 然后按照学生的id去遍历item,找出每个学生的所有成绩。

  • 排序每个学生的成绩,然后取最高的五门计算平均分

  • 将结果保存进一个新的列表里
def highFive(self,items):
	id_list=list(set([i for i,j in items]))
	res=[]
	for id_1 in id_list:
		score_arr=[]
		for ids,scores in items:
			if ids==id_1:
				score_arr.append(scores)
		sums=sum(sorted(score_arr[:5]))
		res.append[id_1,int(sums/5)]
	return res



581. 最短无序连续子数组

给定一个整数数组,你需要寻找一个

连续的子数组

,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。

你找到的子数组应是

最短

的,请输出它的长度。

输入: [2, 6, 4, 8, 10, 9, 15]
输出: 5
解释: 你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。

思路:


  • 先对数组nums进行排序
  • 利用两个指针,从首尾遍历,寻找排序前和排序后不一样的元素,其索引即为要找的

    最短

    子数组
class Solution:
    def findUnsortedSubarray(self, nums: List[int]) -> int:
        sorted_nums=sorted(nums)
        p1,p2=0,len(nums)-1
        while p1<=p2 and nums[p1]==sorted_nums[p1]:
            p1+=1
        while p1<=p2 and nums[p2]==sorted_nums[p2]:
            p2-=1
        return p2-p1+1



268. 缺失数字

给定一个包含

0, 1, 2, ..., n



n

个数的序列,找出 0 ..

n

中没有出现在序列中的那个数。

输入: [3,0,1]
输出: 2

思路:

  • 先考虑特殊情况:首位不是0,那么缺少0,末尾不是n,那么缺少n
  • else: 整个数组应该遵循 nums[i-1]+1=nums[i],如果nums[i-1]+1!=nums[i],那么缺少的就是nums[i-1]+1
class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        nums.sort()
        if nums[-1]!=len(nums):
            return len(nums)
        elif nums[0]!=0: 
            return 0
        for i in range(1,len(nums)):   #从1开始检查,把0作为nums[i-1]+1的起点
            expected_num=nums[i-1]+1
            if nums[i]!=expected_num:
                return expected_num



455. 分发饼干

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

输入: [1,2,3], [1,1]

输出: 1

解释: 
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。

输入: [1,2], [1,2,3]

输出: 2

解释: 
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.

思路:

  • 贪心算法,优先满足胃口小的

  • 先对胃口g,饼干尺寸s进行升序排序
  • 让两个指针分别指向g和s的初始位置
  • if 胃口g[i]<=饼干s[j],则这块饼干j可以分给孩子i,指针i,j各移动一下,结果计数+1
  • else: 无法满足胃口,将j+1,看一块更大的饼干是否满足孩子i的胃口。
class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        res,g_len,s_len=0,len(g),len(s)
        s.sort()
        g.sort()
        i,j=0,0
        while i<g_len and j<s_len :
            if g[i]<=s[j]:
                res+=1
                i+=1
                j+=1
            else:
                j+=1
        return res



628. 三个数的最大乘积

给定一个整型数组,在数组中找出由三个数组成的最大乘积,并输出这个乘积。

输入: [1,2,3]
输出: 6

输入: [1,2,3,4]
输出: 24
注意:

给定的整型数组长度范围是[3,104],数组中所有的元素范围是[-1000, 1000]。
输入的数组中任意三个数的乘积不会超出32位有符号整数的范围。

思路: 最大三个数的两种情形

  • 两个负数一个正数
  • 三个正数
  • 先对数组排序,要么排序后末尾三个为正数,要么前面两负一正,只有这两种可能
class Solution:
    def maximumProduct(self,nums):
        nums.sort()
        v1=nums[-1]*nums[-2]*nums[-3]
        v2=nums[0]*nums[1]*nums[-1]
        return max(v1,v2)



976. 三角形的最大周长

给定由一些正数(代表长度)组成的数组

A

,返回由其中三个长度组成的、

面积不为零

的三角形的最大周长。

如果不能形成任何面积不为零的三角形,返回

0

输入:[2,1,2]
输出:5

输入:[1,2,1]
输出:0

输入:[3,2,3,4]
输出:10

思路:三角形充分必要条件:a+b>c,假设已经知道c的长度了,只需要尽可能选大的a和b

class Solution:
    def largestPerimeter(self, A: List[int]) -> int:
        A.sort()
        for i in range(len(A)-3,-1,-1):
            if A[i]+A[i+1]>A[i+2]:
                return A[i]+A[i+1]+A[i+2]
        return 0