1. 程式人生 > >陣列中子陣列和為固定值的題目彙總

陣列中子陣列和為固定值的題目彙總

開頭附件一部分陣列去重的知識

unique函式是一個去重函式,去除相鄰中的重複元素(只留一個)。

其中,最關鍵的是:並不是刪除並不是把重複的元素刪除,而是全部放倒陣列的後面。

因為,unique只是去除(相鄰)的重複元素,因此,為了去除重複的元素,應該,首先對陣列/Vector進行排序,這樣保證重複元素在相鄰的位置。

unique函式,返回的是去重後的尾地址。

因此對於一個內容為{2, 2, 5, 5, 6}的vector,執行unique函式以後,vector大小並沒有改變,只不過順序變成了{2, 5, 6, 2, 5},並且函式的返回值為:3。

此時需要刪除重複元素,只需要將後面的資料全部刪除即可。

排序函式(sort)和去重函式都在<algorithm>標頭檔案中。

複製程式碼
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <vector>
 4 using namespace std;
 5 
 6 
 7 int main() {
 8     vector<int> v;
 9     cout << "Number of vector's element : " << endl;
10     int number;
11     cin >> number;
12     for (int i = 0; i < number; i++) {
13 int temp; 14 cin >> temp; 15 v.push_back(temp); 16 } 17 sort(v.begin(),v.end()); 18 v.erase(unique(v.begin(), v.end()), v.end()); 19 for (int i = 0; i < v.size(); i++) { 20 cout << v[i] << " "; 21 } 22 cout << endl;
23 return 0; 24 }
複製程式碼

unique()函式將重複的元素放到vector的尾部然後返回指向第一個重複元素的迭代器再用erase函式擦除從這個元素到最後元素的所有的元素

自己寫的去重函式!

int QuChong(int *nums, int len)
{
    sort(nums, nums + len);
    int i = 0, j = 0;
    for ( i = 0; i < len-1; i++)
    {
        while (nums[i] == nums[i + 1])
        {
            i++;
        }
        nums[j++] = nums[i];
    }
    return j;
}
 int main()
 {
     int nums[10] = { 1, 1,8,2, 3, 4, 5, 6, 7, 8 };
     cout << QuChong(nums,10) << endl;
     cout << unique(nums, nums + 10)-nums << endl;;
     system("pause");
     return 0;
 } 

題目表

1)輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,使得他們的和正好是S,如果有多對,輸出任意一對既可。

2)排序不重複的陣列求所有對數和為固定值sum的所有對數!

3)排序不重複的陣列求所有對數差值為固定值的所有對數!

3-1)給出n和k,然後給出n個數,求出數組裡面兩兩數的差為k有幾對,陣列排序及是否重複不限制。

4)輸入一個非遞增非排序的陣列(可能有重複數字)和一個數字S,在陣列中查詢兩個數,使得他們的和正好是S,如果有多對,輸出所有可能對數,不能重複。

5)輸入一個正數S,打印出所有和為S的連續正數序列,至少包含兩個數;例如輸入15,應該輸出(1,2,3,4,5)(4,5,6)(7,8)。

6)回溯法求陣列中和為定值的子陣列的組合!

7)求連續子陣列的最大和問題!

文章正式開始!!

1)輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,使得他們的和正好是S,如果有多對,輸出任意一對既可。

bool FindTwoNumsWithSum(int *nums, int sum, int len, vector<int> &res)
{
    bool found = false;
    if (len < 1 || nums == NULL)
        return found;
    int begin = 0, end = len - 1;
    while (begin < end)
    {
        long long cursum = nums[begin] + nums[end];
        if (cursum == sum)
        {
            res.push_back(nums[begin]);
            res.push_back(nums[end]);
            found = true;
            break;
        }
        if (cursum>sum)
        {
            end--;
        }
        else
            begin++;
    }
    return found;
}

 int main()
 {
     int nums[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
     int len = 8;
     int sum = 9;
     vector<int> res;
     FindTwoNumsWithSum(nums, sum, len, res);
     cout << res[0] << res[1] << endl;
    // MainFun(nums, len,  sum);
     system("pause");
     return 0;
 }

2)排序不重複的陣列求所有對數和為固定值sum的所有對數!

