GallopSearch मर्ज: O (n) * log (i) (O ) बजाय O (n)
मैंने आगे बढ़कर टिप्पणियों में ग्रेबर्ड सुझाव लागू किया। ज्यादातर क्योंकि मुझे इस कोड के एक अत्यधिक कुशल मिशन महत्वपूर्ण संस्करण की आवश्यकता थी।
- कोड एक सरपट खोज का उपयोग करता है जो ओ (लॉग (आई)) है जहां मैं वर्तमान सूचकांक से दूरी प्रासंगिक सूचकांक मौजूद है।
- सरपट खोज के बाद उचित, श्रेणी की पहचान के लिए कोड एक बाइनरीसर्च का उपयोग करता है। चूंकि सरपट इसे एक छोटी सीमा तक सीमित करता है जिसके परिणामस्वरूप बाइनरीसर्च भी हे (लॉग (आई))
- सरपट और मर्ज पीछे की ओर किए जाते हैं। यह मिशन महत्वपूर्ण नहीं लगता, लेकिन यह एरेज़ के विलय के स्थान पर अनुमति देता है। यदि आपके सरणियों में से एक में परिणाम मानों को संग्रहीत करने के लिए पर्याप्त जगह है, तो आप बस इसे विलय सरणी और परिणाम सरणी के रूप में उपयोग कर सकते हैं । आपको ऐसे मामले में सरणी के भीतर मान्य श्रेणी निर्दिष्ट करनी होगी।
- इसके लिए उस मामले में मेमोरी आवंटन की आवश्यकता नहीं है (महत्वपूर्ण कार्यों में बड़ी बचत)। यह केवल यह सुनिश्चित करता है कि यह किसी भी असंसाधित मूल्यों को अधिलेखित नहीं करता है (जो केवल पीछे की ओर किया जा सकता है)। वास्तव में, आप इनपुट और परिणाम दोनों के लिए एक ही सरणी का उपयोग करते हैं। इसका कोई बुरा प्रभाव नहीं पड़ेगा।
- मैंने लगातार Integer.compare () का उपयोग किया ताकि इसे अन्य उद्देश्यों के लिए स्विच किया जा सके।
- वहाँ कुछ मौका है कि मैं एक छोटे से नासमझ है और मैं पहले से साबित कर दिया है जानकारी का उपयोग नहीं किया जा सकता है। जैसे कि द्विआधारी दो मानों की श्रेणी में खोज, जिसके लिए पहले से ही एक मूल्य की जाँच की गई थी। मुख्य लूप को निर्दिष्ट करने का एक बेहतर तरीका भी हो सकता है, फ़्लिपिंग सी मूल्य की आवश्यकता नहीं होगी यदि उन्हें अनुक्रम में दो संचालन में जोड़ा गया। चूँकि आप जानते हैं कि आप एक करेंगे तो दूसरा हर। कुछ पॉलिश के लिए जगह है।
ऐसा करने के लिए यह सबसे कुशल तरीका होना चाहिए, ओ (एन) के बजाय ओ (लॉग (एन) * लॉग (आई) की समय जटिलता के साथ । और ओ (एन) की सबसे खराब स्थिति समय की जटिलता। यदि आपके सरणियाँ अव्यवस्थित हैं और एक साथ मूल्यों के लंबे तार हैं, तो यह इसे करने के लिए किसी अन्य तरीके को बौना कर देगा, अन्यथा यह सिर्फ उनसे बेहतर होगा।
यह मर्ज सरणी के सिरों पर दो रीड वैल्यू और परिणाम एरे के भीतर राइट वैल्यू है। यह पता लगाने के बाद कि कौन सा अंतिम मूल्य कम है, यह उस सरणी में सरपट खोज करता है। १, २, ४,,, १६, ३२, इत्यादि। जब यह वह सीमा पाता है जहाँ दूसरे सरणी का वाच मान बड़ा होता है। यह बाइनरी उस सीमा में खोज करता है (आधे में सीमा को काटता है, सही आधा खोजता है, एकल मूल्य तक दोहराता है)। फिर यह सरणी उन मानों को लिखने की स्थिति में कॉपी करता है। इस बात को ध्यान में रखते हुए कि प्रतिलिपि आवश्यकता के आधार पर ऐसी है कि यह या तो पढ़ने वाले सरणी से समान मानों को अधिलेखित नहीं कर सकती है (जिसका अर्थ है कि लेखन सरणी और रीड सरणी समान हो सकती है)। यह तब दूसरे सरणी के लिए एक ही ऑपरेशन करता है जिसे अब अन्य सरणी के नए रीड वैल्यू से कम जाना जाता है।
static public int gallopSearch(int current, int[] array, int v) {
int d = 1;
int seek = current - d;
int prevIteration = seek;
while (seek > 0) {
if (Integer.compare(array[seek], v) <= 0) {
break;
}
prevIteration = seek;
d <<= 1;
seek = current - d;
if (seek < 0) {
seek = 0;
}
}
if (prevIteration != seek) {
seek = binarySearch(array, seek, prevIteration, v);
seek = seek >= 0 ? seek : ~seek;
}
return seek;
}
static public int binarySearch(int[] list, int fromIndex, int toIndex, int v) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = list[mid];
int cmp = Integer.compare(midVal, v);
if (cmp < 0) {
low = mid + 1;
} else if (cmp > 0) {
high = mid - 1;
} else {
return mid;// key found
}
}
return -(low + 1);// key not found.
}
static public int[] sortedArrayMerge(int[] a, int[] b) {
return sortedArrayMerge(null, a, a.length, b, b.length);
}
static public int[] sortedArrayMerge(int[] results, int[] a, int aRead, int b[], int bRead) {
int write = aRead + bRead, length, gallopPos;
if ((results == null) || (results.length < write)) {
results = new int[write];
}
if (aRead > 0 && bRead > 0) {
int c = Integer.compare(a[aRead - 1], b[bRead - 1]);
while (aRead > 0 && bRead > 0) {
switch (c) {
default:
gallopPos = gallopSearch(aRead, a, b[bRead-1]);
length = (aRead - gallopPos);
write -= length;
aRead = gallopPos;
System.arraycopy(a, gallopPos--, results, write, length);
c = -1;
break;
case -1:
gallopPos = gallopSearch(bRead, b, a[aRead-1]);
length = (bRead - gallopPos);
write -= length;
bRead = gallopPos;
System.arraycopy(b, gallopPos--, results, write, length);
c = 1;
break;
}
}
}
if (bRead > 0) {
if (b != results) {
System.arraycopy(b, 0, results, 0, bRead);
}
} else if (aRead > 0) {
if (a != results) {
System.arraycopy(a, 0, results, 0, aRead);
}
}
return results;
}
यह इसे करने का सबसे कुशल तरीका होना चाहिए।
कुछ उत्तरों में डुप्लिकेट हटाने की क्षमता थी। आपको एक O (n) एल्गोरिथ्म की आवश्यकता होगी क्योंकि आपको वास्तव में प्रत्येक आइटम की तुलना करनी चाहिए। इस तथ्य के बाद लागू होने के लिए यहां एक स्टैंड-अलोन है। यदि आप उन सभी को देखने की जरूरत है, तो आप कई प्रविष्टियों के माध्यम से सभी तरीकों से सरपट नहीं कर सकते हैं, हालांकि आप डुप्लिकेट के माध्यम से सरपट कर सकते हैं, अगर आपके पास उनमें से बहुत कुछ था।
static public int removeDuplicates(int[] list, int size) {
int write = 1;
for (int read = 1; read < size; read++) {
if (list[read] == list[read - 1]) {
continue;
}
list[write++] = list[read];
}
return write;
}
अद्यतन: पिछला उत्तर, भयानक कोड नहीं, लेकिन स्पष्ट रूप से ऊपर से नीच।
एक और अनावश्यक हाइपर-ऑप्टिमाइज़ेशन। यह न केवल अंत बिट्स के लिए एरेस्कोपी को आमंत्रित करता है, बल्कि शुरुआत के लिए भी। डेटा में एक बाइनरीसर्च द्वारा ओ (लॉग (एन)) में किसी भी परिचयात्मक गैर-ओवरलैप को संसाधित करना। O (लॉग (n) + n) O (n) है और कुछ मामलों में प्रभाव विशेष रूप से उन चीजों का स्पष्ट रूप से उच्चारण किया जाएगा, जहां विलय ऐरे के बीच कोई ओवरलैप नहीं है।
private static int binarySearch(int[] array, int low, int high, int v) {
high = high - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = array[mid];
if (midVal > v)
low = mid + 1;
else if (midVal < v)
high = mid - 1;
else
return mid; // key found
}
return low;//traditionally, -(low + 1); // key not found.
}
private static int[] sortedArrayMerge(int a[], int b[]) {
int result[] = new int[a.length + b.length];
int k, i = 0, j = 0;
if (a[0] > b[0]) {
k = i = binarySearch(b, 0, b.length, a[0]);
System.arraycopy(b, 0, result, 0, i);
} else {
k = j = binarySearch(a, 0, a.length, b[0]);
System.arraycopy(a, 0, result, 0, j);
}
while (i < a.length && j < b.length) {
result[k++] = (a[i] < b[j]) ? a[i++] : b[j++];
}
if (j < b.length) {
System.arraycopy(b, j, result, k, (b.length - j));
} else {
System.arraycopy(a, i, result, k, (a.length - i));
}
return result;
}