2022/1/18

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.随机数 

C++产生随机数 - VVingerfly - 博客园 (cnblogs.com)

(58条消息) C++产生随机数_陆柒-优快云博客_c++ 随机数

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;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值