剑指offer算法题

时间:2024-08-02 11:05:08

数组中只出现一次的数字(一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字):

解法在于位运算中的异或,直接异或可以得到这两个数的异或,按照最后的有效数字位可以分为两个数组,然后分别异或得到各自的值;

void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
if(data.size()==0) return;
*num1=0;
*num2=0;
vector<int> data1,data2;
int res=0,flag=0;
for(auto &i : data)
res^=i;
while(!(res&1)){
res>>=1;
flag++;
}
int num=1<<flag;
for(auto &i : data){
if(i&num) data1.push_back(i);
else data2.push_back(i);
}
for(int &i : data1)
*num1^=i;
for(int &i : data2)
*num2^=i;
return;
}

 二进制中1的个数:

int  NumberOf1(int n) {
int count=0;
while(n){
count++;
n=n&(n-1); //把最后的1给消除掉,总共消除了几次,就证明有几个1
}
return count;
}

  数字在排序数组中出现的次数

class Solution {
public:
int res=0; //全局变量
int GetNumberOfK(vector<int> data ,int k) {
int size=data.size();
if(size<=0) return 0;
getn(data,0,size-1,k);
return res;
}
int getn(vector<int> &data,int start, int end, int k){
if(start>end) return 0; //退出条件
int mid=(start+end)/2; //二分 复杂度logn
if(data[mid]==k){
res++; //更改出现次数
getn(data,start,mid-1,k);
getn(data,mid+1,end,k);
}
else if(data[mid]<k){
getn(data,mid+1,end,k);
}
else getn(data,start,mid-1,k);
return 0;
}
}; //可以改为当找到匹配点,从左右开始找相同的,然后直接退出递归
if(k[mid]==a){
res++;
int i=mid;
while((--i)>=0&&k[i]==a){
res++;
}
while((++mid)<10&&k[mid]==a){
res++;
}
return 0;
}

  

  数据流中的中位数:采用两个堆,O(N)的复杂度

class Solution {
public:
void Insert(int num)
{
++count;
if(count&1){ //如果是奇数个数的元素,则先放入小顶堆,然后把小顶堆中的顶放到大顶堆中
min_heap.push(num);
max_heap.push(min_heap.top());
min_heap.pop();
}
else{
max_heap.push(num);
min_heap.push(max_heap.top());
max_heap.pop();
}
} double GetMedian()
{
if(count&1) return max_heap.top();
else return (max_heap.top()+min_heap.top())/2.0;
} private:
int count=0;
priority_queue<int, vector<int>, less<int>> max_heap;
priority_queue<int, vector<int>, greater<int>> min_heap; };