एक पास में लिंक्ड सूची के मध्य तत्व को कैसे ढूंढें?


12

डेटा संरचनाओं और एल्गोरिथ्म से सबसे लोकप्रिय सवाल में से एक, ज्यादातर टेलिफोनिक साक्षात्कार पर पूछा गया।


5
यदि इस थ्रेड में प्रस्तुत किए गए उत्तर साक्षात्कारकर्ता से अपेक्षित हैं, तो यह प्रश्न तकनीकी क्षमता का परीक्षण नहीं करता है, लेकिन उम्मीदवार वकील की तरह कितना अच्छा प्रदर्शन कर सकते हैं।
जी। बछ

2
यह एक भयानक साक्षात्कार प्रश्न है क्योंकि यह " पास " शब्द पर गंभीर रूप से टिका है जो अस्पष्ट, अस्पष्ट, व्यक्तिपरक है। इस प्रश्न के लगभग सभी अच्छे उत्तरों में परिभाषा का दुरुपयोग करना शामिल है ताकि आप इसे प्रभावी रूप से अनदेखा कर सकें।
RBarryYoung

2
खैर, सवाल यहाँ बहुत चर्चा उठाता है। इसका मतलब है कि यह एक सम्मान में एक अच्छा साक्षात्कार प्रश्न है: यह आपको सोचना शुरू करता है।
हेंड्रिक जन

3
मैं जवाब देना चाहता हूं "सभी तत्वों को वेक्टर में पढ़ें, फिर स्थिति आकार () / 2" पर तत्व तक पहुंचें
Cort Ammon

1
@ हेंड्रिकजान दरअसल, मुझे लगता है कि यह पूरी तरह से भयानक साक्षात्कार प्रश्न है। सबसे पहले, यह उत्पादक चर्चा के बजाय "एक पास में" का अर्थ क्या है, इस बारे में तर्क देने की संभावना है। दूसरा, एक उम्मीदवार "सही" उत्तर का पता लगा सकता है और फिर उसे अस्वीकार कर सकता है क्योंकि उन्हें लगा कि उसने "एक पास में" मानदंड का उल्लंघन किया है। तीसरा, क्योंकि यह एक प्रसिद्ध प्रश्न है, यह "क्या आप लोकप्रिय साक्षात्कार प्रश्न जानते हैं?" "क्या आप इस नौकरी के लिए अच्छे हैं?" उनमें से किसी एक को एक प्रश्न के रूप में डूबने के लिए पर्याप्त होना चाहिए; तीनों एक साथ एक आपदा हैं।
डेविड रिचरबी

जवाबों:


24

धोखा देकर, और एक ही समय में दो पास करने से, समानांतर में। लेकिन मुझे नहीं पता कि भर्ती करने वालों को यह पसंद आएगा।

एक अच्छी लिंक के साथ एक ही लिंक की गई सूची पर किया जा सकता है। सूची में दो पॉइंटर्स यात्रा करते हैं, एक दोहरी गति के साथ। जब तेज एक अंत तक पहुंचता है, तो दूसरा एक आधा रास्ता होता है।


1
हाँ, यह स्पष्ट नहीं है कि यह एकल पास है या नहीं। उस बिंदु पर प्रश्न अस्पष्ट है।
बजे डेविड रिचरबी

2
वैसे, यह उस पहेली से संबंधित है जहां आपके पास दो मोमबत्तियाँ हैं, एक घंटे में प्रत्येक जलती हुई है, और आपको 45 मिनट मापने के लिए कहा जाता है।
हेंड्रिक जन

2
क्या यह वास्तव में कोई भिन्न है तो सूची की गणना, तत्वों की गिनती, और फिर दूसरी बार आधे रास्ते के बिंदु पर पुनरावृत्ति? जब आप अतिरिक्त आधे को पुनरावृत्त करते हैं तो यह सब अलग होता है। जैसा कि @RBarryYoung अन्य समान उत्तर पर उल्लेख करता है, यह वास्तव में एक पास नहीं है, यह एक पास और एक आधा है।

