7

नोट: यह कोडिंग साक्षात्कार क्रैकिंग 5 वें संस्करण से समस्या 4.3 हैक्या यह एल्गोरिदम ओ (एन) में चलाएगा?

समस्या: एक हल कर (बढते क्रम) को देखते हुए सरणी, एक एल्गोरिथ्म लिखना कम से कम ऊंचाई के साथ एक द्विआधारी खोज वृक्ष बनाने के लिए

यहाँ मेरी एल्गोरिथ्म, जावा में लिखा इस समस्या

public static IntTreeNode createBST(int[] array) { 
     return createBST(array, 0, array.length-1); 
    } 
    private static IntTreeNode createBST(int[] array, int left, int right) { 
     if(right >= left) { 
      int middle = array[(left + right)/2; 
      IntTreeNode root = new IntTreeNode(middle); 
      root.left = createBST(array, left, middle - 1); 
      root.right = createBST(array, middle + 1, right); 
      return root; 
     } else { 
      return null; 
     } 
    } 

मैं लेखक का के खिलाफ इस कोड की जाँच की क्या करना है और यह लगभग समान है।
हालांकि मुझे इस एल्गोरिदम की समय जटिलता का विश्लेषण करने में कठिनाई हो रही है।
मुझे पता है कि यह ओ (लॉग इन)Binary Search जैसा नहीं होगा क्योंकि आप रिकर्सन के प्रत्येक स्तर पर समान मात्रा में काम नहीं कर रहे हैं। पहले स्तर पर ईजी, काम की 1 इकाई, द्वितीय स्तर - 2 इकाइयों की काम, तीसरी स्तर - काम की 4 इकाइयां, (एन) स्तर - एन काम की इकाइयों को लॉग करने के सभी तरीके।

तो बंद आधारित है कि, चरणों की संख्या इस एल्गोरिदम लेता ऊपरी इस गणितीय अभिव्यक्ति से घिरा हो जाएगा

enter image description here

जो Infinite geometric series देखने के बाद, मैं enter image description here

या 2n के लिए मूल्यांकन जो ओ (एन)

क्या आप लोग मेरे साथ सहमत होंगे यहां काम करें और यह एल्गोरिदम ओ (एन) में चलाएगा या क्या मुझे कुछ याद आया या वास्तव में यह ओ (nlogn) या कुछ अन्य फ़ंक्शन क्लास में चलता है?

+0

हां, यह ओ (एन) है। अगर मैं जटिलता का एक अच्छा सबूत बनता हूं तो इसका एक स्पष्ट विचार था कि मैं इसका उत्तर दूंगा। – Beta

+0

@ बीटा आप सबूत के बिना कैसे बताने में सक्षम थे? – committedandroider

+1

मैंने देखा कि एल्गोरिदम ओ/2 तत्वों पर प्रत्येक बार दो बार कॉल करता है, ओ (1) अतिरिक्त काम और एक तत्व हटा दिया जाता है। मुझे नहीं लगता कि यह एक कठोर सबूत है (जैसा कि "चलो' एफ (एन) 'और 'जी (एन)' जैसे कार्य हो ..."), लेकिन यह पर्याप्त था कि मैं इसे अपने सिर में देख सकता था, टुकड़ों में स्ट्रिंग का एक टुकड़ा की तरह और बिना ओवरलैप के रखे। – Beta

उत्तर

5

कभी-कभी आप पुनरावृत्ति संबंधों को हल करने के बजाय परिणाम में प्रति आइटम की मात्रा की गणना करके गणना को सरल बना सकते हैं। वह चाल यहां लागू होती है। इस स्पष्ट रूप से बराबर फार्म के लिए कोड को बदलने के द्वारा शुरू करें:

private static IntTreeNode createBST(int[] array, int left, int right) { 
    int middle = array[(left + right)/2; 
    IntTreeNode root = new IntTreeNode(middle); 
    if (middle - 1 >= left) { 
     root.left = createBST(array, left, middle - 1); 
    } 
    if (right >= middle + 1) { 
     root.right = createBST(array, middle + 1, right); 
    } 
    return root; 
} 

अब createBST के लिए हर कॉल सीधे 1 नोड पैदा करता है। चूंकि अंतिम पेड़ में एन नोड्स हैं, ncreateBST पर कुल कॉल होना चाहिए और चूंकि प्रत्येक कॉल सीधे निरंतर काम करता है, समग्र समय जटिलता ओ (एन) है।

+0

मुझे इसे मारो। मैं बस एक ही तर्क लिखने के लिए बैठ गया। –

+0

धन्यवाद तर्क के इस हिस्से को समझ में आया - "चूंकि अंतिम पेड़ में एन नोड्स हैं, इसलिए बीएसटी बनाने के लिए कुल कॉल होना चाहिए"। हालांकि उस कोड को बदलने से कैसे पता चलता है कि प्रत्येक कॉल निरंतर काम करता है? एक कॉल अभी भी दो कॉल कर सकता है, जो एक ही आकार के हैं, लेकिन मूल कॉल से छोटे हैं। एक ही आकार की उन कॉलों को हर बार छोटा हो रहा है, इसलिए प्रत्येक कॉल कम कॉल आकार की संपत्ति के कारण लगातार काम नहीं कर रही है? – committedandroider

+0

@committedandroider मैंने कोड बदल दिया ताकि परिणाम बनाने के लिए कॉल और परिणाम के नोड्स एक-से-एक हैं। मूल कोड में, कुछ बीबीएस बनाने के लिए कॉल शून्य वापस आ गया। तर्क को मूल कोड में अनुकूलित किया जा सकता है, लेकिन यह थोड़ा सा गड़बड़ है: उदाहरण के लिए, आप तर्क दे सकते हैं कि बीएसटी बनाने के लिए अधिकांश एन कॉल हैं जो नोड्स बनाते हैं और अधिकतर 2 एन कॉल जो शून्य लौटते हैं। –

1

यदि आप रिकर्सन में भ्रमित हो जाते हैं, तो एक लूप के रूप में रिकर्सिव कॉल (मानसिक रूप से, ज़ाहिर है) को प्रतिस्थापित करें। उदाहरण के लिए, आपके उपरोक्त फ़ंक्शन में, आप "लूप" के अंदर रिकर्सिव कॉल की कल्पना कर सकते हैं। चूंकि, अब यह समय थोड़ी देर तक निष्पादित है जब तक कि सभी एन नोड्स को पार नहीं किया जाता है, जटिलता ओ (एन) होती है।

+0

लेकिन यह Quicksort के साथ कुछ के साथ काम नहीं करेगा। आप सभी तत्वों पर जाते हैं लेकिन रनटाइम ओ (एन लॉग एन) होगा, ओ (एन) नहीं। इस स्थिति के लिए आप अपनी विधि को कैसे दोहराएंगे? मुझे पसंद है कि आपने थोड़ी देर के साथ क्या किया था। – committedandroider

+0

हां, मैं एल्गोरिदम के लिए लूपों की कल्पना करना मुश्किल समझता हूं जैसे कि त्वरित क्रम जो लॉगरिदमिक रूप से बढ़ता है। हालांकि, यह विचार ओ (एन^2), ओ (एन^3), आदि जैसे सभी तेजी से बढ़ते कार्यों के लिए पूरी तरह से काम करता है। हमें केवल नेस्टेड लूप का उपयोग करने की आवश्यकता है। –

संबंधित मुद्दे