【笔试面试】数组相关问题

来源:互联网 发布:马可波罗网络 编辑:程序博客网 时间:2024/04/30 16:09
//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;elsebegin = 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;}elseCombine1(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;}elseCombine(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++];elsearr[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;}elsearr[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;}


0 0
原创粉丝点击