void dualSum(int arr[], int len, int sum)
{
    int low = 0;
    int high = len - 1;

    while (low<high)
    {
        while (arr[high] >= sum)
        {
            high--;
        }

        if (arr[low] + arr[high]>sum)
            high--;
        else if (arr[low] + arr[high]<sum)
            low++;
        else
        {
            cout << arr[low] << " + " << arr[high] << " = " << sum << endl;
            high--; low++;//僅僅是如果題目要求陣列沒有重複元素的時候才會成立!
        }
    }
}
int main()
{
    
    int arr2[] = { 1,2,3,4,5,6 };
    int len = 6;
    int sum = 7;

    dualSum(arr2, len, sum);


    system("pause");
    return 0;
}

3)排序不重複的陣列求所有對數差值為固定值的所有對數!

void dualSum(int arr[], int len, int k)
{
    int low = 0;
    int high = 0;

    while (low<len)
    {        
        if (arr[high] -arr[low]>k)
            low++;
        else if (arr[high] - arr[low]<k)
            high++;
        else
        {
            cout << arr[low] << " chavalue" << arr[high] << " = " << k << endl;
            high++;//僅僅是如果題目要求陣列沒有重複元素的時候才會成立!
        }
    }
}

int main()
{
    int arr[] = { 1, 3, 5, 7, 9, 10 };
    int len = 6;
    int k = 2;

    dualSum(arr, len, k);


    system("pause");
    return 0;

}

3-1)給出n和k,然後給出n個數,求出數組裡面兩兩數的差為k有幾對,陣列排序及是否重複不限制。

int NumChaValue(int * arr,int num, int k)
{
    multiset<int> all;
    for (int i = 0; i < num; i++)
    {
        all.insert(arr[i]);
    }
    multiset<int>::iterator ite = all.begin();
    int res = 0;
    for (; ite != all.end(); ite++)
    {
        if (all.count((*ite) + k)>0)
        {
            res += all.count((*ite) + k);
        }
    }
    return res;
}


int main() {
    int arr[] = {1,3,3,3 ,5};
    //cout << sizeof(arr) / sizeof(arr[0]) << endl;
    int num = sizeof(arr) / sizeof(arr[0]);
    int k = 2;
    cout << NumChaValue( arr,  num, k) << endl;
    system("pause");
    return 0;
}

4)輸入一個非遞增非排序的陣列(可能有重複數字)和一個數字S,在陣列中查詢兩個數,使得他們的和正好是S,如果有多對,輸出所有可能對數,不能重複。

方法一思路: 用N減去每個元素得到另一個數組b,巢狀迴圈找到a與b中值相同而位置不同的元素對;空間複雜度2N,時間複雜度O(N^2)。(時間複雜度較高,相當於暴力解法)

void CalcTwoSum(int *nums, int len, int sum, vector<vector<int>> &vec)
{
    int *numsB= new int[len];
    for (int i = 0; i < len; i++)
    {
        numsB[i] = sum - nums[i];
    }
    int index = 0;
    for (int i = 0; i < len; i++)
    {
        int find = numsB[i];
        for (int j = i + 1; j < len; j++)
        {
            if (nums[j] == find)
            {
                cout << numsB[i] << " + " << nums[i] << endl;
                vector<int> tmp;
                tmp.push_back(numsB[i]);
                tmp.push_back(nums[i]);
                vec.push_back(tmp);//注意vector<vector<int>>的賦值方法,不能像二維陣列那樣單獨賦值,需要建一個臨時vector<int>tmp來賦值處理!!
            }
                
        }
    }
}


