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
Post a Comment