2011-11-20 15 views
8

लंबाई की एक स्ट्रिंग को देखते हुए एन युक्त वर्ण [ए-जेड], मैं एक व्यक्तिगत चरित्र के लिए सबसे लंबा पालिंड्रोम कैसे निर्धारित करूं?मैं किसी दिए गए स्ट्रिंग में सबसे लंबे समय तक व्यक्तिगत वर्ण पैलिंड्रोम को कुशलतापूर्वक कैसे निर्धारित करूं?

मैं एक उदाहरण के साथ इस उदाहरण देकर स्पष्ट करना होगा:

को देखते हुए स्ट्रिंग: स्ट्रिंग का विश्लेषण करने में JOHNOLSON , हम पाते हैं कि हम चरित्र O ऐसी है कि स्ट्रिंग JOHN तरह लग रहा है के साथ एक विलोमपद है OLSONO के लिए विलोमपद अनिवार्य रूप से की तरह O--O--O देख लंबाई 7 की है। इसके अलावा, नोटिस N साथ विलोमपद कि वहाँ, लेकिन यह केवल लंबाई की है 6.

एक अन्य उदाहरण है को देखते हुए स्ट्रिंग: ABCJOHNOLSON ही परिणाम से ऊपर के रूप में लंबाई 7 की तरह लग रही के O की की विलोमपद साथ देता है O--O--O

हालांकि, दिए गए स्ट्रिंग ABCJOHNOLSONDA, साथ सबसे लंबे समय तक व्यक्तिगत चरित्र विलोमपद चरित्र A तरह A------------A देख के साथ लंबाई 14 वर्ष की है।

अन्य सरल उदाहरणों में शामिल हैं:

ABA ->A-A (लंबाई 3)

ABAXYZ ->A-A (लंबाई 3)

ABAXYZA ->A---A (लंबाई 5), नहीं लंबाई 7 क्योंकि A-A---A पत्र A के लिए विलोमपद नहीं है।

अंतिम उदाहरण पर विशेष ध्यान दें क्योंकि यह समस्या के सूक्ष्म बारीकियों में से एक को दर्शाता है।

+3

"पैलिंड्रोम" की तुलना में आप जो खोज रहे हैं उसके लिए एक बेहतर शब्द होना चाहिए क्योंकि आपके अधिकांश उदाहरण palindromes नहीं हैं। – Blastfurnace

+0

एक उदाहरण स्ट्रिंग 'एबीसीडीईएलएमएनए' पर विचार करें कि 'ए' पर विचार करते समय 'ए --- ए - ए --- ए' जैसा दिखता है जो एक पालिंड्रोम होता है (जब आप शेष पात्रों की विशिष्टता को अनदेखा करते हैं) आकार 12 के, लेकिन स्ट्रिंग 'एबीसीडीईएलएमएनओएनए' पर विचार करें, जिसमें से पूरी स्ट्रिंग अब पैलिंड्रोम नहीं है, इसके बजाय एक बहुत छोटा सबस्ट्रिंग सबसे लंबा पैलिंड्रोम बन जाता है, अर्थात् अंत में लंबाई 5 की 'ए --- ए'। – jbranchaud

+0

मैं उस 'पैटर्न' को समझता हूं जिसमें आप रुचि रखते हैं, यह शब्द पैलिंड्रोम शब्दकोष परिभाषा में फिट नहीं है। मुझे आश्चर्य है कि आप जो चाहते हैं उसके लिए एक नियमित अभिव्यक्ति समाधान है। – Blastfurnace

उत्तर

5

आप इसे रैखिक समय में कर सकते हैं, यह कोड नमूना के साथ here का वर्णन किया गया है।

0

यहां मैं क्या आया, मुझे नहीं पता कि यह कितना कुशल हो सकता है।

 
For every letter in the alphabet, 
    Find the first and last occurrence of this letter. 
    While the substring is not a palindrome for that letter (easy to check), 
    find the next letter on both sides so that every possible combination is 
    checked. Take the longest one and store it. 
Take the longest one. 
+0

जब आप कहते हैं कि दोनों पक्षों पर अगला पत्र मिलता है तो क्या आपका मतलब उस चरित्र का अगला उदाहरण है जिसे आप वर्तमान में खोज रहे हैं? यह कुछ तारों के लिए असफल हो जाएगा, जैसे कि "ABAAACAA" –

+0

@ जोर्डनबेंटले: नहीं, मेरा मतलब है (उदाहरण के लिए) 0,7 फिर 0,6 तो 0,4 फिर 0,3 फिर 0,2 फिर 0,0 फिर 2 , 7 फिर 2,6 फिर 2,4 फिर 2,3 फिर 2,2 फिर 3,7 फिर 3,6 तो ... आपको बिंदु मिल गया :) लेकिन अगर आप कुछ शर्तों के तहत पालिंड्रोम पा सकते हैं तो आप तोड़ सकते हैं, कहें हाथोंहाथ। – Ryan

+0

आह, जो अधिक समझ में आता है। अगर मैं इसे सही समझ रहा हूं, तो यह काम करेगा लेकिन सबसे खराब मामला जटिलता ओ (एन!) –

0

निश्चित रूप से इष्टतम नहीं है। मानता है इनपुट स्ट्रिंग सभी लोअरकेस है।

using System; 
using System.Collections.Generic; 

public class LongestPalindrome 
{ 
    public int longest(string s) 
    { 
     Dictionary<char, List<int>> indices = 
      new Dictionary<char, List<int>>(); 

     // find all indices for each letter 
     for (int i = 0; i < s.Length; i++) 
     { 
      char c = s[i]; 
      if (!indices.ContainsKey(c)) 
        indices.Add(c, new List<int>()); 
      indices[c].Add(i); 
     } 

     int max = Int32.MinValue; 

     for (int i = (int)'a'; i <= (int)'z'; i++) 
     { 
      char c = (char)i; 

      // in case a letter didn't appear at all in the input string 
      if (!indices.ContainsKey(c)) continue; 

      List<int> indexList = indices[c]; 

      // in case a letter appeared only once in the input string 
      if (indexList.Count == 1) max = Math.Max(max, 1); 

      for (int j = 0; j < indexList.Count; j++) 
      { 
       for (int k = j + 1; k < indexList.Count; k++) 
       { 
        int dist = indexList[k] - indexList[j] + 1; 
        string sub = s.Substring(indexList[j], dist); 
        if (isPalendrome(sub, c)) 
             max = Math.Max(max, dist); 
       } 
      } 
     } 

     return max; 
    } 

    bool isPalendrome(string s, char c) 
    { 
     int i = 0; 
     while(i < s.Length - 1 - i) 
     { 
      if (s[i] != c && s[s.Length - 1 - i] != c) 
      { 
       i++; 
       continue; 
      } 
      if (s[i] != s[s.Length - 1 - i]) return false; 
      i++; 
     } 
     return true; 
    } 
}