資料結構與演算法(3)
阿新 • • 發佈:2019-02-20
1.把只包含質因子2、3和5的數稱作醜數(Ugly Number)。例如6、8都是醜數,但14不是,因為它包含質因子7。 習慣上我們把1當做是第一個醜數。求按從小到大的順序的第N個醜數。(建立一個數組,順序構建醜數,三個索引號)
class Solution { public: int GetUglyNumber_Solution(int index) { if(index<7) return index; vector<int> res; int t2=0,t3=0,t5=0; //res[0]=1; res.push_back(1); for(int i=1;i<index;i++) { res.push_back(res[t2]*2<res[t3]*3?(res[t2]*2<res[t5]*5?res[t2]*2:res[t5]*5):(res[t3]*3<res[t5]*5?res[t3]*3:res[t5]*5)); //res[i]=res[t2]*2<res[t3]*3?(res[t2]*2<res[t5]*5?res[t2]*2:res[t5]*5):(res[t3]*3<res[t5]*5?res[t3]*3:res[t5]*5); if(res[i]==res[t2]*2) t2++; if(res[i]==res[t3]*3) t3++; if(res[i]==res[t5]*5) t5++; } return res[index-1]; } };
2.一個整型數組裡除了兩個數字之外,其他的數字都出現了偶數次。請寫程式找出這兩個只出現一次的數字。(異或相同相消除,0和任何數異或還是那個數)
class Solution { public: void FindNumsAppearOnce(vector<int> data,int* num1,int* num2) { if(data.size() < 2) return; int resultExclusiveOR = 0; for(int i = 0; i < data.size(); i++){ resultExclusiveOR ^= data[i]; } unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR); *num1 = *num2 = 0; for(int j = 0; j < data.size(); j++){ if(IsBit1(data[j], indexOf1)) *num1 ^= data[j]; else *num2 ^= data[j]; } } unsigned int FindFirstBitIs1(int num){ int indexBit = 0; while(((num & 1) == 0) && (indexBit < 8*sizeof(int))){ num = num >> 1; indexBit++; } return indexBit; } bool IsBit1(int num, unsigned int indexBit){ num = num >> indexBit; return (num&1); } };
3.輸入兩個連結串列,找出它們的第一個公共結點。
class Solution { public: ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { ListNode *p1=pHead1; ListNode *p2=pHead2; int len1=0,len2=0,diff=0; while(p1!=NULL){ p1=p1->next; len1++; } while(p2!=NULL){ p2=p2->next; len2++; } if(len1>len2){ diff=len1-len2; p1=pHead1; p2=pHead2; } else{ diff=len2-len1; p1=pHead2; p2=pHead1; } for(int i=0;i<diff;i++){ p1=p1->next; } while(p1!=NULL && p2!=NULL){ if(p1==p2) break; p1=p1->next; p2=p2->next; } return p1; } };
4.在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007。(歸併排序思想)
class Solution {
public:
int InversePairs(vector<int> data) {
if(data.size()==0)
return 0;
long long res;
vector<int> copy;
for(auto num:data){
copy.push_back(num);
}
int length=data.size();
res=InversePairs(data,copy,0,length-1);
return res%1000000007;
}
long long InversePairs(vector<int>& data,vector<int>& copy,int begin,int end){
if(begin==end){
copy[begin]=data[begin];
return 0;
}
int length=(end-begin)>>2;
long long left=InversePairs(copy,data,begin,begin+length);
long long right=InversePairs(copy,data,begin+length+1,end);
int i=begin+length;
int j=end;
int copyIndex=end;
long long count=0;
while(i>=begin&&j>=(begin+length+1)){
if(data[i]>data[j]){
copy[copyIndex--]=data[i--];
count+=j-begin-length;
}
else
copy[copyIndex--]=data[j--];
}
for(;i>=begin;i--)copy[copyIndex--]=data[i];
for(;j>=begin+length+1;j--)copy[copyIndex--]=data[j];
return left+right+count;
}
};
5.輸出所有和為S的連續正數序列。序列內按照從小至大的順序,序列間按照開始數字從小到大的順序.(秒解)
class Solution {
public:
vector<vector<int> > FindContinuousSequence(int sum) {
vector<vector<int>> v;
if(sum<=2)
return v;
int mid=sum/2;
for(int i=1;i<=mid+1;i++)
{
vector<int> arr;
int tmp=0;
for(int j=i;tmp<sum;j++)
{
tmp+=j;
arr.push_back(j);
}
if(tmp==sum)
v.push_back(arr);
}
return v;
}
};