目录
315. Count of Smaller Numbers After Self
215. Kth Largest Element in an Array
973. K Closest Points to Origin
378. Kth Smallest Element in a Sorted Matrix
373. Find K Pairs with Smallest Sums
719. Find K-th Smallest Pair Distance
493. Reverse Pairs
Hard
702107Add to ListShare
Given an array nums
, we call (i, j)
an important reverse pair if i < j
and nums[i] > 2*nums[j]
.
You need to return the number of important reverse pairs in the given array.
Example1:
Input: [1,3,2,3,1] Output: 2
Example2:
Input: [2,4,3,5,1] Output: 3
Note:
- The length of the given array will not exceed
50,000
. - All the numbers in the input array are in the range of 32-bit integer.
class Solution {
public:
int lowerbit(int x){
return x&(-x);
}
void add(int x,vector<int> &c){
while(x<c.size()){
c[x]+=1;
x+=lowerbit(x);
}
return;
}
int getSum(int x,vector<int> c){
int res=0;
while(x>0){
res+=c[x];
x-=lowerbit(x);
}
return res;
}
int reversePairs(vector<int>& nums) {
vector<int> value=nums;
sort(value.begin(),value.end());
vector<int> c(nums.size()+1);
unordered_map<int,int> mp;
for(int i=0;i<value.size();i++){
mp[value[i]]=i+1;
}
int res=0;
for(int i=nums.size()-1;i>=0;i--){
res+=getSum(lower_bound(value.begin(),value.end(),nums[i]/2.0)-value.begin(),c);
add(mp[nums[i]],c);
}
return res;
}
};
class Solution {
public:
int mergeSort(vector<int> &nums,int left,int right){
if(left>=right) return 0;
int mid=left+(right-left)/2;
int res=mergeSort(nums,left,mid)+mergeSort(nums,mid+1,right);
for(int i=left,j=mid+1;i<=mid;i++){
while(j<=right && nums[i]/2.0 > nums[j]) j++;
res+=j-(mid+1);
}
sort(nums.begin()+left,nums.begin()+right+1);
return res;
}
int reversePairs(vector<int>& nums) {
return mergeSort(nums,0,nums.size()-1);
}
};
- 归并思想
315. Count of Smaller Numbers After Self
Hard
176269Add to ListShare
You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i]
is the number of smaller elements to the right of nums[i]
.
Example:
Input: [5,2,6,1]
Output: [2,1,1,0]
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.
class Solution {
public:
void add(int x,vector<int>& c){
while(x<c.size()){
c[x]+=1;
x+=x&(-x);
}
return;
}
int getSum(int x,vector<int> c){
int res=0;
while(x>0){
res+=c[x];
x-=x&(-x);
}
return res;
}
vector<int> countSmaller(vector<int>& nums) {
vector<int> value=nums;
sort(value.begin(),value.end());
unordered_map<int,int> mp;
for(int i=0;i<value.size();i++){
mp[value[i]]=i+1;
}
vector<int> c(nums.size()+1);
vector<int> res(nums.size());
for(int i=nums.size()-1;i>=0;i--){
res[i]=getSum(lower_bound(value.begin(),value.end(),nums[i])-value.begin(),c);
add(mp[nums[i]],c);
}
return res;
}
};
- Runtime: 640 ms, faster than 9.17% of C++ online submissions for Count of Smaller Numbers After Self.
- Memory Usage: 326.6 MB, less than 8.33% of C++ online submissions for Count of Smaller Numbers After Self.
class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
vector<int> res(nums.size());
deque<int> de;
for (int i = nums.size() - 1; i >= 0;i--){
deque<int>::iterator it = lower_bound(de.begin(), de.end(), nums[i]);
res[i] = it - de.begin();
de.insert(it, nums[i]);
}
return res;
}
};
- Runtime: 132 ms, faster than 33.28% of C++ online submissions for Count of Smaller Numbers After Self.
- Memory Usage: 10.3 MB, less than 83.33% of C++ online submissions for Count of Smaller Numbers After Self.
327. Count of Range Sum
Hard
58175Add to ListShare
Given an integer array nums
, return the number of range sums that lie in [lower, upper]
inclusive.
Range sum S(i, j)
is defined as the sum of the elements in nums
between indices i
and j
(i
≤ j
), inclusive.
Note:
A naive algorithm of O(n2) is trivial. You MUST do better than that.
Example:
Input: nums = [-2,5,-1], lower = -2, upper = 2, Output: 3 Explanation: The three ranges are : [0,0], [2,2], [0,2]and their respective sums are: -2, -1, 2
class Solution {
public:
int countRangeSum(vector<int>& nums, int lower, int upper) {
multiset<long long> sums;
sums.insert(0);
long long sum=0;
int res=0;
for(int i=0;i<nums.size();i++){
sum+=nums[i];
res+=distance(sums.lower_bound(sum-upper),sums.upper_bound(sum-lower));
sums.insert(sum);
}
return res;
}
};
148. Sort List
Medium
2142107Add to ListShare
Sort a linked list in O(n log n) time using constant space complexity.
Example 1:
Input: 4->2->1->3 Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0 Output: -1->0->3->4->5
- 单链表排序
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<deque>
#include<set>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
} ListNode;
ListNode *createList(){
int n;
cin >> n;
ListNode *HEAD =(ListNode *)malloc(sizeof(ListNode));
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
for (int i = 0; i < n;i++){
ListNode *tmp = (ListNode *)malloc(sizeof(ListNode));
int value;
cin >> value;
tmp->value = value;
tmp->next = NULL;
if(i==0) head=tmp;
else HEAD->next=tmp;
HEAD = tmp;
}
return head;
}
ListNode *merge(ListNode *head1,ListNode *head2){
if(head1==NULL) return head2;
if(head2==NULL) return head1;
ListNode *head = NULL;
if(head1->value<=head2->value){
head=head1;
head1 = head1->next;
}else{
head = head2;
head2 = head2->next;
}
ListNode *HEAD = head;
while (head1 && head2){
if (head1->value <= head2->value){
head->next = head1;
head1 = head1->next;
head = head->next;
}
else{
head->next = head2;
head2 = head2->next;
head = head->next;
}
}
if(head1) head->next=head1;
if(head2) head->next=head2;
return HEAD;
}
ListNode *mergeSort(ListNode *head){
if(head==NULL || head->next==NULL) return head;
ListNode *fast = head->next, *slow = head;
while(fast && fast->next){
fast = fast->next->next;
slow = slow->next;
}
ListNode *headb = slow->next;
slow->next = NULL;
return merge(mergeSort(head), mergeSort(headb));
}
void print(ListNode *head){
while(head){
cout << head->value << " ";
head=head->next;
}
return;
}
int main(){
ListNode *tmp=createList();
tmp=mergeSort(tmp);
print(tmp);
system("pause");
return 0;
}
- Runtime: 52 ms, faster than 81.94% of C++ online submissions for Sort List.
- Memory Usage: 15 MB, less than 15.00% of C++ online submissions for Sort List.
- Next challenges:
- Sort Colors
- Insertion Sort List
75. Sort Colors
Medium
2494192Add to ListShare
Given an array with n objects colored red, white or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white and blue.
Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.
Note: You are not suppose to use the library's sort function for this problem.
Example:
Input: [2,0,2,1,1,0] Output: [0,0,1,1,2,2]
Follow up:
- A rather straight forward solution is a two-pass algorithm using counting sort.
First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. - Could you come up with a one-pass algorithm using only constant space?
- 计数排序 // 快速排序的思想(cur指向当前遍历,low指向0,high指向2)
class Solution {
public:
void sortColors(vector<int>& nums) {
int low=0,high=nums.size()-1,cur=0;
while(cur<=high){
if(nums[cur]==0) swap(nums[cur++],nums[low++]);
else if(nums[cur]==1) cur++;
else if(nums[cur]==2) swap(nums[cur],nums[high--]);
}
return ;
}
};
324. Wiggle Sort II
Medium
859467Add to ListShare
Given an unsorted array nums
, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]...
.
Example 1:
Input: nums = [1, 5, 1, 1, 6, 4] Output: One possible answer is [1, 4, 1, 5, 1, 6]
Example 2:
Input: nums = [1, 3, 2, 2, 3, 1] Output: One possible answer is [2, 3, 1, 3, 1, 2]
Note:
You may assume all input has valid answer.
Follow Up:
Can you do it in O(n) time and/or in-place with O(1) extra space?
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
/*Given an unsorted array nums, reorder it in-place
such that nums[0] <= nums[1] >= nums[2] <= nums[3]....
For example, given nums = [3, 5, 2, 1, 6, 4],
one possible answer is [1, 6, 2, 5, 3, 4].
1.先来看一种时间复杂度为O(nlgn)的方法,思路是先给数组排个序,
然后我们只要每次把第三个数和第二个数调换个位置,
第五个数和第四个数调换个位置,以此类推直至数组末尾,
这样就能完成摆动排序了。
2.这道题还有一种O(n)的解法,根据题目要求的
nums[0] <= nums[1] >= nums[2] <= nums[3]....,
可以总结出如下规律:
当i为奇数时,nums[i] >= nums[i - 1]
当i为偶数时,nums[i] <= nums[i - 1]
那么只要对每个数字(从后往前遍历),根据其奇偶性,跟其对应的条件比较,
如果不符合就和前面的数交换位置即可。*/
void wraggle1(vector<int> &nums){
for (int i = nums.size() - 1; i >= 0;i--){
if(i!=0 && i%2==0){
if(nums[i]>nums[i-1]) swap(nums[i],nums[i-1]);
}else if(i%2==1){
if(nums[i-1]>nums[i]) swap(nums[i],nums[i-1]);
}
}
}
/*Given an unsorted array nums, reorder it
such that nums[0] < nums[1] > nums[2] < nums[3]....
这道题给了我们一个无序数组,让我们排序成摆动数组,
满足nums[0] < nums[1] > nums[2] < nums[3]...,并给了我们例子。
我们可以先给数组排序,然后在做调整。调整的方法是找到数组的中间的数,
相当于把有序数组从中间分成两部分,
然后从前半段的末尾取一个,在从后半的末尾取一个,这样保证了第一个数小于第二个数,
然后从前半段取倒数第二个,从后半段取倒数第二个,这保证了第二个数大于第三个数,
且第三个数小于第四个数,以此类推直至都取完,参见代码如下:*/
void wraggle21(vector<int> &nums){
sort(nums.begin(), nums.end());
int left = 0, right = nums.size() - 1;
int mid = left + (right - left) / 2;
left = mid;
vector<int> res;
while(left>=0 && right>mid){
res.push_back(nums[left--]);
res.push_back(nums[right--]);
}
while(left>=0) res.push_back(nums[left--]);
while(right>mid) res.push_back(nums[right--]);
nums = res;
}
/*若使用O(1)的空间复杂度:
小的数字放在偶数位,大的数字放在奇数位
如何判断数字是大的还是小的:中位数比较
nth_element:找到容器中第n大的数,并放在第n位置上,
n位置前、后有序,总的无序.
拿出一个数和中位数进行比较,然后向指定位置上搬运,
这种操作好像在二分法中用的很多,但是,不同的是,
二分法中,是将数往左边和右边放,而此时我们是打算将数往奇偶位上移动,
所以,要区分索引的奇偶性。而这一步我们可以借用二分法中的大小指针法去做,
举个例子,我们可以把二分法中的小指针映射成奇数位,
把二分法张的大指针映射成偶数位,
要让一个数变成奇数,最好的办法就是: num*2+1。
而让一个奇数变成偶数的方法就是:对一个奇数取余。num%奇数。*/
void wraggle22(vector<int> &nums){
if(nums.size()<2) return ;
nth_element(nums.begin(), nums.begin() + nums.size() / 2, nums.end());
int mid = nums[nums.size() / 2];
#define A(i) nums[(2*i+1)%(nums.size()|1)]
int j = 0, i = 0, k = nums.size() - 1;
while(j<=k){
if(A(j)>mid) swap(A(i++),A(j++));
else if(A(j)<mid) swap(A(j),A(k--));
else j++;
}
return;
}
int main(){
vector<int> nums = {5,3,1,2,6,7,8,5,5};
wraggle22(nums);
for (int i = 0; i < nums.size();i++) cout<<nums[i]<<" ";
system("pause");
return 0;
}
215. Kth Largest Element in an Array
Medium
2969209Add to ListShare
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
Example 1:
Input: [3,2,1,5,6,4] and k = 2 Output: 5
Example 2:
Input: [3,2,3,1,2,4,5,5,6] and k = 4 Output: 4
Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.
class Solution {
public:
int findKthLargest(vector<int>& nums,int k){
int left=0,right=nums.size()-1;
while(true){
int pos=partition(nums,left,right);
if(pos==k-1) return nums[pos];
if(pos>k-1) right=pos-1;
else left=pos+1;
}
}
int partition(vector<int> &num,int left,int right){//降序
int i=left+1,j=right;
int tmp=num[left];
while(i<=j){
if(num[i]<tmp && num[j]>tmp) swap(num[i++],num[j--]);
if(num[i]>=tmp) i++;
if(num[j]<=tmp) j--;
}
swap(num[j],num[left]);
return j;
}
};
- 快速排序思想
347. Top K Frequent Elements
Medium
2389160Add to ListShare
Given a non-empty array of integers, return the k most frequent elements.
Example 1:
Input: nums = [1,1,1,2,2,3], k = 2 Output: [1,2]
Example 2:
Input: nums = [1], k = 1 Output: [1]
Note:
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
/*返回k个出现频率最高的元素,非空无序数组
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]*/
#include<iostream>
#include<vector>
#include<unordered_map>
#include<queue>
using namespace std;
/*1.使用map + priority_queue*/
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> mp;
for (int i = 0; i < nums.size();i++){
mp[nums[i]]++;
}
priority_queue<pair<int, int> > q;
unordered_map<int, int>::iterator it;
vector<int> res;
for (it = mp.begin(); it != mp.end();it++){
q.push(make_pair(it->second, it->first));
}
while(k>0){
k--;
cout << k << endl;
res.push_back(q.top().second);
q.pop();
}
return res;
}
/*2.使用桶排序思想,额外维护一个二维数组,存放出现 i 次数的数字组成的数组*/
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> mp;
for (int i = 0; i < nums.size();i++){
mp[nums[i]]++;
}
vector<vector<int>> bucket(nums.size() + 1);
unordered_map<int, int>::iterator it;
for(it=mp.begin();it!=mp.end();it++){
bucket[it->second].push_back(it->first);
}
vector<int> res;
for(int i=nums.size();i>=0;i--){
for (int j = 0; j < bucket[i].size();j++){
res.push_back(bucket[i][j]);
}
if(res.size()==k) return res;
}
return res;
}
int main(){
vector<int> num = {1, 1, 1, 2, 2, 3};
vector<int> res = topKFrequent(num, 2);
for (int i = 0; i < res.size(); i++){
cout << res[i] << " ";
}
system("pause");
return 0;
}
692. Top K Frequent Words
Medium
1304109Add to ListShare
Given a non-empty list of words, return the k most frequent elements.
Your answer should be sorted by frequency from highest to lowest. If two words have the same frequency, then the word with the lower alphabetical order comes first.
Example 1:
Input: ["i", "love", "leetcode", "i", "love", "coding"], k = 2 Output: ["i", "love"] Explanation: "i" and "love" are the two most frequent words.Note that "i" comes before "love" due to a lower alphabetical order.
Example 2:
Input: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4 Output: ["the", "is", "sunny", "day"] Explanation: "the", "is", "sunny" and "day" are the four most frequent words,with the number of occurrence being 4, 3, 2 and 1 respectively.
Note:
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Input words contain only lowercase letters.
Follow up:
- Try to solve it in O(n log k) time and O(n) extra space.
class Solution {
public:
struct cmp_q{
template <typename T, typename U>
bool operator()(T const &left, U const &right){
if (left.first == right.first)
return left.second > right.second;
return left.first < right.first;
}
};
vector<string> topKFrequent(vector<string>& words, int k) {
int n=words.size();
vector<string> res;
map<string,int> mp;
for(int i=0;i<n;i++){
mp[words[i]]++;
}
priority_queue<pair<int,string>,vector<pair<int,string> >,cmp_q > q;
map<string,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++){
q.push(make_pair(it->second,it->first));
}
for(int i=0;i<k;i++){
res.push_back(q.top().second);
q.pop();
}
return res;
}
};
class Solution {
public:
struct Node{
int x;
string y;
};
struct cmp_q{
bool operator()(Node a,Node b){
if(a.x==b.x) return a.y>b.y;
else return a.x<b.x;
}
};
vector<string> topKFrequent(vector<string>& words, int k) {
int n=words.size();
vector<string> res;
map<string,int> mp;
for(int i=0;i<n;i++){
mp[words[i]]++;
}
priority_queue<Node,vector<Node>,cmp_q > q;
map<string,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++){
q.push({it->second,it->first});
}
for(int i=0;i<k;i++){
res.push_back(q.top().y);
q.pop();
}
return res;
}
};
class Solution {
public:
vector<string> topKFrequent(vector<string>& words, int k) {
unordered_map<string, int> mp;
for (int i = 0; i < words.size();i++){
mp[words[i]]++;
}
vector<priority_queue<string,vector<string>,greater<string> > >bucket(words.size()+1);
//这里定义priority_queue的排序:默认是less,即降序,要注明为greater,为升序
//vector<priority_queue ...... >
//priority_queue的定义:priority_queue<string,vector<string>,greater<string> >
unordered_map<string, int>::iterator it;
for (it = mp.begin(); it != mp.end();it++){
bucket[it->second].push(it->first);
}
vector<string> res;
for (int i = bucket.size()-1; i >= 0;i--){
while(k>0 && !bucket[i].empty()){
k--;
res.push_back(bucket[i].top());
bucket[i].pop();
}
}
return res;
}
};
- priority_queue的排序机制的写法和vector的sort的排序机制的写法正好顺序相反
973. K Closest Points to Origin
Medium
111293Add to ListShare
We have a list of points
on the plane. Find the K
closest points to the origin (0, 0)
.
(Here, the distance between two points on a plane is the Euclidean distance.)
You may return the answer in any order. The answer is guaranteed to be unique (except for the order that it is in.)
Example 1:
Input: points = [[1,3],[-2,2]], K = 1 Output: [[-2,2]] Explanation: The distance between (1, 3) and the origin is sqrt(10). The distance between (-2, 2) and the origin is sqrt(8). Since sqrt(8) < sqrt(10), (-2, 2) is closer to the origin. We only want the closest K = 1 points from the origin, so the answer is just [[-2,2]].
Example 2:
Input: points = [[3,3],[5,-1],[-2,4]], K = 2 Output: [[3,3],[-2,4]] (The answer [[-2,4],[3,3]] would also be accepted.)
Note:
1 <= K <= points.length <= 10000
-10000 < points[i][0] < 10000
-10000 < points[i][1] < 10000
/*973. K Closest Points to Origin*/
#include"pch.h"
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct Node {
int x;
vector<int> y;
};
struct cmp_q {
bool operator()(Node a, Node b) {
return a.x > b.x;
}
};
vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
priority_queue < pair<int, vector<int> >, vector<pair<int, vector<int> > >, greater<pair<int, vector<int> > > > q;
for (int i = 0; i < points.size(); i++) {
int sum = points[i][0] * points[i][0] + points[i][1] * points[i][1];
q.push({ sum,{points[i][0],points[i][1]} });
}
vector<vector<int> > res;
for (int i = 0; i < K; i++) {
res.push_back(q.top().second);
q.pop();
}
return res;
}
int main(){
vector<vector<int> > points = { {1,3},{2,-2} };
vector<vector<int> > res = kClosest(points, 1);
for (int i = 0; i < res.size(); i++) {
cout << res[i][0] << " " << res[i][1] << endl;
}
return 0;
}
1054. Distant Barcodes
Medium
21915Add to ListShare
In a warehouse, there is a row of barcodes, where the i
-th barcode is barcodes[i]
.
Rearrange the barcodes so that no two adjacent barcodes are equal. You may return any answer, and it is guaranteed an answer exists.
Example 1:
Input: [1,1,1,2,2,2] Output: [2,1,2,1,2,1]
Example 2:
Input: [1,1,1,1,2,2,3,3] Output: [1,3,1,3,2,1,2,1]
Note:
1 <= barcodes.length <= 10000
1 <= barcodes[i] <= 10000
/*973. K Closest Points to Origin*/
#include"pch.h"
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<unordered_map>
using namespace std;
//1.优先队列存放,每次先取最大的,再取次大的
//Runtime: 452 ms, faster than 6.89% of C++ online submissions for Distant Barcodes.
//Memory Usage : 45.3 MB, less than 100.00% of C++ online submissions for Distant Barcodes.
vector<int> rearrangeBarcodes1(vector<int>& barcodes) {
unordered_map<int, int> mp;
for (int i = 0; i < barcodes.size(); i++) mp[barcodes[i]]++;
priority_queue<vector<int>, vector<vector<int> >, less<vector<int> > > q;
unordered_map<int, int> ::iterator it;
for (it = mp.begin(); it != mp.end(); it++) {
q.push({ it->second,it->first });
}
vector<int> res;
while (!q.empty()) {
vector<int> tmp = q.top();
q.pop();
res.push_back(tmp[1]);
tmp[0] -= 1;
if (!q.empty()) {
vector<int> tmpp = q.top();
q.pop();
res.push_back(tmpp[1]);
tmpp[0] -= 1;
if (tmpp[0] > 0) q.push({ tmpp[0],tmpp[1] });
if (tmp[0] > 0) q.push({ tmp[0],tmp[1] });
}
}
return res;
}
/*2.贪心原则,将每种数字按照出现的次数从大到小排序,然后先依次填位置 1、3、5 等奇数位置,然后再填偶数位置。
/时间复杂度:将数字的个数排序,最坏需要 O(nlogn) 的时间。
空间复杂度:需要数组额外存储数字的个数,还需要哈希表辅助记录,需要记录答案的数组,故空间复杂度为 O(n)。
Runtime: 216 ms, faster than 80.54% of C++ online submissions for Distant Barcodes.
Memory Usage: 21 MB, less than 100.00% of C++ online submissions for Distant Barcodes.*/
static bool cmp(const pair<int, int> &a, const pair<int, int> &b) {
return a.first > b.first;
}
vector<int> rearrangeBarcodes2(vector<int>& barcodes) {
unordered_map<int, int> mp;
for (int i = 0; i < barcodes.size(); i++) mp[barcodes[i]]++;
vector<pair<int, int> >sorted;
unordered_map<int, int>::iterator it;
for (it = mp.begin(); it != mp.end(); it++) {
sorted.push_back({ it->second,it->first });
}
sort(sorted.begin(), sorted.end(), cmp);
int k = 0;
for (int i = 0; i < sorted.size(); i++) {
int num = sorted[i].first;
while (num--) {
if (k < barcodes.size()) {
barcodes[k] = sorted[i].second;
k += 2;
}
else {
k = 1;
barcodes[k] = sorted[i].second;
k += 2;
}
}
}
return barcodes;
}
int main(){
vector<int> barcodes = { 2,2,2,1,5 };
vector<int> res = rearrangeBarcodes2(barcodes);
for (int i = 0; i < res.size(); i++) {
cout << res[i] << " ";
}
return 0;
}
378. Kth Smallest Element in a Sorted Matrix
Medium
1799106Add to ListShare
Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.
Note that it is the kth smallest element in the sorted order, not the kth distinct element.
Example:
matrix = [ [ 1, 5, 9], [10, 11, 13], [12, 13, 15] ],k = 8,return 13.
Note:
You may assume k is always valid, 1 ≤ k ≤ n2.
/*973. K Closest Points to Origin*/
#include"pch.h"
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<unordered_map>
#include<set>
using namespace std;
/*找到矩阵中第k大的数字,矩阵行、列有序
matrix = [[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]],k = 8,return 13*/
/*1.二维变一维:
Runtime: 60 ms, faster than 48.36% of C++ online submissions for Kth Smallest Element in a Sorted Matrix.
Memory Usage: 13.4 MB, less than 31.82% of C++ online submissions for Kth Smallest Element in a Sorted Matrix.*/
int kthSmallest1(vector<vector<int>>& matrix, int k) {
priority_queue<int> st;
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix.size(); j++) {
st.push(matrix[i][j]);
}
}
k = st.size() - k;
int tmp;
for (int i = 0; i <= k; i++) {
tmp = st.top();
st.pop();
}
return tmp;
}
/*2.维护大小为k的最大堆:priority_queue,less,降序,数字越大优先级越高,在队首
求第k小的数,维持一个k大小的最大堆,当堆中数量==k,直接跳到下一行,因为本行的下一个一定比当前堆顶大,不必入堆
Runtime: 48 ms, faster than 67.53% of C++ online submissions for Kth Smallest Element in a Sorted Matrix.
Memory Usage: 13.1 MB, less than 40.91% of C++ online submissions for Kth Smallest Element in a Sorted Matrix.*/
int kthSmallest2(vector<vector<int>>& matrix, int k) {
priority_queue<int> q;
for (int i = 0; i < matrix.size(); i++) {
if (q.size() == k && matrix[i][0] > q.top()) return q.top();
for (int j = 0; j < matrix.size(); j++) {
if (q.size() == k) {
if (matrix[i][j] >= q.top()) break;
else {
q.pop();
q.push(matrix[i][j]);
}
}
else {
q.push(matrix[i][j]);
}
}
}
return q.top();
}
/*3.二分查找:左上角一定最小,右下角一定最大,找出中间数字,
由于不同行之间的元素并不严格有序,所以每一行都要查找mid,
使用upper_bound(第一个大于该元素的位置)
如果目标数比该行尾元素大,那么upper_bound返回该行元素个数,
如果目标数比该行首元素小,那么upper_bound返回0,
遍历完所有的行,可以找出中间数是第几小的数,
与k比较,进行二分查找。时间复杂度:O(nlgn * lgx) , x=max-min
Runtime: 36 ms, faster than 94.89% of C++ online submissions for Kth Smallest Element in a Sorted Matrix.
Memory Usage: 12 MB, less than 100.00% of C++ online submissions for Kth Smallest Element in a Sorted Matrix.*/
int kthSmallest3(vector<vector<int>>& matrix, int k) {
int left = matrix[0][0], right = matrix[matrix.size() - 1][matrix.size() - 1];
while (left < right) {
int mid = left + (right - left) / 2;
int tmp = 0;
for (int i = 0; i < matrix.size(); i++) {
tmp += upper_bound(matrix[i].begin(), matrix[i].end(), mid) - matrix[i].begin();
}
if (tmp < k) left = mid + 1;
else right = mid;
}
return left;
}
/*4.由于列之间也是有序的,所以不用对每一行都二分查找,
从左下角开始,如果比目标值小,就右移一位,反之,上移一位
如果是右移,那么右移之前那个数的上面所有数字都小于目标值,tmp+=i+1
Runtime: 36 ms, faster than 94.89% of C++ online submissions for Kth Smallest Element in a Sorted Matrix.
Memory Usage: 11.9 MB, less than 100.00% of C++ online submissions for Kth Smallest Element in a Sorted Matrix.*/
int kthSmallest4(vector<vector<int>>& matrix, int k) {
int left = matrix[0][0], right = matrix[matrix.size() - 1][matrix.size() - 1];
while (left < right) {
int mid = left + (right - left) / 2;
int tmp = 0;
int i = matrix.size() - 1, j = 0;//行,列
while (i >= 0 && j < matrix.size()) {
if (matrix[i][j] > mid) i--;
else if (matrix[i][j] <= mid) {
tmp += i + 1;
j++;
}
}
if (tmp < k) left = mid + 1;
else right = mid;
}
return left;
}
int main() {
vector<vector<int> > matrix = { {1,5,9},{10,11,13},{12,13,15} };
cout << kthSmallest3(matrix, 8) << endl;
return 0;
}
373. Find K Pairs with Smallest Sums
Medium
101585Add to ListShare
You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.
Define a pair (u,v) which consists of one element from the first array and one element from the second array.
Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.
Example 1:
Input: nums1 = [1,7,11], nums2 = [2,4,6], k = 3 Output: [[1,2],[1,4],[1,6]] Explanation: The first 3 pairs are returned from the sequence: [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
Example 2:
Input: nums1 = [1,1,2], nums2 = [1,2,3], k = 2 Output: [1,1],[1,1] Explanation: The first 2 pairs are returned from the sequence: [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]
Example 3:
Input: nums1 = [1,2], nums2 = [3], k = 3 Output: [1,3],[2,3] Explanation: All possible pairs are returned from the sequence: [1,3],[2,3]
/*373. Find K Pairs with Smallest Sums*/
#include"pch.h"
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<unordered_map>
#include<set>
using namespace std;
struct cmp_q {
bool operator()(const pair<int, int> &a, const pair<int, int> &b) {
return a.first + a.second < b.first + b.second;
//与vector的sort定义是相反的,若想要实现升序(前k个最小的和),返回 >
}
};
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
priority_queue<pair<int, int>, vector<pair<int, int> >, cmp_q> q;
for (int i = 0; i < nums1.size(); i++) {
for (int j = 0; j < nums2.size(); j++) {
if (q.size() == k) {
if (nums1[i] + nums2[j] < q.top().first+q.top().second) {
q.pop();
q.push({ nums1[i],nums2[j] });
}
else break;
}
else {
q.push({ nums1[i],nums2[j] });
}
}
}
vector<vector<int> > res;
while (!q.empty()) {
res.push_back({ q.top().first,q.top().second });
q.pop();
}
return res;
}
int main(){
vector<int> nums1 = { 1,1,2 };
vector<int> nums2 = { 1,2,3 };
vector<vector<int> > res = kSmallestPairs(nums1, nums2,2);
for (int i = 0; i < res.size(); i++) {
cout << res[i][0] << " " << res[i][1] << endl;
}
return 0;
}
719. Find K-th Smallest Pair Distance
Hard
73625Add to ListShare
Given an integer array, return the k-th smallest distance among all the pairs. The distance of a pair (A, B) is defined as the absolute difference between A and B.
Example 1:
Input:nums = [1,3,1]k = 1 Output: 0 Explanation: Here are all the pairs: (1,3) -> 2 (1,1) -> 0 (3,1) -> 2 Then the 1st smallest distance pair is (1,1), and its distance is 0.
Note:
2 <= len(nums) <= 10000
.0 <= nums[i] < 1000000
.1 <= k <= len(nums) * (len(nums) - 1) / 2
.
/*719. Find K-th Smallest Pair Distance*/
#include"pch.h"
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<unordered_map>
#include<set>
using namespace std;
/*第k个小的和*/
/*1.priority_queue,超时*/
int smallestDistancePair1(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
priority_queue<int> q;
for (int i = 0; i < nums.size(); i++) {
for (int j = i + 1; j < nums.size(); j++) {
if (q.size() == k) {
if (nums[j] - nums[i] < q.top()) {
q.pop();
q.push(nums[j] - nums[i]);
}
else break;
}
else {
q.push(nums[j] - nums[i]);
}
}
}
return q.top();
}
/*2.桶排序:0 <= nums[i] < 1000000,创建1000000个桶,桶中存储距离
Runtime: 1272 ms, faster than 5.05% of C++ online submissions for Find K-th Smallest Pair Distance.
Memory Usage: 93.1 MB, less than 8.33% of C++ online submissions for Find K-th Smallest Pair Distance.*/
int smallestDistancePair2(vector<int>& nums, int k) {
int n = nums.size();
vector<int> bucket(1000000, 0);
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
bucket[abs(nums[i] - nums[j])]++;
}
}
int res = 0;
for (int i = 0; i < 1000000; i++) {
while (k && bucket[i]) {
k--;
bucket[i]--;
}
if (k == 0) {
res = i;
break;
}
}
return res;
}
/*3.二分,先排序,起始left=0,right=结束位置
每次start都从最小的位置0开始,从头遍历整个数组,
计算对于每个nums[i],其与前面的数字距离超过mid的个数,
如果超过mid的个数大于指定的k,说明要找的数字在左边,调整right,
反之,说明要找的数字在右边,调整left。
Runtime: 8 ms, faster than 99.39% of C++ online submissions for Find K-th Smallest Pair Distance.
Memory Usage: 9.3 MB, less than 83.33% of C++ online submissions for Find K-th Smallest Pair Distance.*/
int smallestDistancePair3(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
int left = 0, right = nums[nums.size()-1]-nums[0];
while (left < right) {
int mid = left + (right - left) / 2;
int tmp = 0, start = 0;
for (int i = 0; i < nums.size(); i++) {
while (start<nums.size() && nums[i] - nums[start]>mid) start++;
tmp += i - start;
}
if (tmp >= k) right = mid;
else left = mid + 1;
}
return right;
}
int main() {
vector<int> nums = { 1,3,1 };
cout << smallestDistancePair3(nums, 1);
return 0;
}
658. Find K Closest Elements
Medium
979202Add to ListShare
Given a sorted array, two integers k
and x
, find the k
closest elements to x
in the array. The result should also be sorted in ascending order. If there is a tie, the smaller elements are always preferred.
Example 1:
Input: [1,2,3,4,5], k=4, x=3 Output: [1,2,3,4]
Example 2:
Input: [1,2,3,4,5], k=4, x=-1 Output: [1,2,3,4]
Note:
- The value k is positive and will always be smaller than the length of the sorted array.
- Length of the given array is positive and will not exceed 104
- Absolute value of elements in the array and x will not exceed 104
/*658. Find K Closest Elements*/
#include"pch.h"
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<unordered_map>
#include<set>
using namespace std;
/*1.数组中每个数与x的差值绝对值,前k小的数
使用priority_queue:
Runtime: 164 ms, faster than 15.81% of C++ online submissions for Find K Closest Elements.
Memory Usage: 15.9 MB, less than 16.67% of C++ online submissions for Find K Closest Elements.*/
vector<int> findClosestElements1(vector<int>& arr, int k, int x) {
priority_queue<pair<int, int>,vector<pair<int,int> >,less<pair<int,int> > > q;//默认less,大的先出队
for (int i = 0; i < arr.size(); i++) {
if (q.size() == k) {
if (abs(arr[i] - x) < q.top().first) {
q.pop();
q.push({ abs(arr[i] - x),arr[i] });
}
else if (arr[i] - x > 0 && abs(arr[i] - x) > q.top().first) break;
}
else q.push({ abs(arr[i] - x),arr[i] });
}
vector<int> res;
while (!q.empty()) {
res.push_back(q.top().second);
q.pop();
}
sort(res.begin(), res.end());
return res;
}
/*2.桶排序:k<数组长度,数组长度<=10000,-10000<=每个数的值(包括x)<=10000
Runtime: 144 ms, faster than 21.11% of C++ online submissions for Find K Closest Elements.
Memory Usage: 50.1 MB, less than 16.67% of C++ online submissions for Find K Closest Elements.*/
vector<int> findClosestElements2(vector<int>& arr, int k, int x) {
vector<vector<int> > bucket(20001);
for (int i = 0; i < arr.size(); i++) {
bucket[abs(arr[i] - x)].push_back(arr[i]);
}
vector<int> res;
for (int i = 0; i < 20001; i++) {
if (bucket[i].size() != 0) {
if (bucket[i].size() < k) {
k -= bucket[i].size();
for (int j = 0; j < bucket[i].size(); j++) res.push_back(bucket[i][j]);
}
else {
for (int j = 0; j < k; j++) res.push_back(bucket[i][j]);
i = 20001;
}
}
}
sort(res.begin(), res.end());
return res;
}
/*3.二分法:找到第一个不小于x的数,然后向左右遍历
Runtime: 104 ms, faster than 56.01% of C++ online submissions for Find K Closest Elements.
Memory Usage: 13.8 MB, less than 16.67% of C++ online submissions for Find K Closest Elements.*/
vector<int> findClosestElements3(vector<int>& arr, int k, int x) {
int tar = lower_bound(arr.begin(), arr.end(), x)-arr.begin();
int left = tar - 1, right = tar;
vector<int> res;
while (k>0 && left >= 0 && right < arr.size()) {
if (k>0 && abs(arr[left] - x) <= abs(arr[right]- x)) {
res.push_back(arr[left]);
left--;
k--;
}
else if (k > 0 && abs(arr[left] - x) > abs(arr[right]-x)) {
res.push_back(arr[right]);
right++;
k--;
}
}
while (k > 0 && left >= 0) {
res.push_back(arr[left--]);
k--;
}
while (k > 0 && right < arr.size()) {
res.push_back(arr[right++]);
k--;
}
sort(res.begin(), res.end());
return res;
}
/*4.二分法:每次比较mid与x的距离和mid+k与x的距离,从而判断折半的方向
Runtime: 100 ms, faster than 79.15% of C++ online submissions for Find K Closest Elements.
Memory Usage: 13.1 MB, less than 66.67% of C++ online submissions for Find K Closest Elements.*/
vector<int> findClosestElements4(vector<int>& arr, int k, int x) {
int left = 0, right = arr.size() - k;
while (left < right) {
int mid = left + (right - left)/2;
if (x - arr[mid] > arr[mid + k] - x) left = mid + 1;
else right = mid;
}
return vector<int>(arr.begin() + left, arr.begin() + left + k);
}
int main() {
vector<int> nums = { 1,2,3,4,5 };
vector<int> res = findClosestElements4(nums, 4,3);
for (int i = 0; i < res.size(); i++) {
cout << res[i] << " ";
}
return 0;
}