數(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 來(lái)表示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,說(shuō)明元素已經(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,說(shuō)明元素已經(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(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)過(guò)這...
    Winterfell_Z閱讀 6,612評(píng)論 0 13
  • 指針是C語(yǔ)言中廣泛使用的一種數(shù)據(jù)類型。 運(yùn)用指針編程是C語(yǔ)言最主要的風(fēng)格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu); ...
    朱森閱讀 3,619評(píng)論 3 44
  • 數(shù)組是最簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu),占據(jù)連續(xù)內(nèi)存并且按順序存儲(chǔ)。 以下是與數(shù)組有關(guān)的算法題目。 (1)查詢數(shù)組中重復(fù)數(shù)字 算法...
    頑皮的石頭7788121閱讀 2,189評(píng)論 0 0
  • 1. 鏈表 鏈表是最基本的數(shù)據(jù)結(jié)構(gòu),面試官也常常用鏈表來(lái)考察面試者的基本能力,而且鏈表相關(guān)的操作相對(duì)而言比較簡(jiǎn)單,...
    Mr希靈閱讀 1,589評(píng)論 0 20
  • 劍指offer線性數(shù)據(jù)結(jié)構(gòu) 劍指offer是找工作開(kāi)始后刷的第一本書(shū),刷題用??途W(wǎng)。這本書(shū)可以說(shuō)是已經(jīng)總結(jié)歸納的很...
    鍋鍋Iris閱讀 1,087評(píng)論 0 2

友情鏈接更多精彩內(nèi)容