//2015.08.10
/*** 数组的若干问题
** 1 求数组的最值问题
** 2 求数组中出现次数超过总数一半的元素
** 3 两个有序数组的共同元素
** 4 两个有序数组中和为某一值得元素对
** 5 数组中只有某一元素出现基数次,求之
** 6
**/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void printArry(vector<int> & arr)
{
for (unsigned i=0;i<arr.size();++i)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
//求数组的最大值和最小值
void maxAndmin(vector<int> & arr,int &maxNum,int &minNum)
{
cout<<endl<<"原始数组:";
printArry(arr);
if (!arr.size())
return;
maxNum = arr[0];
minNum = arr[0];
for (unsigned i=1;i<arr.size();++i)
{
if (arr[i] > maxNum)
maxNum = arr[i];
if (arr[i] < minNum)
minNum = arr[i];
}
cout<<"此数组的最大值和最小值分别为:"<<maxNum<<ends<<minNum<<endl;
}
//求数组的最大值和次大值 若有两个最大值怎么办?
void maxAndNextmax(vector<int> & arr,int &maxNum,int &nextMaxNum)
{
cout<<endl<<"原始数组:";
printArry(arr);
cout<<"数组的最大值和次大值分别为:"<<ends;
if (arr.size()<2)
return;
maxNum = max(arr[0],arr[1]);
nextMaxNum = min(arr[0],arr[1]);
for (unsigned i=2;i<arr.size();++i)//若有两个最大值相等怎么办?
{
if (arr[i] > nextMaxNum )
{
nextMaxNum = arr[i];
if (nextMaxNum > maxNum)
swap(nextMaxNum,maxNum);
}
}
cout<<maxNum<<ends<<nextMaxNum<<endl;
}
//求数组前最大的前k个数
int maxNumK(vector<int> & arr,int k)
{
cout<<endl<<"原始数组:";
printArry(arr);
int m = arr.size();
if (k > m)
{
cout<<"所求的个数比数组的元素多!error!!"<<endl;
return 0; //设置全局变量 是否成功
}
int * temp = new int[k];
for(int i=0;i<k;i++)
temp[i] = arr[i];
sort(temp,temp+k);
for (unsigned i=k;i<arr.size();++i)
{
if (arr[i] > temp[0])
{
temp[0] = arr[i];
sort(temp,temp+k);
}
}
cout<<"数组的前k个最大的数是:"<<ends;
//printArry(temp);
for (int i=0;i<k;++i)
{
cout<<temp[i]<<" ";
}
cout<<endl;
int num = temp[k-1];
delete [] temp;
return num;
}
//数组中出现次数超过一半的元素
int elementMulti(vector<int> & arr)
{
cout<<endl<<"原始数组:";
printArry(arr);
int element = arr[0];
int count =1;
for (unsigned i =1;i<arr.size();++i)
{
if (arr[i]==element)
{
count++;
}
else
{
count--;
if (count==0)
{
count = 1;
element = arr[i];
}
}
}
cout<<"数组中出现次数超过一半的元素是:"<<element<<endl;
return element;
}
//求数组中最短的距离
int minDistance(vector<int> arr)
{
cout<<endl<<"原始数组:";
printArry(arr);
sort(arr.begin(),arr.end());
int miniDist = arr[1]-arr[0];
for(unsigned i=1;i<arr.size();++i)
if (arr[i]-arr[i-1] < miniDist)
miniDist = arr[i]-arr[i-1];
cout<<"数组的最近的距离为:"<<miniDist<<endl;
return miniDist;
}
//两个有序数组的共同元素
void common(vector<int> & arr1,vector<int> & arr2)
{
cout<<endl<<"原始数组分别为:"<<endl;
printArry(arr1);
printArry(arr2);
cout<<"两个数组的共同元素为:"<<ends;
unsigned i = 0,j=0;
while(i<arr1.size() && j<arr2.size())
{
if (arr1[i]==arr2[j])
{
cout<<arr1[i]<<ends;
++i;
++j;
}
else if (arr1[i] < arr2[j])
++i;
else ++j;
}
cout<<endl;
}
//======================================??????解法有问题
//找出出现基数次的元素 ??若有多个元素出现奇数次??
int findOdd(vector<int> & arr)
{
cout<<endl<<"原始数组:";
printArry(arr);
int result = arr[0];
for (unsigned i=1;i<arr.size();++i)
{
result = result^arr[i];
}
cout<<"出现奇数次的元素为:"<<result<<endl;
return result;
}
//求数组中满足给定和的数对
void pairNum(vector<int> & arr1,vector<int> & arr2,int num)
{
cout<<endl<<"原始数组分别为:"<<endl;
printArry(arr1);
printArry(arr2);
cout<<"满足指定和的数对有: ";
unsigned i = 0;
int j = arr2.size()-1;
while (i<arr1.size() && j>=0)
{
if (arr1[i]+arr2[j] == num)
{
cout<<arr1[i++]<<","<<arr2[j--]<<ends<<ends;
}
else if (arr1[i]+arr2[j] < num)
{
++i;
}
else --j;
}
cout<<endl;
}
//连续最大和 ???如何求出这些连续的位置??
int maxAdd(vector<int> & arr)
{
cout<<endl<<"原始数组:";
printArry(arr);
int maxNum= arr[0];
int pos =0;
int currSum = 0;
int currPos = 0;
for (unsigned i=0;i<arr.size();++i)
{
currSum = currSum+arr[i];
if (currSum>=0)
{
/*maxNum = max(maxNum,currSum);*/
if (currSum > maxNum)
{
maxNum = currSum;
pos = currPos;
}
}
else
{
currSum=0;
currPos = i;
}
}
cout<<"数组的连续最大和为:"<<maxNum<<endl;
return maxNum;
}
//数组循环移位 两种方法:1 队列 2交换
void cycleArry(vector<int> & arr)
{
}
//数字组合 回溯
void Combine1(vector<int> & arr,int temp[],int k,int level)
{
int begin;
if (level ==0)
begin =0;
else
begin = temp[level-1]+1;
int end = arr.size() - k + level;
for (int i=begin;i<=end;++i)
{
temp[level] = i;
if (level == k-1)
{
for (int j=0;j < k;++j)
{
cout<<arr[temp[j]]<<",";
}
cout<<ends<<ends;
}
else
Combine1(arr,temp,k,level+1);
}
}
bool isvalid(int temp[],int level,int num)
{
for(int i=0;i<level;++i)
{
if (temp[i] >= num)
{
return false;
}
}
return true;
}
void Combine(vector<int> & arr,int temp[],int k,int level)
{
// int begin;
// if (level ==0)
// begin =0;
// else
// begin = temp[level-1]+1;
// int end = arr.size() - k + level;
for (unsigned i=0;i<arr.size();++i)
{
if (isvalid(temp,level,i))
{
temp[level] = i;
if (level == k-1)
{
for (int j=0;j < k;++j)
{
cout<<arr[temp[j]]<<",";
}
cout<<ends<<ends;
}
else
Combine(arr,temp,k,level+1);
}
}
}
void DfsCombine(vector<int> & arr,int k)
{
int * temp = new int[k];
int level =0;
Combine1(arr,temp,k,level);
}
//合并两个数组
void CombineVector(vector<int> & arr1,vector<int> & arr2,vector<int> & arr)
{
cout<<endl<<"原始数组分别为:"<<endl;
printArry(arr1);
printArry(arr2);
arr.resize(arr1.size()+arr2.size());
unsigned i=0,j=0;
int k=0;
while(i<arr1.size() && j < arr2.size())
{
if (arr1[i] <= arr2 [j])
arr[k++] = arr1[i++];
else
arr[k++] = arr2[j++];
}
while(i<arr1.size()) arr[k++] = arr1[i++];
while(j<arr2.size()) arr[k++] = arr2[j++];
cout<<"合并后的数组为:"<<ends;
printArry(arr);
}
//绝对值最小的元素 //二分法遇到连续相等的情况怎么办?
//通过二分法查找正负数分界点
void minAbs(vector<int> & arr,int &i,int &j)
{
if (j-i==1)
{
return ;
}
int middle = (i+j)/2;
if (arr[middle] >= 0)
{
j = middle;
}
else i = middle;
minAbs(arr,i,j);
}
void minAbs1(vector<int> & arr,int &i,int &j)
{
while((j-i)!=1)
{
int middle = (i+j)/2;
if (arr[middle] >= 0)
{
j = middle;
}
else i = middle;
}
}
int minAbs(vector<int> & arr)
{
cout<<endl<<"原始数组:";
printArry(arr);
if (arr[0]>=0)
{
cout<<"绝对值最小的元素是:"<<arr[0]<<endl;
return arr[0];
}
if (arr[arr.size()-1]<=0)
{
cout<<"绝对值最小的元素是:"<<arr[arr.size()-1]<<endl;
return arr[arr.size()-1];
}
int i=0;
int j = arr.size()-1;
minAbs(arr,i,j);
cout<<"绝对值最小的元素是:"<<min(-arr[i],arr[j])<<endl;
return min(-arr[i],arr[j]);
}
//二分查找是否含有某元素
bool binarySearch(vector<int> & arr,int k)
{
cout<<endl<<"原始数组为:"<<ends;
printArry(arr);
int i=0;
int j= arr.size()-1;
int flag =0;
while(i<=j)
{
int middle = (i+j)/2;
if (arr[middle] == k)
{
flag =1;
break;
//return true;
}
else if (arr[middle] < k)
{
i = middle+1;
}
else j = middle-1;
}
cout<<"次数组是否包含数字"<<k<<"? 答:"<<flag<<endl;
if (flag)
return true;
else return false;
}
//将数组重新排序,将数值为0的元素放到最前面,剩下的元素按原始顺序后移
void reSort(vector<int> & arr)
{
cout<<"原始数组:"<<ends;
printArry(arr);
cout<<"重排数组:"<<ends;
int i= arr.size()-1;
int j;
while(1)
{
while(i>=0 && arr[i])
--i;
if (i < 0)
break;
j = i;
while(j>=0 && !arr[j])
--j;
if (j<0)
break;
swap(arr[i],arr[j]);
--i;
}
printArry(arr);
}
//字符数组的翻转
void reverseArry(vector<char> & arr)
{
for (unsigned k=0;k<arr.size();++k)
{
cout<<arr[k]<<" ";
}
cout<<endl;
int i=0;
int j= arr.size()-1;
while(i<j)
{
swap(arr[i++],arr[j--]);
}
for (unsigned k=0;k<arr.size();++k)
{
cout<<arr[k]<<" ";
}
cout<<endl;
}
//语句的翻转
void reverseString(string & str,int fist,int end)
{
while(fist<end)
{
swap(str[fist++],str[end--]);
}
}
void reverseString(string & str)
{
cout<<"反转前:"<<str<<endl;
unsigned i=0,j=0;
while(j<str.size())
{
while(i<str.size() && str[i]==' ')
{
++i;
}
j = i;
while(j<str.size() && str[j]!=' ')
++j;
reverseString(str,i,j-1);
i=j;
}
reverseString(str,0,str.size()-1);
cout<<"翻转后:"<<str<<endl;
}
//最长公共子序列
int LCS(vector<int> & arr1,vector<int> & arr2)
{
unsigned m = arr1.size();
unsigned n = arr2.size();
vector<vector<int>> arr;
arr.resize(m+1);
for (unsigned i=0;i<m+1;++i)
{
arr[i].resize(n+1);
}
for (unsigned i=0;i<m+1;++i)
arr[i][0] =0;
for(unsigned j=0;j<n+1;++j)
arr[0][j] = 0;
for (unsigned i = 1;i< m+1; ++i)
{
for (unsigned j = 1;j < n+1; ++j)
{
if (arr1[i-1]==arr2[j-1])
{
arr[i][j] = arr[i-1][j-1]+1;
}
else
arr[i][j] = max(arr[i-1][j],arr[i][j-1]);
}
}
int result = arr[m][n];
cout<<"最长公共子序列长度为:"<<arr[m][n]<<endl;
cout<<"输出其中一个最长的公共子序列:"<<endl;
//如何使用回溯算法将全部情况输出?
vector<int> temp;
temp.resize(result);
while(m && n)
{
if (arr1[m-1]==arr2[n-1])
{
temp[--result] = arr1[m-1];
--m;
--n;
}
else if (arr[m-1][n] > arr[m][n-1])
{
--m;
}
else
--n;
}
for (unsigned k=0;k<temp.size();++k)
{
cout<<temp[k]<<" ";
}
cout<<endl;
return arr[m][n];
}
//最长公共子串
int LCSS(string & str1,string & str2)
{
//初始化
unsigned m = str1.size();
unsigned n = str2.size();
vector<vector<char>> arr;
arr.resize(m+1);
for (unsigned i =0;i<m+1;++i)
arr[i].resize(n+1);
for (unsigned i=0;i<m+1;++i)
arr[i][0] = 0;
for (unsigned i=0;i<n+1;++i)
arr[0][i] = 0;
//填充
for(unsigned i=1;i<m+1;++i)
{
for (unsigned j=1;j<n+1;++j)
{
if (str1[i-1]==str2[j-1])
{
arr[i][j] = arr[i-1][j-1]+1;
}
else arr[i][j] = 0;
}
}
//计算
int result = 0;
int pos =0;
for (unsigned i=1;i<n+1;++i)
{
if (result<arr[m][i])
{
result = arr[m][i];
pos = i;
}
}
vector<char> temp;
temp.resize(result);
int k = result;
while(k > 0)
{
temp[--k] = str2[--pos];
}
cout<<"两个字符串的最长公共子串长度为:"<<result<<endl;
cout<<"最长公共子串为:";
for (unsigned i=0;i<temp.size();++i)
{
cout<<temp[i];
}
cout<<endl;
return result;
}
//最长递增子序列
//0(n2) 写法
int LIS(vector<int> & arr)
{
int n = arr.size();
vector<int> lis;
lis.resize(n);//存储当前结点最长的递增子序列
//maxV.resize(n);//当前结点最长的递增子序列的最大值
for (int i=0;i<n;++i)
{
//maxV[i] = 1;
lis[i]=1;
}
//maxV[0] = arr[0];
for (int i=1;i<n;++i)
{
for(int j=0;j<i;++j)
{
if (arr[i]>arr[j] && lis[i]<=lis[j])
{
lis[i] = lis[j]+1;
}
}
}
//找最大值
int maxN = lis[0];
for (int i=1;i<n;++i)
{
if (lis[i]>maxN)
{
maxN = lis[i];
}
}
cout<<"最长递增子序列的长度为:"<<maxN<<endl;;
return maxN;
}
【笔试面试】数组相关问题
最新推荐文章于 2018-06-04 07:03:43 发布