1.除二操作/2与>>1
而>> 1和/ 2在n为负奇数时截断的反向不一样。
-5 / 2 = -(int)2.5 = -2,这里是把绝对值变小了,加个负号,结果就变大了。 -5 >> 1 = (1011) >> 1 = (1101) = -3,假设用4-bit表示一个整数,补码表示。发现结果变小了。 -5 / 2 = -2 5 / 2 = 2。这表明除二是向零取整 -5 >> 1 = -3 5 >> 1 = 2。这表明右移一位是向下取整
2.堆排序
#include<iostream> #include<vector> using namespace std; //将index的位置的值向下沉,形成大根堆 //heapsize是有效长度为了判断是否完成 void heapify(vector<int>& arr,int index,int heapsize) { int leftk=index*2+1,rightk=leftk+1; while(leftk<heapsize) { //两个儿子哪个大,并且有右儿子 int lagerst=rightk<heapsize&&arr[rightk]>arr[leftk]?rightk:leftk; if(arr[index]>=arr[lagerst]) break; else { swap(arr[index],arr[lagerst]); index=lagerst; } leftk=index*2+1; rightk=leftk+1; } } //作用:arr中数都已经确定,index从0到arr.size()-1 //将arr依次变成大根堆 void heapinsent(vector<int>& arr,int index) { while(arr[index]>arr[(index-1)/2]) //注意要是可能出现负数就直接用/2 { swap(arr[index],arr[(index-1)/2]); index=(index-1)>>1; } } int main() { int a; cin>>a; vector<int> arr(a); for(int &b:arr) cin>>b; for(int b=0;b<arr.size();b++) heapinsent(arr,b); //一个一个加入从0到len-1一个下标一个下标加入 for(int b=arr.size()-1;b>=0;b--) heapify(arr, b, heapsize); //heapify就是把b坐标的值向下沉,从len-1到0从右向左,从下向上每个坐标值都下沉就可以实现 //注意有效长度一直不变 int heapsize=arr.size(); while(heapsize>0) { swap(arr[0],arr[--heapsize]); heapify(arr,0,heapsize); } //b是1234...arr.size()-1 for(int i=0;i<a;i++) cout<<arr[i]<<" "; return 0; }
当一堆数全部给到arr中可以直接使用heapify变成大根堆
#include<iostream> #include<vector> using namespace std; //将index的位置的值向下沉,形成大根堆 //heapsize是有效长度为了判断是否完成 void heapify(vector<int>& arr,int index,int heapsize) { int leftk=index*2+1,rightk=leftk+1; while(leftk<heapsize) { //两个儿子哪个大,并且有右儿子 int lagerst=rightk<heapsize&&arr[rightk]>arr[leftk]?rightk:leftk; if(arr[index]>=arr[lagerst]) break; else { swap(arr[index],arr[lagerst]); index=lagerst; } leftk=index*2+1; rightk=leftk+1; } } //作用:arr中数都已经确定,index从0到arr.size()-1 //将arr依次变成大根堆 int main() { int a; cin>>a; vector<int> arr(a); for(int &b:arr) cin>>b; int heapsize=arr.size(); for(int b=arr.size()-1;b>=0;b--) heapify(arr, b, heapsize); //heapify就是把b坐标的值向下沉,从右向左,从下向上每个坐标值都下沉就可以实现 //注意有效长度一直不变 while(heapsize>0) { swap(arr[0],arr[--heapsize]); heapify(arr,0,heapsize); } //b是1234...arr.size()-1 for(int i=0;i<a;i++) cout<<arr[i]<<" "; return 0; }
3.荷兰国旗问题
#include<iostream> #include<vector> using namespace std; int main() { int a,tar; cin>>a>>tar; vector<int> arr(a); for(int &b:arr) cin>>b; int p1=-1; //>=区最右端最初是-1 p1是<=区右边界 for(int index=0;index<arr.size();index++) if(arr[index]<=tar) swap(arr[index],arr[++p1]); //当有一个<=数交换当前数和<=区下一个数,<=区右扩一位 for(int i=0;i<a;i++) cout<<arr[i]<<" "; return 0; }
#include<iostream> #include<vector> using namespace std; int main() { int a,tar; cin>>a>>tar; vector<int> arr(a); for(int &b:arr) cin>>b; int p1=-1,p2=arr.size(),index=0; //>=区最右端最初是-1 while(index<p2) //下标小于右边的边界 { if(arr[index]<tar) swap(arr[index++],arr[++p1]); else if(arr[index]>tar) swap(arr[index],arr[--p2]); //向右换之后还得判断这 //个位置要不要向左换所以index不变 else index++; } if(p1+1>p2-1) {p1=-2;p2=0;} cout<<p1+1<<" "<<p2-1; return 0; }
#include<iostream> #include<vector> using namespace std; //int res[2];定义全局数组就可以直接输出结果 vector<int> partition(vector<int> arr,int left,int right,int target) { int p1=left-1,p2=right+1,index=left; //>=区最右端最初是-1 vector<int> res(2); while(index<p2) { if(arr[index]<target) swap(arr[index++],arr[++p1]); else if(arr[index]>target) swap(arr[index],arr[--p2]); else index++; } if(p1+1>p2-1) {p1=-2;p2=0;} res[0]=p1+1; res[1]=p2-1; return res; } int main() { int a,tar; cin>>a>>tar; vector<int> arr(a); for(int &b:arr) cin>>b; int p1=0,p2=arr.size()-1,index=0; //>=区最右端最初是-1 for(int a:partition(arr,p1,p2,tar)) cout<<a<<" "; return 0; }
4.随机数
5.快速排序
#include<iostream> #include<vector> using namespace std; int res[2]; void partition(vector<int>& arr,int left,int right) { int p1=left-1,p2=right+1,index=left,target=arr[right]; while(index<p2) { if(arr[index]<target) swap(arr[index++],arr[++p1]); else if(arr[index]>target) swap(arr[index],arr[--p2]); else index++; } res[0]=p1+1; res[1]=p2-1; } void process(vector<int>& arr,int left,int right) { if(left<right){ swap(arr[right],arr[(rand()%(right-left))+1+left]); partition(arr,left,right); process(arr,left,res[0]-1); process(arr,res[1]+1,right); } } int main() { int a; cin>>a; vector<int> arr(a); for(int &b:arr) cin>>b; int p1=0,p2=arr.size()-1; //>=区最右端最初是-1 process(arr,p1, p2); for(int i=0;i<a;i++) cout<<arr[i]<<" "; return 0; }
6.题目1 581. 最短无序连续子数组 - 力扣(LeetCode) (leetcode-cn.com)
class Solution { public: int findUnsortedSubarray(vector<int> arr) { int len=arr.size(),left=0,right=arr.size()-1; vector<int> midarr(arr); sort(midarr.begin(),midarr.end()); while(left<len&&midarr[left]==arr[left]) left++; while(right>left&&midarr[right]==arr[right]) right--; return right-left+1; } }; class Solution { public: int findUnsortedSubarray(vector<int> arr) { int len=arr.size(),left=0,right=arr.size()-1; int max=arr[0],min=arr[len-1]; for(int i=0;i<len;i++) { if(arr[i]>=max) max=arr[i]; else left=i; } for(int j=len-1;j>=0;j--) { if(arr[j]<=min) min=arr[j]; else right=j; } if(left==0) return 0; return left-right+1; } };
class Solution { public: string modifyString(string s) { int n = s.size(); for (int i = 0; i < n; ++i) { if (s[i] == '?') { for (char ch = 'a'; ch <= 'c'; ++ch) { if ((i > 0 && s[i - 1] == ch) || (i < n - 1 && s[i + 1] == ch)) { continue; } s[i] = ch; break; } } } return s; } };