目录
-
074. 合并区间
-
075. 数组相对排序
-
076. 数组中的第 k 大的数字
-
077. 链表排序
-
078. 合并排序链表(困难)
=========================================================================
题目:
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
示例:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
提示:
-
1 <= intervals.length <= 104
-
intervals[i].length == 2
-
0 <= starti <= endi <= 104
思路:
快排 + 遍历
现按区间的开始时间进行排序
然后创建一个二维数组,先将第一个区间加入,而后遍历区间
- 如果本区间结尾小于下一个区间开始,直接加入下一个区间
- 否则 更新本区间的结束时间,取本区间与下一区间的结束值大值
class Solution {
public:
vector<vector> merge(vector<vector>& intervals) {
if(intervals.size() == 0) return {};
//sort(intervals.begin(), intervals.end());
quickSort(intervals, 0, intervals.size() - 1);
vector<vector> ans;
ans.emplace_back(intervals[0]);
for(int i = 1; i < intervals.size(); i++) {
// 如果前一个数的结尾大于这个数的开头,就可以合并
if(ans.back()[1] >= intervals[i][0]) {
if(ans.back()[1] < intervals[i][1])
ans.back()[1] = intervals[i][1];
// 否则跳过这个数
}else {
// 不能合并
ans.emplace_back(intervals[i]);
}
}
return ans;
}
// 快排
void quickSort(vector<vector>& arr, int l, int r) {
if(l >= r) return ;
int i = l, j = r, mid = arr[(l + r) >> 1][0];
do{
while(arr[i][0] < mid) i++;
while(arr[j][0] > mid) j–;
if(i <= j)
swap(arr[i++], arr[j–]);
}while(i <= j);
quickSort(arr, l, j);
quickSort(arr, i, r);
}
};
===========================================================================
题目:
给定两个数组,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 <= arr1.length, arr2.length <= 1000
-
0 <= arr1[i], arr2[i] <= 1000
-
arr2 中的元素 arr2[i] 各不相同
-
arr2 中的每个元素 arr2[i] 都出现在 arr1 中
思路:
将排序规则
arr2
加入map中,自定义sort排序,将规则改成
- 在map中存在的为小值
- 如果都在
map
中,则比较数组下标看谁小(map
值)
- 否则直接比较两个值
class Solution {
public:
vector relativeSortArray(vector& arr1, vector& arr2) {
unordered_map<int, int> map;
for(int i = 0; i < arr2.size(); i++)
map[arr2[i]] = i;
sort(arr1.begin(), arr1.end(), [&](int x, int y) {
if(map.count(x)) {
return map.count(y)? map[x] < map[y] : true;
}else {
return map.count(y)? false : x < y;
}
});
return arr1;
}
};
=================================================================================
题目:
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
提示:
-
1 <= k <= nums.length <= 104
-
-104 <= nums[i] <= 104
思路:
优先队列(大根堆)
第
K
大 等价于 第n = nums.size() - k + 1
小,所以我们存储最小的n
个元素,堆顶就是第k大元素
当堆达到
n + 1
时 将堆顶移除,这样就可以保持将 大于 第k
大的元素移除掉
class Solution {
public:
int findKthLargest(vector& nums, int k) {
// 第k大就是第nums.size() - k + 1 小;
// 小到大排序
priority_queue<int, vector, less> pq;
int n = nums.size() - k + 1;
for(int i : nums) {
pq.emplace(i);
if(pq.size() > n) pq.pop();
}
return pq.top();
}
};
=========================================================================
题目:
给定链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
示例:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
提示:
-
链表中节点的数目在范围 [0, 5 * 104] 内
-
-105 <= Node.val <= 105
进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
思路:
归并思想:找中点 + 递归成单个链表节点 + 合并链表
找中点时记得将中点的前一个与后面断开
class Solution {
public:
// 找中点 + 递归成单个链表节点 + 合并链表
ListNode* sortList(ListNode* head) {
// 到只剩一个元素返回
if(head == nullptr || head->next == nullptr)
return head;
// 数组分成两段并返回中点
ListNode* head1 = head;
ListNode* head2 = serachMid(head);
head1 = sortList(head1);
head2 = sortList(head2);
// 合并并返回
return merge(head1,head2);
}
// 找中点
ListNode* serachMid(ListNode* head) {
ListNode *slow = head, *fast = head;
while(fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
ListNode* mid = slow->next;
slow->next = nullptr;
return mid;
}
// 合并链表
ListNode* merge(ListNode* head1, ListNode* head2) {
ListNode* dummy = new ListNode(-1);
ListNode* cur = dummy;
while(head1 && head2) {
if(head1->val <= head2->val) {
cur->next = head1;
head1 = head1->next;
}else {
cur->next = head2;
head2 = head2->next;
}
cur = cur->next;
}
if(head1) cur->next = head1;
if(head2) cur->next = head2;
return dummy->next;
}
};
===============================================================================
题目:
结局:总结+分享
看完美团、字节、腾讯这三家的一二三面试问题,是不是感觉问的特别多,可能咱们真的又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。
开篇有提及我可是足足背下了Java互联网工程师面试1000题,多少还是有点用的呢,换汤不换药,不管面试官怎么问你,抓住本质即可!能读到此处的都是真爱
- Java互联网工程师面试1000题
而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的 《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。
- 程序员代码面试指南–IT名企算法与数据结构题目最优解
- 其余像设计模式,建议可以看看下面这4份PDF(已经整理)
- 更多的Java面试学习笔记如下,关于面试这一块,我额外细分出Java基础-中级-高级开发的面试+解析,以及调优笔记等等等。。。
以上所提及的全部Java面试学习的PDF及笔记,如若皆是你所需要的,那么都可发送给你!
不换药,不管面试官怎么问你,抓住本质即可!能读到此处的都是真爱
- Java互联网工程师面试1000题
[外链图片转存中…(img-gnYhZXS8-1721145792616)]
而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的 《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。
- 程序员代码面试指南–IT名企算法与数据结构题目最优解
[外链图片转存中…(img-fle94OWP-1721145792617)]
- 其余像设计模式,建议可以看看下面这4份PDF(已经整理)
[外链图片转存中…(img-lUUDnvw8-1721145792617)]
- 更多的Java面试学习笔记如下,关于面试这一块,我额外细分出Java基础-中级-高级开发的面试+解析,以及调优笔记等等等。。。
[外链图片转存中…(img-bhiGj6XB-1721145792618)]
以上所提及的全部Java面试学习的PDF及笔记,如若皆是你所需要的,那么都可发送给你!