1. 删除返回最小值并由最后元素填补
bool Del_Min(vector<int>& nums,int &val) {
if(nums.size()==0) return false;
int pos = 0;//假定0号元素最小
for(int i=1;i<nums.size();i++)
if(nums[i]<nums[pos])
pos = i;//找最小值下标
val = nums[pos];//返回最小值
nums[pos] = nums.back();//替换删除值
nums.pop_back();//长度减一
return true;
}
2. 逆置所有元素
void Reverse(vector<int>& nums) {
int n = nums.size();
for(int i=0;i<nums.size()/2;i++)
swap(nums[i],nums[n-1-i]);
}
3. 删除所有指定值
void del_x(vector<int>& nums,int val) {
//本质上是重新更改映射
int k =0;//记录不等于val的个数
for(int i=0;i<nums.size();i++)
if(nums[i]!=val)
nums[k++] = nums[i];
//修改数组长度为k
}
4. 有序表中删除所有指定范围值
//与题3解法相同,由于是有序表,也可以先找映射前后的下标,再一一映射
bool Del_s_t(vector<int>& nums,int s,int t) {
int i , j;
if(s>=t||nums.size()==0) return false;
for(i=0;i<nums.size()&&nums[i]<s;i++);//找映射左下标,第一个大于等于s的值
for(j=i;j<nums.size()&&nums[j]<=t;j++);//找映射右下标,第一个大于t的值
for(;j<nums.size();j++)
nums[i] = nums[j];//重新映射
//修改数组长度为i
return true;
5. 删除所有指定范围值
void Del_s_t(vector<int>& nums,int s,int t) {
//本质上是重新更改映射
int k =0;//记录不在目标范围的个数
for(int i=0;i<nums.size();i++)
if(nums[i]<s||nums[i]>t)
nums[k++] = nums[i];
//修改数组长度为k
}
6. 有序表中删除重复值
bool Del_same(vector<int>& nums) {
if(nums.size()==0) return false;
int i , j;//双指针映射
for(i=0,j=1;j<nums.size();j++)
if(nums[i]!=nums[j])
nums[++i] = nums[j];//拓展映射数组
//修改数组长度为i+1
return true;
}
7. 有序顺序表合并
vector<int> merge(vector<int>& v1,vector<int>& v2) {
vector<int> res(v1.size()+v2.size());
int i = 0,j=0,k=0;
while(i<v1.size()&&j<v2.size()){
if(v1[i]<v2[j]) res[k++] = v1[i++];
else res[k++] = v2[j++];
}
while(i<v1.size()) res[k++] = v1[i++];
while(i<v1.size()) res[k++] = v2[j++];
return res;
}
8. 两区域元素位置互换(原地)
//先全部逆置,再分区域逆置
void Exchange(vector<int>nums,int m,int n){
Reverse(nums,0,m+n-1);
Reverse(nums,0,n-1);
Reverse(nums,n,m+n-1);
}
void Reverse(vector<int>& nums,int left,int right) {
for(int i=left;i<(left+right)/2;i++)
swap(nums[i],nums[right-i]);
}
9. 二分查找并插入
void bisearch(vector<int> nums,int val.int n){
int low = 0,high = n-1;
int mid;
while(low<=high){//循环结束后,若没找到,high小于val,low大于val
mid = (low + high)/2;
if(nums[mid]==val) break;//找到目标值
else if(nums[mid]<val) low = mid + 1;
else high = mid -1;
}
if(nums[mid]==val&&mid!=n-1)
swap(nums[mid],nums[mid+1]);//题目要求
if(low>high){
for(i=n-1;i>high;i--) nums[i+1] = nums[i];//后移元素,空出high后面元素
nums[high+1] = val;//插入值
}
}
10. 循环左移p个位置
//最优解类似题8,实质上等价于将p个元素区域和n-p个元素区域互换
三个逆置时间复杂度分别为O(p/2),O((n-p)/2),O(n/2)
故时间复杂度为O(n),空间复杂度为O(1)
//解法2借用一个辅助单元实现右移1位的操作,循环p次
//解法3借用p个辅助单元来进行移动
11. 求两升序序列中位数
//由于题目是等长序列,可以简单递归使问题规模不断变小
int medium(vector<int>& nums1, vector<int>& nums2, int s1, int d1, int s2, int d2) {
//之所以偶数递归加一,是因为整除向下取整
int m1 = (s1 + d1) / 2;
int m2 = (s2 + d2) / 2;
if (s1 == d1 && s2 == d2) return nums1[s1] < nums2[s2] ? nums1[s1] : nums2[s2];//边界条件
if (nums1[m1] == nums2[m2]) return nums1[m1];
if (nums1[m1] < nums2[m2]) {
if ((s1 + d1) % 2 == 0)//若元素个数为奇数
return medium(nums1, nums2, m1, d1, s2, m2);//舍弃nums1前面元素和nums2后面元素
else //若元素个数为偶数
return medium(nums1, nums2, m1 + 1, d1, s2, m2);//舍弃并保证双方还是偶数
}
else {
if ((s2 + d2) % 2 == 0)//若元素个数为奇数
return medium(nums1, nums2, s1, m1, m2, d2);//舍弃nums1后面元素和nums2前面元素
else //若元素个数为偶数
return medium(nums1, nums2, s1, m1, m2 + 1, d2);//舍弃并保证双方还是偶数
}
}
标签:顺序,nums,int,应用题,vector,元素,nums1,nums2
From: https://www.cnblogs.com/929code/p/16608382.html