1.删除有序数组重复元素(双指针)
#include<iostream>
using namespace std;
int main(){
int a[]={1,1,2,2,3,3,4};
int k=1;
for(int i=1;i<7;i++){
if(a[i]!=a[i-1]){
a[k]=a[i];
k++;
}
}
for(int i=0 ;i<k;i++){
cout<<a[i]<<endl;
}
return 0;
}
2.合并两个有序顺序表(开辟新空间)
#include<iostream>
using namespace std;
int main(){
int a[]={1,3,5};
int b[]={2,4,6,7};
int c[3+4];
//核心 begin
int i=0,j=0,k=0;
while(i<3&&j<4){
if(a[i]<=a[j]){
c[k]=a[i];
k++;
i++;
}
else{
c[k]=b[j];
k++;
j++;
}
}
while(i<3){
c[k]=a[i];
i++;
k++;
}
while(j<4){
c[k]=b[j];
j++;
k++;
}
//end
for(int i=0;i<3+4;i++){
cout<<c[i]<<" ";
}
return 0;
}
- 将顺序表{a0,a1,a2,a3,b0,b1,b2}->{b0,b1,b2,a0,a1,a2,a3}
思路:整体逆置 + 部分逆置
#include<iostream>
using namespace std;
int main(){
int a[]={1,2,3,4,5,6,7};//m=4.n=3
int temp;
int j=7-1;
for(int i=0;i<j;i++){
temp=a[j];
a[j]=a[i];
a[i]=temp;
j--;
}
j=2; //(3-1)
for(int i=0;i<j;i++){
temp=a[j];
a[j]=a[i];
a[i]=temp;
j--;
}
j=4+3-1;//(4-1)
for(int i=3;i<j;i++){
temp=a[j];
a[j]=a[i];
a[i]=temp;
j--;
}
for(int i=0;i<7;i++){
cout<<a[i]<<" ";
}
return 0;
}
4.查找有序顺序表中的等于x的 若找出则和后边的交换位置,没有找出则插入该插入的位置。
思路:二分
#include<iostream>
using namespace std;
int main(){
int a[6]={1,4,5,9,10};
int r=sizeof(a)/4-1;
//核心 begin
int length=r+1;
int l=0;
int mid=0;
while(l<=r){
mid=(r+l)/2;
if(a[mid]==3){
break;
}
else if (a[mid]<3)
l=mid+1;
else
r=mid-1;
}
if(a[mid]==3&&mid!=length-1){
int temp=a[mid];
a[mid]=a[mid+1];
a[mid+1]=temp;
}
if(l>r){
int i;
for( i = length-1;i>r;i--){
a[i+1]=a[i];
}
a[i+1]=3;
}
// end
for(int i = 0 ;i<length;i++){
cout<<a[i]<<" ";
}
return 0;
}
5.求两个升序序列的中位数 (**********)(18页-11题)
设a数组中位数是 m1 , b数组中位数是 m2
思路:
- 若 a[m1]=b[m2] 直接输出
- a[m1]<b[m2] 则去掉a的m1的左边和b数组的m2的右边(如果a数组长度是偶数 则带上m1一起去掉)(奇偶只看小的那个)
- a[m1]>b[m2] 则去掉b的m2的左边和a数组的m1的右边(如果b数组长度是偶数 则带上m2一起去掉)(奇偶只看小的那个)
最后看a[l1]和b[l2]的小的那个就是要找的
#include<iostream>
using namespace std;
int main(){
int a[]={1,3,5,7};
int b[]={2,3,9,8};
//begin
int l1=0,r1=3,l2=0,r2=3;
int m1,m2;
int flag=0;
while(l1!=r1&&l2!=r2){
m1=(l1+r1)/2;
m2=(l2+r2)/2;
cout<<a[m1]<<" "<<b[m2]<<endl;
if(a[m1]==b[m2]){
flag=1;
break;
}
if(a[m1]<b[m2]){
if((r1+l1)%2==0){
l1=m1;
r2=m2;
}
else{
l1=m1+1;
r2=m2;
}
}else{
if((r2+l2)%2==0){
r1=m1;
l2=m2;
}else{
r1=m1;
l2=m2+1;
}
}
}
int temp=a[l1]<b[l2]?a[l1]:b[l2];
if (flag==1){
temp=a[m1];
}
cout<<temp;
//end
return 0;
}
时间复杂度 log2^n; 空间复杂度 1
- 找出数组中大于一般的数,若没有则输出-1;(18页第二题)
思路 :摩尔投票法
#include<iostream>
using namespace std;
int main(){
int a[]={1,1,1,1,1,3,5,7,8,11,123,123};
int temp=a[0],count=1;
for(int i=1;i<sizeof(a)/4;i++){
if(a[i]==temp){
count++;
}else{
if(count>0){
count--;
}else{
temp=a[i];
count=1;
}
}
}
if(count>0){
count=0;
for(int i=0;i<sizeof(a)/4;i++)
if(a[i]==temp)
count++;
}
if(count>sizeof(a)/4/2){
cout<<temp;
}else{
cout<<"-1"<<endl;
}
//end
return 0;
}
摩尔投票法找出的(count>0)不一定是超过一半的,最后还需要遍历看count是不是大于一半,若大于则是要求的.
时间复杂度 n 空间复杂度 1
也可以用快排+找众数的方法去做
7. 王道书(19页13题)
思路 :tm的自己看答案(自己没想到 就不写思路了)
#include<iostream>
#include<cstring>
using namespace std;
int main(){
int a[]={1,2,3};
//b=(int *)malloc(sizeof(a[0])*(sizeof(a)/4));
int *b = new int(sizeof(a)/4);
//头文件#include<cstring>
//memset(结构体/数组名 , 用于替换的ASCII码对应字符 , 前n个字符 );
memset(b,0,sizeof(a)/4);
for(int i=0;i<sizeof(a)/4;i++){
if(a[i]>0){
b[a[i]-1]=1;
}
}
int flag=0,j;
for(int i=0;i<sizeof(a)/4;i++){
if(b[i]==0){
flag=1;
j=i;
break;
}
}
if(flag==1){
cout<<j+1;
}else{
cout<<sizeof(a)/4+1;
}
//end
return 0;
}
最后一题直接看答案 ,已经写吐了 (⊙o⊙)…!!!