最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關于C++數組中重復的數字

 更新時間:2021年11月03日 10:47:09   作者:zx255  
這篇文章主要介紹得是關于C++數組中重復的數字,文章以問題描述得形式,對問題展開分析用不同得方法去解決問題并附上方法得詳細代碼,需要的朋友可以參考以下文章得具體內容

1、題目描述

找出數組中重復的數字。在一個長度為 n 的數組 nums 里的所有數字都在 0~n-1 的范圍內。數組中某些數字是重復的,但不知道有幾個數字重復了,也不知道每個數字重復了幾次。

請找出數組中任意一個重復的數字。

題目示例:

  • 輸入:[2, 3, 1, 0, 2, 5, 3]
  • 輸出:2 或 3

1.1 方法一:排序

先對數組進行排序
此時從頭到尾掃一遍數組就可以了
時間復雜度 O ( l o g 2 n ) O(log_2n) O(log2​n)

代碼示例:

int repeatNum(vector<int>& v){
    if(v.empty()) return -1;
    int len = v.size();
    sort(v.begin(), v.end());
    for(int i = 1; i < len; i++){
        if(v[i] == v[i-1]){
            return v[i];
        }
    }
    return -1;
}

1.2 方法二:哈希表

  • 從頭到尾掃一遍數組
  • 每掃到一個數字,判斷哈希表里是否包含了該數字
  • 如果還沒有,就把它加入哈希表中
  • 如果已經存在該數字,就找到了一個重復的數字。

時間復雜度 O ( n ) O(n) O(n) 、空間復雜度 O ( n ) O(n) O(n) ,提高時間效率是以創(chuàng)建一個 O ( n ) O(n) O(n) 的哈希表為代價的。

代碼示例:

int repeatNum(vector<int>& v){
    if(v.empty()) return -1;
    map<int, int> m;
    for(int i = 0; i < v.size(); i++){
        if(m[v[i]]) return v[i];
        else m[v[i]]++;
    }
    return -1;
}

1.3 方法三:數組位置交換

  • 從頭到尾掃描數組
  • 當掃描的數組下標為 i 時,判斷i這個位置的數字 (m) 是否等于 i 本身
  • 若是則掃描下一個數字
  • 若不是則判斷 m 和 下標為 m 的數字是否相同 (v[i] == v[v[i]])
  • 若相同則返回,循環(huán)結束
  • 若不同則把第 i 個數字 (m) 和 第 m 個數字交換
  • 然后重復這個過程,直至循環(huán)結束

時間復雜度為 O ( n ) O(n) O(n) ,空間復雜度為 O ( 1 ) O(1) O(1)

代碼示例:

int repeatNum(vector<int>& v){
    if(v.empty()) return -1;
    for(int i = 0; i < v.size(); ++i){
        if(v[i] < 0 || v[i] > v.size()-1) // 數字必須在 0 ~ n-1 之間
            return -1;
    }
    
    for(int i = 0; i < v.size(); ++i){
        while(v[i] != i){
            if(v[i] == v[v[i]]) return v[i];
            swap(v[i], v[v[i]]);
        }
    }
    return false;
}

2、題目升級

長度為 n+1 的數組,所有的數都在 1 ~ n 的范圍內,因此數組中至少有一個數字是重復的。找出數組中 任意一個 重復的數字,但 不能修改輸入的數組。

題目示例:

  • 輸入:[2, 3, 5, 4, 3, 2, 6, 7]
  • 輸出:2 或 3

2.1 方法一:哈希表

方法同上:

int repeatNum(vector<int>& v){
    if(v.empty()) return -1;
    map<int, int> m;
    for(int i = 0; i < v.size(); i++){
        if(m[v[i]]) return v[i];
        else m[v[i]]++;
    }
    return -1;
}

2.2 方法二:輔助數組

  • 創(chuàng)建一個長度為 n+1 的輔助數組,然后逐一的把原數組的每個數字復制到輔助數組中
  • 若原數組中 被復制的數字 是 m,則把它復制到輔助數組中下標為 m 的位置

時間復雜度為 O ( n ) O(n) O(n) ,空間復雜度為 O ( n ) O(n) O(n)

代碼示例:

int repeatNum(vector<int>& v){
    int len = v.size();
    vector<int> v1(len);
    for(int i = 0; i < len; ++i){
        if(v1[v[i]]) return v1[v[i]];
        else v1[v[i]] = v[i];
    }
    return -1;
}

2.3 方法三:二分查找

將 1 ~ n 的數字從中間的數字 分成兩部分,即分成 1 ~ m m+1 ~ n

  • 若 1 ~ m 的數字,在整個數組上的數目超過 m,即超過該區(qū)間的長度,那么這一半的區(qū)間里一定包含重復的數字
  • 否則,另一半 m+1 ~ n 區(qū)間里一定包含重復的數字

繼續(xù)把包含重復數字的區(qū)間一分為二,直到找到一個重復的數字

時間復雜度為 O ( n l o g n ) O(nlog_n) O(nlogn​),空間復雜度為 O ( 1 ) O(1) O(1)

代碼示例:

int countRange(vector<int>& v, int sz, int start, int end){
    if(v.empty()) return 0;

    int count = 0;
    for(int i = 0; i < sz; ++i){
        if(v[i] >= start && v[i] <= end){
            ++count;
        }
    }
    return count;
}

int getrepeat(vector<int>& v){
    if(v.empty()) return -1;
    
    int sz = v.size();
    int start = 1, end = sz-1;
    while(end >= start){
        int mid = start + ((end-start)>>1);
        int count = countRange(v, sz, start, mid);
        if(end == start){
            if(count > 1) return start;
            else break;
        }
        if(count > (mid - start + 1)) end = mid;
        else start = mid + 1;
    }
    return -1;
}

測試代碼:

bool duplicate(vector<int>& v, int **res){
    if(v.empty()) return false;
    for(int i = 0; i < v.size(); ++i){
        if(v[i] < 0 || v[i] > v.size()-1) 
            return false;
    }
    
    for(int i = 0; i < v.size(); ++i){
        while(v[i] != i){
            if(v[i] == v[v[i]]) {
                *res = &v[i];
                return true;
            }
            swap(v[i], v[v[i]]);
        }
    }
    return false;
}

int main(){
    int arr[] = {2, 3, 5, 4, 3, 2, 6, 7};
    vector<int> v(arr, arr+8);  // 這種賦值方式不會導致vector自動擴展內部大小

    int* res = nullptr;
    if(duplicate(v, &res)) cout << *res << endl;
    else cout << '0' << endl;
    //cout << repeatNum(v) << endl;
    /*
    for(int i = 0; i < v.size(); i++){
        if(i == 0) cout << v[i];
        else cout << ' ' << v[i];
    }
    cout << endl;
    
    for(auto a : v){    // 有兩個警告(auto是C++_11的擴展)
        cout << a << ' ';
    }
    */
    return 0;
}

到此這篇關于關于C++數組中重復的數字的文章就介紹到這了,更多相關C++數組中重復數字內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

注:文章轉自微信眾號:Coder梁(ID:Coder_LT)

相關文章

  • C++深入了解模板的使用

    C++深入了解模板的使用

    這篇文章主要介紹了C++中模板(Template)的詳解及其作用介紹,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C++ Opencv自寫函數實現膨脹腐蝕處理技巧

    C++ Opencv自寫函數實現膨脹腐蝕處理技巧

    這篇文章主要介紹了C++ Opencv 自寫函數實現膨脹腐蝕處理,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10
  • C++繼承的定義與注意事項

    C++繼承的定義與注意事項

    這篇文章主要給大家介紹了關于C++繼承的定義與注意事項的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • C++?list容器merge算法的使用以及注意事項

    C++?list容器merge算法的使用以及注意事項

    這篇文章主要介紹了C++?list容器merge算法的使用以及注意事項,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Qt繪制圖表的實現

    Qt繪制圖表的實現

    Qt中提供了強大的2D繪圖系統(tǒng),可以使用同一API實現在屏幕和繪圖設備上進行繪制,本文就詳細的介紹了Qt繪制坐標圖、柱狀圖、折線圖、餅圖、曲線圖、散點圖等,感興趣的可以了解一下
    2021-05-05
  • C語言中輸入輸出流與緩沖區(qū)的深入講解

    C語言中輸入輸出流與緩沖區(qū)的深入講解

    一般情況下,由鍵盤輸入的字符并沒有直接送入程序,而是被存儲在一個緩沖區(qū)當中。下面這篇文章主要給大家介紹了關于C語言中輸入輸出流與緩沖區(qū)的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-09-09
  • C#和C++編程語言中的類淺析

    C#和C++編程語言中的類淺析

    在本篇文章里我們給大家分析了C#和C++編程語言中的類的相關知識點,正在學習的朋友們跟著操作下。
    2019-02-02
  • C++隨機生成迷宮算法

    C++隨機生成迷宮算法

    這篇文章主要為大家詳細介紹了C++隨機生成迷宮算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C++實現正態(tài)隨機分布的方法

    C++實現正態(tài)隨機分布的方法

    本篇介紹了,使用c++實現正態(tài)隨機分布的實現方法。需要的朋友參考下
    2013-05-05
  • 詳解Dijkstra算法原理及其C++實現

    詳解Dijkstra算法原理及其C++實現

    Dijkstra算法用于計算一個節(jié)點到其他節(jié)點的最短路徑。Dijkstra是一種按路徑長度遞增的順序逐步產生最短路徑的方法,是一種貪婪算法。本文將詳解Dijkstra算法原理及其C++實現,感興趣的可以了解一下
    2022-07-07

最新評論

乌拉特前旗| 赣榆县| 全南县| 昭通市| 拉孜县| 晴隆县| 卢湾区| 西充县| 璧山县| 南靖县| 洱源县| 尚义县| 泰州市| 当阳市| 大悟县| 海口市| 湾仔区| 连州市| 抚顺市| 岱山县| 浦江县| 兴山县| 商丘市| 神木县| 大荔县| 个旧市| 北海市| 都兰县| 浦县| 南漳县| 渑池县| 桑日县| 古丈县| 汝州市| 朝阳市| 黄大仙区| 五峰| 吴川市| 乌兰察布市| 武夷山市| 台安县|