數(shù)組求交集算法

數(shù)組求交集的方法
1.暴力搜索
2.利用HashMap
3.先排序再用兩個(gè)指針查找
4.位圖法
5.大文件求交集用分治法瞻离,組內(nèi)用位圖法

public class Main {
    /**
     * 暴力搜索
     * <p>
     * 時(shí)間復(fù)雜度O(n^2) 空間復(fù)雜度O(1)
     */
    static ArrayList<Integer> f0(int[] arr, int[] arr2) {
        Set<Integer> res = new HashSet<>();
        for (int i : arr) {
            for (int j : arr2) {
                if (i == j) {
                    res.add(i);
                }
            }
        }

        return new ArrayList<>(res);
    }

    /**
     * 利用HashMap
     * <p>
     * 時(shí)間復(fù)雜度O(n) 空間復(fù)雜度O(n)
     */
    static ArrayList<Integer> f1(int[] arr, int[] arr2) {
        Set<Integer> res = new HashSet<>();
        Map<Integer, Integer> map = new HashMap<>();
        for (int a : arr) {

            if (map.containsKey(a)) {
                map.put(a, (map.get(a) + 1));
            } else {
                map.put(a, 1);
            }
        }

        for (int a : arr2) {
            if (map.containsKey(a)) {
                res.add(a);
            }
        }

        return new ArrayList<>(res);
    }

    /**
     * 先排序再用兩個(gè)指針查找
     * <p>
     * 時(shí)間復(fù)雜度O(nlogn) 空間復(fù)雜度O(1)
     */
    static ArrayList<Integer> f2(int[] arr, int[] arr2) {
        Set<Integer> res = new HashSet<>();
        int p = 0, q = 0;
        Arrays.sort(arr);
        Arrays.sort(arr2);
        while (p < arr.length && q < arr2.length) {
            if (arr[p] < arr2[q]) {
                p++;
            } else if (arr2[q] < arr[p]) {
                q++;
            } else {
                res.add(arr[p]);
                p++;
                q++;
            }
        }

        return new ArrayList<>(res);
    }

    /**
     * 位圖法
     * 思路:
     * 假設(shè)數(shù)組a有m個(gè)元素,數(shù)組b有n個(gè)元素,并且滿足m<n
     * 1.建立一個(gè)int數(shù)組 extra 來表示bitmap, 一個(gè)int為32位,可以表示32個(gè)數(shù), 那么extra的元素個(gè)數(shù)為: Max(a)-Min(a) + 1
     * 2.將a中的元素映射到 extra 中的對(duì)應(yīng)位置,用1表示
     * 3.將b中的元素映射到 extra 中的對(duì)應(yīng)位置,如果該位置已經(jīng)是1融求,說明元素已經(jīng)存在,為重復(fù)元素算撮,記錄該元素
     * <p>
     * 時(shí)間復(fù)雜度O(n) 空間復(fù)雜度O(Max(a)-Min(a)/32)
     */
    static List<Integer> f3(int[] a, int[] b) {
        int min, max;
        int alen = a.length;
        int blen = b.length;
        int[] ps, pl;
        int len;
        int longlen;
        if (alen < blen) {
            ps = a;
            len = alen;
            longlen = blen;
            pl = b;
        } else {
            ps = b;
            len = blen;
            longlen = alen;
            pl = a;
        }
        min = max = ps[0];
        for (int i = 1; i < len; ++i) {
            if (ps[i] < min)
                min = ps[i];
            if (ps[i] > max)
                max = ps[i];
        }
        int gap = max - min;
        gap = gap / 32 + 1; //存儲(chǔ)差值要gap個(gè)int 類型的數(shù)
        int[] extra = new int[gap];
        for (int i = 0; i < gap; ++i) extra[i] = 0;
        int row, column;
        for (int i = 0; i < len; ++i) {
            //找到 ps[i] 在bitmap中位置, 用位運(yùn)算將該位置記為1
            row = (ps[i] - min) / 32;
            column = (ps[i] - min) % 32;
            extra[row] |= 1 << column;

        }
        Set<Integer> res = new HashSet<>();
        for (int i = 0; i < longlen; ++i) {
            //pl[i]如果超出ps元素的范圍生宛,肯定就不重復(fù)了,所以只關(guān)注ps數(shù)組最大最小值范圍內(nèi)的數(shù)
            if (pl[i] >= min && pl[i] <= max) {
                row = (pl[i] - min) / 32;
                column = (pl[i] - min) % 32;
                //如果該位置已經(jīng)是1肮柜,說明元素已經(jīng)存在陷舅,為重復(fù)元素,記錄該元素
                if (0 != (extra[row] & (1 << column))) {
                    res.add(pl[i]);
                }
            }
        }

        return new ArrayList<>(res);
    }
    
