c# - Where is the flaw in my algorithm to get the largest palindrome is a string representation of a number? -


i'm trying largest palindrome can formed k replacements of digits in string number.

e.g.

number="3943",k=1 --> "3993" 

for exact test case getting "393" , test cases getting error like

unhandled exception: system.invalidoperationexception: sequence contains no elements @ system.linq.enumerable.last[tsource] (ienumerable`1 source) <0x414ec920 + 0x001ab> in :0 @ solution.largestpalindrome (system.string numstr, int32 k) [0x00197] in solution.cs:74 @ solution+c__anonstorey0.<>m__0 (system.string str) [0x00009] in solution.cs:61

using system; using system.collections.generic; using system.io; using system.linq; class solution {     static bool ispalindrome(string s)     {         // returns true or false depending on whether string         // s palindrome         // e.g. "abba" --> true, "acba" --> false         for(int = 0, j = s.length - 1; < j; ++i, --j)         {             if(s[i] != s[j])                 return false;         }         return true;     }      static string replace(string s, int i, char c)     {         // returns copy of s character @ index         // replaced character c         // e.g. "george",2,"x" --> "gexrge"         string part1 = s.length > 0 ? s.substring(0, i) : string.empty;         string part2 = < (s.length - 1) ? c.tostring() : string.empty;         string part3 = (i + 1) < (s.length - 1) ? s.substring(i + 1, s.length - - 1) : string.empty;         return part1 + part2 + part3;     }      static string largestpalindrome(string numstr, int k)     {         // numstr: string representation of number         // k: maximum number of digit replacements allowed          // if no digit replacements allowed, return same string         if(k == 0)             return numstr;          // digrange {'0', '1', ..., '9'}         list<char> digrange = new list<char>();         for(char c = '0'; c <= '9'; ++c)             digrange.add(c);          // possibilities possibilities of replacing 1 digit numstr         // e.g. numstr="02" --> possibilities={"12","22","32",...,"92","00","01","03","09"}         list<string> possibilities = new list<string>();                 for(int = 0; < numstr.length; ++i)         {                      foreach(char dig in digrange.where(d => d != numstr[i]))             {                 possibilities.add(replace(numstr,i,dig));             }         }          // if k = 1, strings in cumulativepossiblities palindromes;          // else, transform each largest palindrome formed k - 1 character         // replacements of         var cumulativepossibilities =  k == 1              ? possibilities.where(str => ispalindrome(str))             : possibilities.select(str => largestpalindrome(str, k - 1)).where(str => ispalindrome(str));          // sort cumulativepossibilities in ascending order of integer representation         // of strings         cumulativepossibilities.tolist().sort((s1,s2) => {             int64 i1 = int64.parse(s1),                   i2 = int64.parse(s2);             return (i1 > i2) ? 1 : ((i1 == i2) ? 0 : -1);         });          // last element of now-sorted cumulativepossibilities,          // largest number represented possible strings         // or null if there none         string largest = cumulativepossibilities.last();          // return largest or "-1" if there none         return largest != null ? largest : "-1";     }      static void main(string[] args)     {         string[] tokens_n = console.readline().split(' ');         int k = convert.toint32(tokens_n[1]);         string number = console.readline();         // use brute force algorithm find largest palindrome of string         // representation of number after k replacements of characters         console.writeline(largestpalindrome(number,k));     } } 

not efficient method, simple implement; key feature using palindromesubstitutions (counting how many characters' substitutions prevents string being palindrome) instead of ispalindrome (just fact if string palindrome or not)

// how many characters should substituted in order // turn string palindrom private static int palindromesubstitutions(string value) {   if (string.isnullorempty(value))     return 0;    int result = 0;    (int = 0; < value.length / 2; ++i)     if (value[i] != value[value.length - 1 - i])       result += 1;    return result; }  // let's test substrings of size length, length - 1, ... , 2, 1 // until find substring required tolerance private static string bestpalindromesubstitutions(string value, int tolerance) {   (int size = value.length; size >= 1; --size)     (int start = 0; start <= value.length - size; ++start)       if (palindromesubstitutions(value.substring(start, size)) <= tolerance)         return value.substring(start, size);    return ""; }  private static string substitutetopalindrome(string value) {   if (string.isnullorempty(value))     return value;    stringbuilder sb = new stringbuilder(value);    (int = 0; < value.length / 2; ++i)      sb[value.length - 1 - i] = sb[i];    return sb.tostring(); } 

test:

 string input = "73943";  string best = bestpalindromesubstitutions(input, 1);  string report =     string.format("best palindrome {0} -> {1}", best, substitutetopalindrome(best)); 

output

   best palindrome 3943 -> 3993 

Comments