int QuChong(int *nums, int len)
{
    sort(nums, nums + len);
    int i = 0, j = 0;
    for ( i = 0; i < len-1; i++)
    {
        while (nums[i] == nums[i + 1])
        {
            i++;
        }
        nums[j++] = nums[i];
    }
    return j;
}
 int main()
 {
     int nums[10] = { 1, 1,8,2, 3, 4, 5, 6, 7, 8 };
     int len = QuChong(nums, 10);
     int sum = 9;
     vector<vector<int>> vec;
     CalcTwoSum(nums, len, sum,vec);

     system("pause");
     return 0;
 }

5)輸入一個正數S,打印出所有和為S的連續正數序列,至少包含兩個數;例如輸入15,應該輸出(1,2,3,4,5)(4,5,6)(7,8)。

我的做法,好理解一些

void PrintContinuousSequence(int small, int big);

void FindContinuousSequence(int sum)
{
    if (sum < 3)
        return;

    int small = 1;
    int big = 2;
    int middle = (1 + sum) / 2;
    int curSum = small + big;

    while (small < middle)
    {
        if (curSum == sum)
        {
            PrintContinuousSequence(small, big);
            big++;
            curSum += big;//這個千萬不要漏掉,因為要求滿足和為sum的所有組合,否則就停掉了!

        }
        else if (curSum > sum)
        {
            curSum -= small;
            small++;
        }
        else
        {
            big++;
            curSum += big;
        }
        
    }
}

void PrintContinuousSequence(int small, int big)
{
    for (int i = small; i <= big; ++i)
        printf("%d ", i);

    printf("\n");
}
int main()
{

    FindContinuousSequence(15);


    system("pause");
    return 0;
}

劍指offer做法

void PrintContinuousSequence(int small, int big);

void FindContinuousSequence(int sum)
{
    if(sum < 3)
        return;

    int small = 1;
    int big = 2;
    int middle = (1 + sum) / 2;
    int curSum = small + big;

    while(small < middle)
    {
        if(curSum == sum)
            PrintContinuousSequence(small, big);

        while(curSum > sum && small < middle)
        {
            curSum -= small;
            small ++;

            if(curSum == sum)
                PrintContinuousSequence(small, big);
        }

        big ++;
        curSum += big;
    }
}

void PrintContinuousSequence(int small, int big)
{
    for(int i = small; i <= big; ++ i)
        printf("%d ", i);

    printf("\n");
}

6)回溯法求陣列中和為定值的子陣列的組合(方法2 感覺好理解一些)

方法1

void sumn(vector<int> &A, int start, int end, int sum, vector<int> &tmp, vector<vector<int>> &res);
void MainFun(int *nums, int len, int sum)
{
    vector<int> A;
    int start = 0,end=len-1;
    for (int i = 0; i < len; i++)
        A.push_back(nums[i]);
    vector<int> tmp;
    vector<vector<int>> res;
    sumn(A, start, end, sum, tmp, res);
    for (int i = 0; i < res.size(); i++)
    {
        for (unsigned int j = 0; j < res[i].size(); j++)
        {
            cout << res[i][j] << " ";
        }
        cout << endl;
    }
}


void sumn(vector<int> &A, int start, int end, int sum, vector<int> &tmp, vector<vector<int>> &res){
    if (start == end && sum == 0)
    {
        res.push_back(tmp);
    }
    else if (start == end)
        return;
    else
    {
        if (sum >= A[start])
        {
            tmp.push_back(A[start]);
            sumn(A, start + 1, end, sum - A[start], tmp, res);//求start後面和為sum - A[start]的組合
            tmp.pop_back();//需要將tmp臨時陣列恢復原樣
        }
        sumn(A, start + 1, end, sum, tmp, res);//依次遞增start求陣列後面除了含有start前面數字的子陣列組合。
    }
}

 int main()
 {
     int nums[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
     int len = 8;
     int sum = 15;
     MainFun(nums, len,  sum);
     system("pause");
     return 0;
 }

方法2

void Combination_helper(vector<int> array, int begin, int &current, int target, vector<int>&path)
{
    if (begin >= array.size())
        return;
    current += array[begin];
    path.push_back(array[begin]);
    if (current == target)
    {
        for (int i = 0; i < path.size(); i++)
            cout << path[i] << ' ';
        cout << endl;
    }
    Combination_helper(array, begin + 1, current, target, path);
    path.pop_back();
    current -= array[begin];

    /*
    int j;
    for (j = begin + 1; j < array.size();)
    {
        if (array[j] == array[begin])
            j++;
        else
            break;
    }
    *///這個是去掉重複值的作用,看看要求裡面有沒有去重的題目要求
    Combination_helper(array, begin+1, current, target, path);

}
int main()
{
    vector<int>array({ 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7 });
    //vector<int>array({ 1, 2, 3});
    vector<int>path;
    int current = 0;
    Combination_helper(array, 0, current, 10, path);
    system("pause");
    return 0;

}

7)求連續子陣列的最大和問題(劍指offer T31)並且輸出這個最大的子陣列ResMaxInt