2
यदि सूची लंबी है, तो दोनों पॉइंटर्स को "समानांतर में" स्थानांतरित करना दूसरी बार शुरू से पुनरावृत्ति करने की तुलना में कम कैश मिसेज़ को प्रेरित करेगा।
zwol

2
यह चक्र का पता लगाने के लिए कछुआ और हरे एल्गोरिथ्म के समान सिद्धांत का उपयोग करता है ।
यहोशू टेलर

7

यदि यह एक दोगुनी लिंक की गई सूची नहीं है, तो आप बस एक सूची को गिन और उपयोग कर सकते हैं, लेकिन इसके लिए सबसे खराब स्थिति में आपकी मेमोरी को दोगुना करने की आवश्यकता होती है, और यह तब काम नहीं करेगा जब सूची मेमोरी में स्टोर करने के लिए बहुत बड़ी हो।

एक सरल, लगभग मूर्खतापूर्ण समाधान, बस हर दो नोड्स के मध्य नोड में वृद्धि होती है

function middle(start) {
    var middle = start
    var nextnode = start
    var do_increment = false;
    while (nextnode.next != null) {
        if (do_increment) {
             middle = middle.next;
        }
        do_increment = !do_increment;
        nextnode = nextnode.next;
    }
    return middle;
}

आपका दूसरा विकल्प सही उत्तर (IMHO) है।
मैथ्यू क्रुमले

1
यह वास्तव में लिंक्ड सूची पर 1 1/2 पास बना रहा है।
RBarryYoung

6

हेंड्रिक के जवाब पर विस्तार से

यदि यह एक दोहरी लिंक वाली सूची है, तो दोनों सिरों से पुनरावृति

function middle(start, end) {
  do_advance_start = false;
  while(start !== end && start && end) {
     if (do_advance_start) {
        start = start.next
     }
     else {
        end = end.prev
     }
     do_advance_start = !do_advance_start
  }
  return (start === end) ? start : null;
}

दिया हुआ [1, 2, 3] => 2

1, 3
1, 2
2, 2

दिया हुआ [1, 2] => 1

1, 2
1, 1

दिया हुआ [1] => 1

दिया हुआ [] => null


यह कैसे कुशल है? आप भी n बार पुनरावृत्ति कर रहे हैं और n / 2 नहीं।
करण खन्ना

3

लिंक्ड सूची के नोड्स की ओर इशारा करने में सक्षम पॉइंटर के साथ एक संरचना बनाएं और एक पूर्णांक चर के साथ जो सूची में नोड्स की संख्या की गिनती रखता है।

struct LL{
    struct node *ptr;
    int         count;
}start;

अब में लिंक की गई सूची के पहले नोड के पते को स्टोर करें और प्रारंभ करें । लिंक सूची में एक नया नोड के सफल निर्माण के बाद सुनिश्चित करें कि का मूल्य एक से है। इसी तरह, जब भी लिंक की गई सूची से कोई नोड हटा दिया जाता है, तो इसे एक बार घटाएं।s t t a r t सी यू एन टी = 1 एस टी एक आर टी c o u n tstart.ptrstart.count=1
start.count

एक एकल पास में मध्य तत्व को खोजने के लिए का उपयोग करें ।start.count


-2

डायनामिक ऐरे बनाएं, जहां एरे का प्रत्येक तत्व सूची में प्रत्येक नोड के लिए ट्रैवर्सिंग ऑर्डर में शुरुआत से शुरू होने वाला है। 1 से बना एक पूर्णांक, जो आपने कितने नोड्स का दौरा किया है, (जो हर बार जब आप एक नए नोड में जाते हैं तो वेतन वृद्धि) का ट्रैक रखता है। जब आप अंत तक पहुँचते हैं, तो आपको पता चलता है कि सूची कितनी बड़ी है, और आपके पास प्रत्येक नोड के लिए एक आदेशित सरणी है। अंत में, सूची के आकार को 2 से विभाजित करें (और 0-आधारित अनुक्रमण के लिए 1 घटाएं) और सरणी के उस सूचकांक में रखे गए सूचक को लाएं; यदि सूची का आकार विषम है, तो आप चुन सकते हैं कि किस तत्व को वापस करना है (मैं अभी भी पहले वाले को वापस करूंगा)।

