整形int數組操作

1 給定兩個已經排序好的數組A,B,A足夠大,把兩個數組重新合併成A的有序數組

2 給定一個存放整數的數組,重新排列數組使得數組左邊爲奇數,右邊爲偶數 :空間複雜度是1,時間複雜度是n

3 找出數組裏大於等於左側、小於等於右側的所有數

4 給定 幾個數字,寫出來全排列 ,如1234


===============================================================================

1 給定兩個已經排序好的數組A,B,A足夠大,把兩個數組重新合併成A的有序數組

思路:

1 從最大(A和B的最後進行比較,把最大的元素放到最後面,之後--)

2 結束條件:只剩下A的元素了,或者只剩下B的元素之後複製到A的對應位置就可以了。


void printArray( int * arrA, int n )
{
    if(arrA==NULL||n<=0) return;
    cout<<endl;
    for(int i=0;i<n;i++)
    {
        cout<<arrA[i]<<" ";
    }
}


int * MergerArray( int *arrA,int sizeA,int *arrB,int sizeB )
{
    //第一種方法:從最後的一個元素開始比較,從後往前 移動元素。: 就地 進行排序
    if(arrA==NULL||arrB==NULL||sizeA<0||sizeB<0)
        return NULL;
    int posA=sizeA-1,posB=sizeB-1;    //posA+posB-1 爲當前的合併的元素的下標
    while(posA>=0&&posB>=0)
    {
        if(arrA[posA]>arrB[posB])
        {
            arrA[posA+posB+1]=arrA[posA];
            posA--;
        }
        else
        {
            arrA[posA+posB+1]=arrB[posB];
            posB--;
        }
    }
    //退出循環的兩種情況:1 只剩下arrA的元素(不用管了(posB<0)),2 只剩下arrB的元素(posA<0)
    while(posB>=0)
    {
        arrA[posA+posB+1]=arrB[posB];
        posB--;
    }
    /*copy(arrA, arrA + sizeA+sizeB-1, ostream_iterator<int>(cout, " ")); */
    printArray(arrA,sizeA+sizeB);
    return arrA;
}


測試代碼

int arrayA[10] = {11, 21, 25, 37, 49}; 
    int arrayB[] = {2, 4, 6, 28, 100}; 
    int sizeB = sizeof (arrayB) / sizeof *(arrayB); 
    int sizeA = sizeof (arrayA) / sizeof *(arrayA) - sizeB; 
    MergerArray(arrayA,sizeA,arrayB,sizeB);


2 給定一個存放整數的數組,重新排列數組使得數組左邊爲奇數,右邊爲偶數 :空間複雜度是1,時間複雜度是n


思路:其實就是 要求原地進行交換之類的-----每一趟(在while循環裏,成對出現low和high)

1 可以是兩頭標記(low標記偶數,high標記奇數,結束low=high

2 可以是 從頭開始標記(even標記偶數在前,odd標記奇數在後,之後交換,知道最後爲止)

測試代碼

int arr[]={1,2,3,4,5,11,6,7,8,9};
    int n=sizeof(arr)/sizeof(int);
    reArray(arr,n);



void reArray( int *arr,int n )
{
    ////方法1
    //printArray(arr,n);
    //int low=0,high=n-1;
    //while(low<high)                         //  while(low<=high)多交換一次:注意邊界條件    
    //{
    //  while(low<high&&arr[low]%2!=0)       //左邊找到偶數
    //  {
    //      low++;
    //  }
    //  while(low<high&&arr[high]%2==0)    //右邊找到奇數
    //  {
    //      high--;
    //  }
    //  swap(arr[low],arr[high]);
    //  printArray(arr,n);
    //}
    //printArray(arr,n);
    //方法2: todo:如果要求 偶數和奇數的相對位置不變,該怎麼辦???
    printArray(arr,n);
    int low=0,high=0;
    while(low<n&&high<n)
    {
        while(low<n&&arr[low]%2!=0)       //找到偶數
        {
            low++;
        }
        high=low;                         //要交換的奇數必須要在偶數的右邊 才符合情況。
        while(high<n&&arr[high]%2==0)     //找到奇數
        {
            high++;
        }
        if(low<n&&high<n)               //不判斷的話,可能會發生過界的情況 或者在上面的 判斷條件加上 low=n-1
        {
            swap(arr[low],arr[high]);
        }
        printArray(arr,n);
    }
    printArray(arr,n);
}

3 找出數組裏大於等於左側、小於等於右側的所有數

思路:提前對數組進行處理 leftmax,rightmin arr[i]與其進行比較

掃描一趟歸併: max[i] =max(max[i-1],arr[i]),對於初始化 max[0]=arr[0];


int array[] = {3, 1, 2, 5, 8, 6, 10,11};
const int size = sizeof array / sizeof *array;

//使用動態數組保存要 得到的結果(結果是幾個不知道)
void reArray2( int *arr,int n,vector<int> &result )
{
    //以空間 換時間:每一個i對應 leftmax[i]和rightmin[i]:一趟掃描最大值和最小值
    //對應的是:有 [i-1]推導出[i]
    printArray(arr,n);          //作爲測試來用的。
    int maxLeft[size];
    int minRight[size];
    maxLeft[0]=arr[0];
    minRight[n-1]=arr[n-1];
    for(int i=0;i<n;i++)
    {
        maxLeft[i]=maxLeft[i-1]>arr[i]?maxLeft[i-1]:arr[i];                    //max(maxLeft[i-1],arr[i])
    }
    for(int i=n-1;i>=1;i--)
    {
        minRight[i-1]=minRight[i]<arr[i-1]?minRight[i]:arr[i-1];               //min(minRight[i],arr[i-1])
    }
    for(int i=0;i<n;i++)
    {
        if(arr[i]>=maxLeft[i]&&arr[i]<=minRight[i])
        {
            /*cout<<arr[i]<<endl;*/
            result.push_back(arr[i]);
        }
    }
    copy(result.begin(), result.end(), ostream_iterator<int>(cout, " ")); 
}


4 給定 幾個數字,寫出來全排列 ,如1234

思路:全排列的問題:交換→遞歸→最次還原(交換)

還要繼續學習呀: STL系列之十 全排列(百度迅雷筆試題)


void Perm(int *array, int pos, int size )
{
    assert(array!=NULL);
    if(pos==size)
    {
        copy(array, array + size+1, ostream_iterator<int>(cout, " ")); 
        cout <<"本次全排列完畢!" <<endl; 
    }
    else
    {
        for(int i=pos;i<=size;i++)
        {
            //在這裏可以使用 if語句減少重複數值的判斷。if(arr[i]==arr[pos]比較是否相等)
            swap(array[i],array[pos]);
            Perm(array,pos+1,size);
            swap(array[i],array[pos]);
        }
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章