int maxSubInt(int arr[], int length, vector<int> &ResMaxInt)
{
    if (NULL == arr || length <= 0)
        return 0;
    int TmpSum = 0;
    vector<int> TmpMaxInt;
    int ResSum = 0;
    for (int i = 0; i < length; i++)
    {
        if (TmpSum <= 0)
        {
            TmpSum = arr[i];
            vector<int> TmporaryMaxInt;
            TmporaryMaxInt.push_back(arr[i]);
            TmpMaxInt = TmporaryMaxInt;
        }
        else
        {
            TmpSum += arr[i];
            TmpMaxInt.push_back(arr[i]);
        }
        if (TmpSum>ResSum)
        {
            ResSum = TmpSum;
            ResMaxInt = TmpMaxInt;
        }
    }
    return ResSum;
}
int main() {
    int arr[] = { 1, -2, 3, 10, -4, 7, 2, -5 };
    int length = sizeof(arr) / sizeof(arr[0]);
    vector<int> ResMaxInt;
    cout << maxSubInt(arr,  length, ResMaxInt) << endl;
    system("pause");
    return 0;
}

相關推薦

陣列中子陣列固定題目彙總

開頭附件一部分陣列去重的知識unique函式是一個去重函式,去除相鄰中的重複元素(只留一個)。其中,最關鍵的是:並不是刪除並不是把重複的元素刪除,而是全部放倒陣列的後面。因為,unique只是去除(相鄰)的重複元素,因此,為了去除重複的元素,應該,首先對陣列/Vector進行

程式設計師面試一百題-10-在排序陣列中查詢給定的兩個數字

1-題目 : 輸入一個已經按升序排序過的陣列和一個數字,在陣列中查詢兩個數,使得它們的和正好是輸入的那個數字;要求時間複雜度是O(n);如果有多對數字的和等於輸入的數字,輸出任意一對即可。 2-示例 : 輸入 : 1、2、4、7、11、15和15 輸出 : 4、11 3-思路 :

8.9 不重複列印排序陣列中相加給定的所有二元組三元組

【題目】:   給定排序陣列arr和整數k,不重複列印arr中所有相加和為k的不降序二元組   例如:     arr=[-8, -4, -3, 0, 1, 2, 4, 5, 8, 9],k=10,列印結果為:     1,9     2,8   【補充題目】:   給定排序陣列ar

未排序陣列中累加給定的系列問題

題目一:Zero Sum Subarray 給定一整形陣列,返回序列和為0的子陣列的起始和結束下標。 比如:int[] array={-3,1,2,-3,4};   返回(0,2)和(1,3)。 題解:使用hashmap儲存陣列中從0開始到索引i的子段和,在將值push進m

陣列兩個數指定陣列下標