यहाँ कुछ जावा कोड है जो बिंदु को पार करता है (भले ही एक गतिशील सरणी का विचार थोड़ा विस्की हो जाएगा)। मैं C / C ++ प्रदान करूंगा, लेकिन मैं उस क्षेत्र में बहुत कठोर हूं।

public Node getMiddleNode(List<Node> nodes){

    int size = 1;
    //add code to dynamically increase size if at capacity after adding
    Node[] pointers = new Node[10];

    for (int i = 0; i < nodes.size(); i++){
        //remember to dynamically allocate more space if needed
        pointers[i] = nodes.get(i);
        size++;
    }

    return pointers[(size - 1)/2];

}

-3

क्या रिकर्सन को एक से अधिक पास माना जाता है?

संदर्भ द्वारा पूर्णांक गणना पास करते हुए, सूची को अंत तक पीछे ले जाएं। बाद के संदर्भ के लिए प्रत्येक स्तर पर उस मूल्य की एक स्थानीय प्रतिलिपि बनाएँ, और अगली कॉल में जाने वाली रेफरी की संख्या बढ़ाएँ।

अंतिम नोड पर, गिनती को दो और ट्रंकट / फ्लोर () से विभाजित करें (यदि आप चाहते हैं कि पहला नोड "मध्य" हो जब केवल दो तत्व हों) या राउंड अप (यदि आप दूसरा नोड चाहते हैं मध्य")। एक शून्य या एक-आधारित सूचकांक का उचित रूप से उपयोग करें।

अनवाइंडिंग, स्थानीय काउंट (जो नोड की संख्या है) के लिए रेफरी काउंट से मेल खाता है। यदि बराबर है, तो उस नोड को वापस करें; पुन: पुनरावर्ती कॉल से वापस लौटा नोड।

ऐसा करने के अन्य तरीके हैं; उनमें से कुछ कम बोझिल हो सकते हैं (मुझे लगा कि मैंने देखा कि कोई व्यक्ति इसे एक सरणी में पढ़ता है और मध्य-कुडो को निर्धारित करने के लिए सरणी लंबाई का उपयोग करता है)। लेकिन स्पष्ट रूप से, कोई अच्छा जवाब नहीं हैं, क्योंकि यह एक बेवकूफ साक्षात्कार प्रश्न है। नंबर एक, जो अभी भी लिंक की गई सूची ( समर्थन राय ) का उपयोग करता है ; दो, मध्य नोड को खोजना एक मनमाना, अकादमिक अभ्यास है जिसका वास्तविक जीवन परिदृश्यों में कोई मूल्य नहीं है; तीन, अगर मुझे वास्तव में मध्य नोड जानने की जरूरत है, तो मेरी लिंक की गई सूची नोड संख्या को उजागर करेगी। यह उस संपत्ति को बनाए रखने के लिए आसान है जो हर बार पूरी सूची को बर्बाद करने की तुलना में मध्य नोड चाहता है। और अंत में, चार, प्रत्येक साक्षात्कारकर्ता को अलग-अलग उत्तरों को पसंद या अस्वीकार करने जा रहा है - जो एक साक्षात्कारकर्ता सोचता है कि वह चालाक है, दूसरा हास्यास्पद कहेगा।

मैं लगभग हमेशा अधिक प्रश्नों के साथ साक्षात्कार प्रश्नों का उत्तर देता हूं। अगर मुझे इस तरह का कोई प्रश्न मिलता है (मेरे पास कभी नहीं है), तो मैं पूछूंगा (1) आप इस लिंक की गई सूची में क्या संग्रह कर रहे हैं, और क्या वास्तव में ऐसा करने की आवश्यकता है, तो मध्य नोड तक कुशलता से पहुंचने के लिए एक अधिक उपयुक्त संरचना है। ; (२) मेरी अड़चनें क्या हैं? यदि स्मृति कोई समस्या नहीं है (उदाहरण सरणी उत्तर), तो मैं इसे तेज़ी से बना सकता हूं, लेकिन यदि साक्षात्कारकर्ता सोचता है कि स्मृति को ख़राब करना बेकार है, तो मैं चक्कर खाऊंगा। (३) मैं किस भाषा में विकसित होऊंगा? लगभग हर आधुनिक भाषा जो मुझे पता है कि अंतर्निहित सूचियों से निपटने के लिए अंतर्निहित कक्षाएं हैं जो सूची को अनावश्यक बनाते हैं - भाषा के डेवलपर्स द्वारा दक्षता के लिए ट्यून की गई चीज़ को फिर से क्यों बनाया जाए?


6
आप नहीं जानते हैं कि किसने क्या निष्कर्ष निकाला है कि आपका निष्कर्ष यह है कि एक व्यक्ति ने जो कुछ भी लिखा है, वह सच हो सकता है या नहीं भी हो सकता है, लेकिन यह निश्चित रूप से आपके लिए उपलब्ध तथ्यों का कोई आधार नहीं है। लेकिन मैं आपके उत्तर को अस्वीकार कर रहा हूं क्योंकि हम स्पष्टीकरण की तलाश कर रहे हैं, कोड के ढेर नहीं।
डेविड रिचरबी

यह एक धारणा हो सकती है, लेकिन जब मैं एक पल देखता हूं और 30 सेकंड से कम समय बाद हर पोस्ट में ठीक -1 होता है, तो यह अनुचित नहीं है। यहां तक ​​कि अगर यह 5 या 6 अलग-अलग लोग थे, तो उनमें से एक ने भी एक टिप्पणी क्यों नहीं छोड़ी। लेकिन कम से कम एक कारण बताते हुए धन्यवाद। मुझे नहीं पता कि क्यों कोड के मुकाबले एक स्पष्ट विवरण बेहतर है - हां, यह एक टेलीफोनिक साक्षात्कार के लिए है, लेकिन मैं ओपी को पुनर्जन्म के लिए एक डिब्बाबंद जवाब नहीं दे रहा हूं, मैं उसे ऐसा करने का एक तरीका दिखा रहा हूं। IE मुझे लगता है कि किसी पोस्ट को डाउनवोट करना क्योंकि उसमें कोड है, जिसके लिए वह नहीं है, लेकिन कम से कम यह कहने के लिए धन्यवाद कि आपने ऐसा क्यों किया।
जेम्स के

उचित बिंदु - यह मेरे लिए नहीं हुआ था कि आप वोटों का समय जान सकें (पृष्ठ लोड होने के दौरान जब वे हुए हैं, मुझे लगता है, हमारे जैसे सामान्य उपयोगकर्ता केवल उसी तरह से पता लगा सकते हैं)। हमारे पास कुछ मेटा पोस्ट हैं जिनके बारे में हम यहां वास्तविक कोड से बचने की कोशिश करते हैं: (1) (2)
डेविड रिचरबी

मेटा लिंक के लिए धन्यवाद। मैंने अक्सर पूछे जाने वाले प्रश्न पढ़े, लेकिन मैंने वहां कुछ भी नहीं देखा - ऐसा नहीं है कि मैंने ऐसा कुछ देखा होगा, सबसे अधिक संभावना है, कुछ ऐसा नहीं जिसकी मैंने उम्मीद की थी। लेकिन मुझे कुछ भी नहीं मिला, जब मैं डिंग करने के बाद वापस आया। मैं अभी भी इसे देख सकता हूं, लेकिन मैंने देख लिया। मेटा पोस्ट में तर्क समझ में आता है; जवाब देने के लिए धन्यवाद।
जेम्स के।

-5

2 पॉइंटर्स का उपयोग करके। प्रत्येक पुनरावृत्ति में एक वृद्धि और हर दूसरे पुनरावृत्ति में अन्य। जब 1 पॉइंटर लिंक की गई सूची के अंत में जाता है, तो दूसरा पॉइंटर लिंक की गई सूची के मध्य मोड की ओर इशारा करेगा।


यह सिर्फ हेंड्रिक के जवाब की नकल करता है । कृपया जवाब न दें जब तक आपके पास कहने के लिए कुछ नया न हो।
डेविड रिचरबी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.