    public static void main(String[] args) {
        Random random = new Random();
        int m = 100000;
        int[] a = new int[m];
        while (m > 0) {
            a[m - 1] = random.nextInt(5000);
            m--;
        }
        int n = 100000;
        int[] b = new int[n];
        while (n > 0) {
            b[n - 1] = random.nextInt(5000);
            n--;
        }

        new Thread(() -> {
            long time = System.currentTimeMillis();
            System.out.println(f0(a, b));
            System.out.println("f0 cost: " + (System.currentTimeMillis() - time) + " ms");

        }).start();

        new Thread(() -> {
            long time = System.currentTimeMillis();
            System.out.println(f1(a, b));
            System.out.println("f1 cost: " + (System.currentTimeMillis() - time) + " ms");

        }).start();

        new Thread(() -> {
            long time = System.currentTimeMillis();
            System.out.println(f2(a, b));
            System.out.println("f2 cost: " + (System.currentTimeMillis() - time) + " ms");


        }).start();

        new Thread(() -> {
            long time = System.currentTimeMillis();
            System.out.println(f3(a, b));
            System.out.println("f3 cost: " + (System.currentTimeMillis() - time) + " ms");

        }).start();

    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末审洞,一起剝皮案震驚了整個(gè)濱河市莱睁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌预明,老刑警劉巖缩赛,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異撰糠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辩昆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門阅酪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事术辐⊙饩。” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵辉词,是天一觀的道長必孤。 經(jīng)常有香客問我,道長瑞躺,這世上最難降的妖魔是什么敷搪? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮幢哨,結(jié)果婚禮上赡勘,老公的妹妹穿的比我還像新娘。我一直安慰自己捞镰,他們只是感情好闸与,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著岸售,像睡著了一般践樱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凸丸,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天拷邢,我揣著相機(jī)與錄音,去河邊找鬼甲雅。 笑死解孙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抛人。 我是一名探鬼主播弛姜,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼妖枚!你這毒婦竟也來了廷臼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤绝页,失蹤者是張志新(化名)和其女友劉穎荠商,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體续誉,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡莱没,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了酷鸦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饰躲。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡牙咏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嘹裂,到底是詐尸還是另有隱情妄壶,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布寄狼,位于F島的核電站丁寄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏泊愧。R本人自食惡果不足惜伊磺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拼卵。 院中可真熱鬧奢浑,春花似錦、人聲如沸腋腮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽即寡。三九已至徊哑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聪富,已是汗流浹背莺丑。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留墩蔓,地道東北人梢莽。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像奸披,于是被迫代替她去往敵國和親昏名。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 一些概念 數(shù)據(jù)結(jié)構(gòu)就是研究數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)以及它們之間相互關(guān)系阵面,并對(duì)這種結(jié)構(gòu)定義相應(yīng)的運(yùn)算轻局,而且確保經(jīng)過這...
    Winterfell_Z閱讀 5,654評(píng)論 0 13
  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型。 運(yùn)用指針編程是C語言最主要的風(fēng)格之一样刷。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu)仑扑; ...
    朱森閱讀 3,424評(píng)論 3 44
  • 數(shù)組是最簡單的數(shù)據(jù)結(jié)構(gòu),占據(jù)連續(xù)內(nèi)存并且按順序存儲(chǔ)置鼻。 以下是與數(shù)組有關(guān)的算法題目镇饮。 (1)查詢數(shù)組中重復(fù)數(shù)字 算法...
    頑皮的石頭7788121閱讀 2,070評(píng)論 0 0
  • 1. 鏈表 鏈表是最基本的數(shù)據(jù)結(jié)構(gòu),面試官也常常用鏈表來考察面試者的基本能力箕母,而且鏈表相關(guān)的操作相對(duì)而言比較簡單盒让,...
    Mr希靈閱讀 1,430評(píng)論 0 20
  • 劍指offer線性數(shù)據(jù)結(jié)構(gòu) 劍指offer是找工作開始后刷的第一本書梅肤,刷題用潘臼撸客網(wǎng)邑茄。這本書可以說是已經(jīng)總結(jié)歸納的很...
    鍋鍋Iris閱讀 991評(píng)論 0 2