问题描述
小U作为一位雇主,想要招聘一位工人。现有 n 个人前来应聘,每个人都写下了他们期望的薪资。小U打算选择期望薪资最低的人,但为了避免纠纷,他只会选择在没有其他人提出相同期望薪资的情况下期望薪资最低的人。如果没有符合条件的人,他将不录用任何人。
你的任务是帮助小U找到合适的最低薪资。如果没有合适的人,输出 -1。
测试样例
样例1:
输入:
n = 3 ,salaries = [3, 2, 1]
输出:1
样例2:
输入:
n = 6 ,salaries = [1, 1, 4, 5, 1, 4]
输出:5
样例3:
输入:
n = 3 ,salaries = [4, 4, 4]
输出:-1
思路解析
1. 排序
首先,我们可以对 salaries 数组进行排序。排序后,期望薪资最低的值会出现在数组的最前面。这样我们可以从最小的薪资开始检查,直到找到一个没有重复的薪资为止。
2. 遍历检查
排序后,我们从最小的薪资开始遍历,检查是否有重复的薪资。如果有重复的薪资,我们继续向后查找,直到找到一个没有重复的薪资。如果遍历完整个数组都没有找到符合条件的薪资,则返回 -1。
3. 特殊情况处理
- 如果
n == 1,即只有一个应聘者,那么直接返回该应聘者的薪资。 - 如果数组中所有薪资都相同,则返回
-1。
图解
假设输入为 n = 6, salaries = [1, 1, 4, 5, 1, 4]:
-
排序:
salaries = [1, 1, 1, 4, 4, 5] -
遍历检查:
- 第一个薪资是 1,有重复,跳过。
- 第二个薪资是 1,有重复,跳过。
- 第三个薪资是 1,有重复,跳过。
- 第四个薪资是 4,有重复,跳过。
- 第五个薪资是 4,有重复,跳过。
- 第六个薪资是 5,没有重复,返回 5。
代码详解
go
复制
package main
import (
"fmt"
"sort"
)
func solution(n int, salaries []int) int {
if n == 1 {
return salaries[0]
}
// 对薪资进行排序
sort.Slice(salaries, func(i, j int) bool {
return salaries[i] < salaries[j]
})
// 初始化当前薪资为最小的薪资
t := salaries[0]
// 遍历薪资数组
for i := 1; i < n; {
// 如果当前薪资与前一个薪资不同,说明找到了一个没有重复的最低薪资
if salaries[i] != t {
return t
} else {
// 跳过所有相同的薪资
for i < n && salaries[i] == t {
i++
}
// 如果还有剩余的薪资,更新当前薪资为下一个不同的薪资
if i < n {
t = salaries[i]
i++
}
}
}
// 如果最后一个薪资与倒数第二个薪资不同,返回最后一个薪资
if salaries[n-1] != salaries[n-2] {
return salaries[n-1]
}
// 如果没有符合条件的薪资,返回 -1
return -1
}
func main() {
fmt.Println(solution(3, []int{3, 2, 1}) == 1)
fmt.Println(solution(6, []int{1, 1, 4, 5, 1, 4}) == 5)
fmt.Println(solution(3, []int{4, 4, 4}) == -1)
}
代码解析
-
排序:
- 使用
sort.Slice对salaries数组进行排序,排序后数组中的薪资从小到大排列。
- 使用
-
遍历检查:
- 初始化
t为排序后的第一个薪资。 - 从第二个薪资开始遍历,如果当前薪资与
t不同,说明找到了一个没有重复的最低薪资,直接返回t。 - 如果当前薪资与
t相同,则跳过所有相同的薪资,直到找到下一个不同的薪资。
- 初始化
-
特殊情况处理:
- 如果
n == 1,直接返回唯一的薪资。 - 如果遍历完整个数组都没有找到符合条件的薪资,检查最后一个薪资是否与倒数第二个薪资不同,如果是,则返回最后一个薪资,否则返回
-1。
- 如果
总结
通过排序和遍历检查,我们可以高效地找到符合条件的最低薪资。排序的时间复杂度为 O(n log n),遍历的时间复杂度为 O(n),因此整体的时间复杂度为 O(n log n)。这种方法在处理大规模数据时也能保持较高的效率。