天池训练营链接
有序数组的平方
双指针,时间O(n),空间O(n)
但是太慢了
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
//双指针插入,一个在头,一个在尾部
vector<int> v;
int n=nums.size();
int left=0,right=n-1;
if(n==0) return v;
while(left <= right){
if(left==right){
v.insert(v.begin(), nums[left]*nums[left]);
break;
}
else{
if(abs(nums[left])>abs(nums[right])){
v.insert(v.begin(), nums[left]*nums[left]);
left+=1;
}
else{
v.insert(v.begin(), nums[right]*nums[right]);
right-=1;
}
}
}
return v;
}
};
不用insert
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
//双指针插入,一个在头,一个在尾部
int n=nums.size();
vector<int> v(n);
int left=0,right=n-1;
if(n==0) return v;
int pos=n-1;
while(left <= right){
if(abs(nums[left])>abs(nums[right])){
v[pos] = nums[left]*nums[left];
left+=1;
pos--;
}
else{
v[pos] = nums[right]*nums[right];
right-=1;
pos--;
}
}
return v;
}
};
数组的相对排序
计数排序参考题解
1.计数排序
建立一个长1001的vector v,扫描arr1,把arr1的值在v里面计数,v[i]是arr1里面i出现的次数
然后扫描arr2,每扫一个数,看v里面出现过几次,迭代把这些数存进arr1的对应位置
最后扫描v,剩下的升序存进arr1
class Solution {
public:
vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) {
//建立一个长1001的vector v,扫描arr1,把arr1的值在v里面计数,v[i]是arr1里面i出现的次数
//然后扫描arr2,每扫一个数,看v里面出现过几次,迭代把这些数存进arr1的对应位置
//最后扫描v,剩下的升序存进arr1
vector<int> v(1001, 0);
for(auto num:arr1){
v[num]++;
}
int pos=0;//arr1里面插入的位置
for(auto num:arr2){
while(v[num]>0){
arr1[pos]=num;
v[num]--;
pos++;
}
}
for(int i=0; i<1001;++i){
while(v[i]>0){
arr1[pos]=i;
v[i]--;
pos++;
}
}
return arr1;
}
};
2.自定义排序
class Solution {
public:
vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) {
unordered_map<int,int> rank;
for(int i=0;i<arr2.size(); ++i){
rank[arr2[i]]=i;//rank是arr2里面该数字的下标
}
sort(arr1.begin(), arr1.end(), [&](int x, int y){
if(rank.count(x)){
if(rank.count(y)){//x,y都在arr2
return rank[x]<rank[y];
}
else
return true;//x在arr2,y不在
}
else{
if(rank.count(y)) return false;//x不在arr2,y在
else return x<y;
}
});
return arr1;
}
};
对链表进行插入排序
题解链接
链表一定要画图。整个链表的图
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
if(head == nullptr) return head;
ListNode *dummyHead=new ListNode(0, head);
ListNode* lastSorted=head;//head先插进已排序链表,lastSorted是已排序链表的最后一个节点
ListNode* cur=head->next;
while(cur!=nullptr){
//往后遍历,逐个插入到已经排序好的链表中
if(cur->val >= lastSorted->val){
lastSorted=lastSorted->next;
}
else{
ListNode* pre=dummyHead;
while(pre->next->val <= cur->val){
pre=pre->next;
}
//插在pre后面
lastSorted->next=cur->next;
cur->next=pre->next;
pre->next=cur;
}
cur=lastSorted->next;
}
return dummyHead->next;
}
};
合并两个有序数组
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
//用辅助数组的方法很简单,所以这里只做逆向指针方法,空间O(1)原地改
int pos1=m-1, pos2=n-1, pos=n+m-1;
while(pos1>=0 && pos2>=0){
if(nums1[pos1]>nums2[pos2]){
nums1[pos]=nums1[pos1];
pos1-=1;
}
else{
nums1[pos]=nums2[pos2];
pos2-=1;
}
pos-=1;
}
if(pos2<0) return;
else{
for(int i=pos2; i>=0; --i){
nums1[pos]=nums2[i];
pos-=1;
}
}
return;
}
};
知识
- 哈希表和自定义排序
unordered_map<int,int> rank;//哈希表
sort(arr1.begin(), arr1.end(), [&](int x, int y){
if(rank.count(x)){
if(rank.count(y)){//x,y都在arr2
return rank[x]<rank[y];
}
else
return true;//x在arr2,y不在
}
else{
if(rank.count(y)) return false;//x不在arr2,y在
else return x<y;
}
});