日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

java - 算法問題,2個數組,數組a保存1000W條手機號,數組b保存5000W條,找出兩個數組相同的手機號,執行時間需要 <2s

瀏覽:201日期:2024-01-17 18:49:46

問題描述

有人說用歸并算法,但是執行下來時間遠遠不止2s。在下實在想不出還有什么好辦法,希望各位能給個提示或者解法,謝謝。

下面是我的測試代碼:

public class TestA { public static void main(String[] args) {long[] a = new long[50000000];long num = 13000000000l;for (int i = 0; i < a.length; i++) { a[i] = (num + i);}long[] b = new long[10000000];long num2 = 14000000000l;for (int i = 0; i < b.length - 2; i++) { b[i] = (num2 + i);}b[9999999] = 13000000000l;b[9999998] = 13000000001l;long[] c = new long[a.length+b.length];long start = System.currentTimeMillis();for (int i = 0; i < a.length; i++) { c[i] = a[i];}for (int i = 0; i < b.length; i++) { c[i + a.length] = b[i];}System.out.println('start');sort(c, 0, c.length-1);long end = System.nanoTime();System.out.println(System.currentTimeMillis() - start);for (int i = 0; i < c.length; i++) {System.out.println(c[i]);} } public static void sort(long[] data, int left, int right) {if (left < right) { // 找出中間索引 int center = (left + right) / 2; // 對左邊數組進行遞歸 sort(data, left, center); // 對右邊數組進行遞歸 sort(data, center + 1, right); // 合并 merge(data, left, center, right);} } public static void merge(long[] data, int left, int center, int right) {long[] tmpArr = new long[data.length];int mid = center + 1;// third記錄中間數組的索引int third = left;int tmp = left;while (left <= center && mid <= right) { // 從兩個數組中取出最小的放入中間數組 if (data[left] <= data[mid]) {if(data[left] == data[mid]){ System.out.println(data[left]);}tmpArr[third++] = data[left++]; } else {tmpArr[third++] = data[mid++]; }}// 剩余部分依次放入中間數組while (mid <= right) { tmpArr[third++] = data[mid++];}while (left <= center) { tmpArr[third++] = data[left++];}// 將中間數組中的內容復制回原數組while (tmp <= right) { data[tmp] = tmpArr[tmp++];} }}

問題解答

回答1:

提供一個思路,我們要找的是兩個數組里相同的電話號碼。那么我們把第一個數組的電話號碼建立一顆 字典樹。在第二個的時候直接在 字典樹 里查找即可。總體是一個 O(N * 11) = O(N) 的復雜度。每個電話號碼 11 位的話。總的只是一個 O(N) 的復雜度。參考知乎:https://zhuanlan.zhihu.com/p/...

public class TrieTree { private class Node {char ch;TreeMap<Character, Node> node;int count;public Node(char ch) { ch = this.ch; node = new TreeMap<>(); count = 0;} } public class StringCount implements Comparable{public String str;public int count;public StringCount(String str, int count) { this.str = str; this.count = count;}@Overridepublic int compareTo(Object o) { StringCount t = (StringCount) o; if(this.count > t.count){return -1; } if(this.count < t.count){return 1; } return 0;} } private int indexStringCount; private StringCount[] stringCounts; private Node root; private int size; private static boolean DEBUG = true;public TrieTree() {root = new Node(’$’);size = 0; } public int insert(String str) {int res = 0;Node temp = root;for (int i = 0; i < str.length(); i++) { char ch = str.charAt(i); if (temp.node.get(ch) == null) temp.node.put(ch, new Node(ch)); temp = temp.node.get(ch);}if(temp.count == 0) size ++;res = ++temp.count;return res; }public StringCount[] getStringCount(){indexStringCount = 0;stringCounts = new StringCount[this.size];ergodic(root, '');Arrays.sort(stringCounts);{ for(StringCount s : stringCounts){System.out.println(s.str + ' ' + s.count); }}return stringCounts; } private void ergodic(Node foo, String str){if(foo.count != 0){ stringCounts[indexStringCount ++] = new StringCount(str, foo.count);}for(Character ch:foo.node.keySet()){ ergodic(foo.node.get(ch), str + ch);} }private void show(Node foo, String str) {if (foo.count != 0) { System.out.println(str + ' : ' + foo.count);}for(Character ch:foo.node.keySet()){ show(foo.node.get(ch), str + ch);} } public void showALL() {show(root, ''); } public int size(){return size; }public static void main(String[] args) {TrieTree tree = new TrieTree();String[] strs = { 'a', 'aa', 'a', 'b', 'aab', 'bba' };for (int i = 0; i < strs.length; i++) { tree.insert(strs[i]);}tree.showALL();System.out.println(tree.size);tree.getStringCount(); }}回答2:

剛剛找到一種方法,執行時間大概在2s左右:

public class TestB { static long count; public static void main(String[] args) {long[] a = new long[50000000];long num = 13000000000l;for (int i = 0; i < a.length; i++) { a[i] = num + i;}long[] b = new long[10000000];long num2 = 14000000000l;for (int i = 0; i < b.length - 3; i++) { b[i] = num2 + i;}b[9999999] = 13000000000l;b[9999998] = 13000000002l;b[9999997] = 13000000002l;long start = System.currentTimeMillis(); Arrays.sort(a);int flag = -1;for (int i = 0; i < b.length; i++) { count = b[i]; flag = Arrays.binarySearch(a, count); if (flag <= 50000000 && flag >= 0) {System.out.println(count + ' ' +flag); }}System.out.println(System.currentTimeMillis() - start); }}

這個方法主要思想是先排序,再使用 Arrays.binarySearch()方法進行二分法查詢,返回匹配的數組下標。

修改了一下獲取數據源的方法,發現如果使用隨機數據源,耗費的時間是8s左右,誤差時間主要消耗在sort()排序方法上,數據源的規律還是影響排序算法的時間復雜度的。代碼修改如下:

public class TestB {

static long count;public static void main(String[] args) { System.out.println(random()); long[] a = new long[50000000]; for (int i = 0; i < a.length; i++) {a[i] = random(); } long[] b = new long[10000000]; for (int i = 0; i < b.length; i++) {b[i] = random(); } long start = System.currentTimeMillis(); Arrays.sort(b); Arrays.sort(a); int flag = -1; int cc =0; for (int i = 0; i < b.length; i++) {count = b[i];flag = Arrays.binarySearch(a, count);if (flag <= 50000000 && flag >= 0) { System.out.println(count + ' ' + flag); cc++;} } System.out.println('相同數據的數量:'+cc); System.out.println(System.currentTimeMillis() - start);}public static long random() { return Math.round((new Random()).nextDouble()*10000000000L+10000000000L);}

}

回答3:

考慮bitmap, 參考https://github.com/RoaringBit...RoaringBitmap aBM = new RoaringBitmap()for (int i = 0; i < a.length; i++) {

aBM.add(a[i])

}...RoaringBitmap interactionBM = RoaringBitmap.and(aBM, bBM)for (int item: interactionBM) {

System.out.println(item)

}

回答4:

long start = System.currentTimeMillis();HashSet<Long> alongs = new HashSet<>();for (long l : b) { alongs.add(l);}ArrayList<Long> sames = new ArrayList<>();for (long l : a) { if (alongs.contains(l)) {sames.add(l); }}long end = System.currentTimeMillis();System.out.println(end - start);

使用上述代碼,在我的機器上,是8s

回答5:

http://tieba.baidu.com/p/3866...

回答6:

C#, 本地運行,release,611ms

long[] a = new long[50000000];long num = 13000000000L;for (int i = 0; i < a.Length; i++){ a[i] = (num + i);}long[] b = new long[10000000];long num2 = 14000000000L;for (int i = 0; i < b.Length - 2; i++){ b[i] = (num2 + i);}b[9999999] = 13000000000L;b[9999998] = 13000000001L;var hashSetB = new HashSet<long>(b);var matches = new List<long>();var timer = new System.Diagnostics.Stopwatch();Console.WriteLine('Starts...');timer.Start();for (var i = 0; i < a.Length; i++){ if (hashSetB.Contains(a[i])) {matches.Add(a[i]); }}timer.Stop();Console.WriteLine(timer.ElapsedMilliseconds);Console.WriteLine('Found match: ' + string.Join(', ', matches));Console.ReadLine();回答7:

redis SINTER(返回一個集合的全部成員,該集合是所有給定集合的交集。)

回答8:

如果說這個操作只能在數組中進行的話,沒什么取巧的辦法,至少要遍歷較小的那個數組,甚至排序都是免不了的。而如果可以將數組內容導出到其他數據結構的話,又貌似有違題目初衷的嫌疑。出題者是不是想考驗數組操作呢?

回答9:

來一種更簡單的方法,在MBP上只要200ms左右。普通的Pentium G2020也只要250ms額,這種算法完全不行,回答10:

這題目其實算法是關鍵。建議大家看一下編程珠璣的第一章。會提供很好的思路。首先問題必須細化一下,就是手機號必須只有中國的手機號嗎。否則數量會多很多。我簡單說一下編程珠璣里是怎樣存儲電話號碼的。他是只使用一個二進制的數字來存儲所有的手機號碼。一個二進制的數位可以很長很長。長度就等于最大的可能的那個電話號碼。比如說13999999999,其實13可以省掉,我們的這個數字就是999999999位的一個二進制數。在每一位上,如果有這個電話號碼,就標記為1,如果沒有就標記為0.為了簡單起見,我就假設手機號的范圍是0-9,我們先準備一個10位的二進制數0000000000.假設第一個數組有3個電話號碼,分別是1,5,7,那么存儲這個數組的二進制數就是0010100010,這個數字的1,5,7位上是1,其他位是0。假設第二個數組有6個電話號碼,分別是1,2,3,4,7,8那么存儲這個數組的二進制數就是0110011110,這個數字的1,2,3,4,7,8位上是1,其他位是0。那么如何找出這兩個數組中相同的電話呢?只需要做一下位運算中“按位與”(AND)的操作即可,同一位上兩個都是1的,還是1,只要有一個是0的,就是0。0010100010 & 0110011110 = 0010000010

一下就找出來是第1位和第7位上是1的一個二進制數。

標簽: java
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
婷婷精品在线| 国产欧美另类| 亚洲不卡视频| 亚洲一区网站| 伊人久久成人| 亚洲精品一二三区区别| 国产一区一一区高清不卡| 久久精品99国产精品日本| 麻豆精品网站| 麻豆久久精品| 免费观看在线综合色| 国产亚洲福利| 久久国产高清| 蜜臀a∨国产成人精品| 石原莉奈在线亚洲二区| 男女男精品视频网| 玖玖玖国产精品| 亚洲尤物av| 日韩专区视频网站| 男人的天堂久久精品| 综合欧美亚洲| 欧美综合二区| 国产精品美女| 亚洲精品看片| 国产精品分类| 国产不卡人人| 欧美中文一区二区| 视频一区二区中文字幕| 日韩超碰人人爽人人做人人添| 国产日韩欧美三区| 成人在线观看免费视频| 久久蜜桃资源一区二区老牛| 99热国内精品| 国产视频一区免费看| 国产一区二区高清| 亚洲少妇诱惑| 日本不卡不码高清免费观看| 亚洲开心激情| 国产精品777777在线播放| 国产一区二区三区探花| 久久精品欧洲| 国产成人精品一区二区免费看京| 国产成人久久精品一区二区三区| 久久精品一区二区不卡| 国产毛片久久| 日日夜夜免费精品视频| 国产黄色精品| 91精品在线观看国产| 丝袜诱惑制服诱惑色一区在线观看| 亚洲我射av| 久久国产精品免费精品3p| 精品国产欧美日韩| 激情视频网站在线播放色| 尤物精品在线| 日韩高清不卡在线| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 九九综合九九| 亚洲精品三级| 国产一区二区三区不卡av| 国产aa精品| 免费精品视频| 国产欧美一区二区三区国产幕精品 | 玖玖玖国产精品| 欧美片网站免费| 青青青免费在线视频| 视频在线观看91| 久久超级碰碰| 久久uomeier| 免播放器亚洲一区| 97在线精品| 蜜桃久久久久久| 久久一区二区中文字幕| 四虎国产精品免费观看| 国产精品一区二区免费福利视频| 香蕉成人久久| 红桃视频国产一区| 久久中文字幕二区| 日本在线高清| 国产精品久久久久久久久妇女| 国产视频一区二| 日韩欧美美女在线观看| 午夜久久一区| 激情欧美日韩一区| 伊人久久视频| zzzwww在线看片免费| 麻豆精品在线观看| 国产精品一区二区三区美女 | 日韩午夜免费| 激情欧美亚洲| 99精品电影| 日本在线精品| 成人日韩精品| 日韩另类视频| 国产亚洲一区二区手机在线观看| 在线人成日本视频| 成人三级高清视频在线看| 精品国产黄a∨片高清在线| 国产精品三级| 精品一区二区三区免费看 | 亚洲一区二区三区免费在线观看| 91久久久久| 免费久久99精品国产| 99国产一区| 亚洲aⅴ网站| 国产乱码精品一区二区三区四区 | 国产精品腿扒开做爽爽爽挤奶网站| 在线亚洲自拍| 亚洲v天堂v手机在线| 国产午夜久久av| 久久三级中文| 久久久久美女| 亚洲免费影视| 日韩和欧美一区二区| 国产探花一区二区| 捆绑调教美女网站视频一区| 亚洲国产福利| 欧美日韩视频| 免费看黄色91| 国产精品视频一区视频二区| 国产成人精品免费视| 欧美综合另类| 日韩中文字幕无砖| 精品伊人久久| 999精品色在线播放| 亚洲丝袜美腿一区| 麻豆91精品91久久久的内涵| 91精品精品| 日本在线不卡视频| 国产高清视频一区二区| 91精品韩国| 亚洲精品一二| 捆绑调教日本一区二区三区| 久久高清国产| 鲁大师精品99久久久| 久久亚洲国产| 日本成人在线视频网站| 日韩美女一区二区三区在线观看| 久久福利影视| 麻豆久久久久久| 国产一区二区精品| 久久成人高清| 91久久视频| 久久精品三级| 亚洲一区日韩在线| 精品亚洲自拍| 巨乳诱惑日韩免费av| 精品久久免费| 日韩中文欧美在线| 高清一区二区三区av| 亚洲精品午夜av福利久久蜜桃| 91成人精品观看| 久久精品在线| 欧美一区免费| 欧美日韩少妇| 久久精品一本| 日韩精品一二三| 欧美精品日日操| 日韩av在线播放中文字幕| 99国产精品一区二区| 91精品在线免费视频| 欧美在线网站| 中文在线а√在线8| 91精品国产自产精品男人的天堂| 婷婷精品视频| 黄色欧美在线| 欧美在线看片| av不卡在线看| 久久国产日韩| 国产aⅴ精品一区二区三区久久| 亚洲精品亚洲人成在线观看| 中文字幕一区久| 麻豆精品在线观看| 蜜桃视频第一区免费观看| 欧美日韩精品免费观看视欧美高清免费大片 | 久久久久久久久久久妇女| 国产精品一区亚洲| 日韩在线电影| 国产精品女主播一区二区三区| 欧美亚洲日本精品| 久久中文字幕一区二区| 日本欧美一区二区| 久热精品在线| 亚洲经典在线| 激情综合自拍| 中文字幕在线看片| 麻豆久久一区| 久久的色偷偷| 国产极品模特精品一二| 国产欧美日韩一区二区三区四区 | 精品国产乱码久久久久久1区2匹| 亚洲精选久久| 亚洲综合日本| 夜夜精品视频| 亚洲精品在线观看91| 欧美日韩一区二区三区视频播放| 亚洲黄色网址| 日韩久久精品网| 欧美片第1页| 欧洲av一区二区| 久久激情一区|