散列表方式: public void findBathIndex(int[] arr,int k){ if(arr==null){ return;

未排序陣列中累加給定的最長子陣列系列問題

牛客網左程雲第二課第三題,這是一個很重要的演算法原型。 問題:給定一個無序陣列 arr,其中元素可正、可負、可 0,給定一個整數 k。求 arr 所有的子陣列中累加和為 k 的最長子陣列長度。  要求:時間複雜度 O(N) 分析:本題和未排序正數陣列中累加和為給定值的最長子

未排序陣列中累加給定的最長子陣列

題目給定一個無序陣列arr,其中元素可正,可負,可0,給定一個整數k。求arr所有的子陣列中累加和為k的最長子陣列長度。分析為了解答題目,引入一個概念,s(i)代表子陣列arr[0..i]所有元素的累加和。那麼子陣列arr[j-1, i](0<=j<=i<a

每日一練——從長度n的數組裡選出m個數使固定sum

這個問題是我從leetcode上一道問題所想到的,原題:如果是從陣列中選出2個數相加使之成為固定的數sum,這當然很簡單,把陣列中的數字遍歷一遍,判斷另一個數字是否也在陣列中即可。程式碼如下。

題目三:給定一個數組,可以正、負0,請返回累加給定k的最長子陣列長度。

import java.util.HashMap; /** * * 2、給定一個數組,值可以為正、負和0,請返回累加和為給定值k的最長子陣列長度。 * 咱們可以反推,比如:1- 100,陣列和為1000. * 要求最長和為300的子陣列,我可以反著求第一

Three Sum(找出陣列中,所有三個數字的組合,其給定的情況)

import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Three Sum * * Given an array S of n integ

回溯法求解陣列中和固定的所有元素集合

一、前言        本文參考自http://blog.csdn.net/u012462822/article/details/51193689,找出陣列中和為固定值的所有元素集合,常用的思路是先進行排序,之後再用回溯的方法不斷嘗試所有可能集合。以下先用快速排序(寫得有點

陣列------的多個數

題目描述; 給定兩個整數sum和n,要求在1, 2, 3, …, n中找到所有和為sum的組合. eg: sum = 6, n = 6 1 2 3 4 5 6

在給定的陣列中找出兩個元素給定的所有元素對

Design an algorithm to find all pairs of integers within an array which sum to a specified value.  使用hash map: 1假設V為給定的值,A為給定的陣列。 2建立has

從給定陣列中選取任意個數(可重複),使其給定

回溯法練習:從給定有序陣列中選取任意個數(可重複),使其和為給定值(leetcode39):Example 1:Input: candidates = [2,3,6,7], target = 7A solution set is: [ [7], [2,2,3] ]思路

c++ 找陣列中兩個元素,其等於固定sum,並輸出

週二去中興面試的,筆試題做的是選擇填空,加一道程式設計題。 程式設計題求得是陣列中兩個元素,求和等於固定值sum。 這題最簡單的方法當然是採用雙重迴圈,進行遍歷。但是這種方法的效率無疑是比較低的。複雜度是O(n^2)。 所以我就從另外一個角度進行分析:1. 先對陣列進行排序

Java 列舉陣列中任意元素的組合

import java.util.Arrays; /** * 列舉陣列中任意元素和為定值的組合 */ public class SolveProb { // Arrays.sort(arr); static int[] flag = new int[1

【演算法題】找到陣列中和固定的兩個元素

在閱讀的過程中有任何問題,歡迎一起交流 QQ:1494713801 題目:編寫一個函式,輸入為一個int型的陣列numbers和一個int型變數target,找到這個陣列中和為target的兩個元素,輸出其index。 假設每組輸入有且僅有一組輸出 示例: Input

指定整數陣列中輸出一整數的所有組合

題目:編寫一個函式,在陣列a[10] = {1,3,5,7,9,11,13,15,17}中輸出和為25的所有整數組合 思想:遞迴,探底一種情況後返回前一種狀態。 程式碼: #include <stdio.h> #include <string.h>

在0~N個數字中,取指定個數的不重復數字,要求這些數字的指定,求所有結果

readline tco write span count string rgs logs index 1 using System; 2 using System.Collections.Generic; 3 using System.Linq;

編程之法:面試算法心得(尋找的多個數)

arch 全部 col static 多個 ++ som ava sta 內容全部來自編程之法:面試和算法心得一書,實現是自己寫的使用的是java 題目描述 輸入兩個整數n和sum,從數列1,2,3.......n 中隨意取幾個數,使其和等於sum,要求將其中所有的可能組合