我试图获得可以通过k
替换字符串number
中的数字形成的最大回文。
e.g。
number="3943",k=1 --> "3993"
对于那个确切的测试用例,我得到"393"
,对于某些测试用例,我收到的错误如
未处理的异常:System.InvalidOperationException:Sequence System.Linq.Enumerable.Last [TSource]中不包含任何元素 (IEnumerable`1 source)< 0x414ec920 + 0x001ab> in:0 在Solution.LargestPalindrome(System.String numstr,Int32 k) [0x00197]在solution.cs中:74 at 解决方案+ c__AnonStorey0。<> m__0(System.String str) solution.cs中的[0x00009]: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 the string
// s is a palindrome
// e.g. "abba" --> true, "acba" --> false
for(int i = 0, j = s.Length - 1; i < j; ++i, --j)
{
if(s[i] != s[j])
return false;
}
return true;
}
static string Replace(string s, int i, char c)
{
// returns a copy of s with the character at index i
// replaced by character c
// e.g. "george",2,"x" --> "gexrge"
string part1 = s.Length > 0 ? s.Substring(0, i) : string.Empty;
string part2 = i < (s.Length - 1) ? c.ToString() : string.Empty;
string part3 = (i + 1) < (s.Length - 1) ? s.Substring(i + 1, s.Length - i - 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 will be {'0', '1', ..., '9'}
List<char> digrange = new List<char>();
for(char c = '0'; c <= '9'; ++c)
digrange.Add(c);
// possibilities will be all possibilities of replacing one digit from numstr
// e.g. numstr="02" --> possibilities={"12","22","32",...,"92","00","01","03","09"}
List<string> possibilities = new List<string>();
for(int i = 0; i < numstr.Length; ++i)
{
foreach(char dig in digrange.Where(d => d != numstr[i]))
{
possibilities.Add(Replace(numstr,i,dig));
}
}
// if k = 1, get all the strings in cumulativePossiblities that are palindromes;
// else, transform each into the largest palindrome formed by k - 1 character
// replacements of itself
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 the integer representation
// of the strings
cumulativePossibilities.ToList().Sort((s1,s2) => {
Int64 i1 = Int64.Parse(s1),
i2 = Int64.Parse(s2);
return (i1 > i2) ? 1 : ((i1 == i2) ? 0 : -1);
});
// get the last element of the now-sorted cumulativePossibilities,
// which will be the largest number represented by the possible strings
// or will be null if there are none
string largest = cumulativePossibilities.Last();
// return the largest or "-1" if there were 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 to find largest palindrome of the string
// representation of the number after k replacements of characters
Console.WriteLine(LargestPalindrome(number,k));
}
}
答案 0 :(得分:0)
方法效率不高,但实施简单;关键功能是使用PalindromeSubstitutions
(计算多少字符&#39;替换可防止字符串为回文)而不是IsPalindrome
(只是一个事实如果字符串是回文或不是)
// How many characters should be substituted in order to
// turn the string into palindrom
private static int PalindromeSubstitutions(string value) {
if (string.IsNullOrEmpty(value))
return 0;
int result = 0;
for (int i = 0; i < value.Length / 2; ++i)
if (value[i] != value[value.Length - 1 - i])
result += 1;
return result;
}
// Let's test all substrings of size Length, Length - 1, ... , 2, 1
// until we find substring with required tolerance
private static string BestPalindromeSubstitutions(string value, int tolerance) {
for (int size = value.Length; size >= 1; --size)
for (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);
for (int i = 0; i < value.Length / 2; ++i)
sb[value.Length - 1 - i] = sb[i];
return sb.ToString();
}
测试:
string input = "73943";
string best = BestPalindromeSubstitutions(input, 1);
string report =
string.Format("Best palindrome {0} -> {1}", best, SubstituteToPalindrome(best));
输出
Best palindrome 3943 -> 3993
答案 1 :(得分:0)
问题是贪婪算法的一个非常简单的例子。让我们首先计算需要多少排列(至少)将数字转换为回文数。
int req = 0;
for(int i = 0; i <= (s.length()-1)/2; i++){
if (s[i] != s[s.length()-1-i] && i != s.length()-1-i) req++;
}
现在完成后,让我们再次从左到右依次检查数字:i
经过0
到(s.length()-1)/2
。考虑以下情况(这里i
不是中间字母,我们单独考虑的情况):
s[i] == s[s.length()-i-1]
,它未计入req
,因此如果k >= req + 2
和s[i] != '9'
,我们会将这两个字母更改为'9'
,并减少{{} 1}}由2,k
保持不变。但请注意,我们保证有足够的操作来确保该号码可以变成回文(如果最初可能的话)req
- 现在如果s[i] != s[s.length()-i-1]
或其中一个字母为k == req
,请执行以下操作:'9'
。按s[i]=s[s.length()-i-1]=max({s[i], s[s.length()-i-1]})
减少k
和req
。1
且两个字母都不是k > req
,我们会将它们都更改为'9'
。 9
,k -= 2
。现在,如果req -= 1
和i = s.length()-i-1
,请将此字母k > 0
更改为s[i]
。
你最终得到的结果是你正在寻找的。
总复杂度为'9'
。