假设我们有一个整数列表,例如:
L = [13,13,4,13,4,2]
我想找到所有回文的集合,其中每个回文是L
的子列表,其中包含连续的整数。对于上面的列表,将是:
S = {[13], [4], [2], [13,13], [13,4,13], [4,13,4]}
因为L
的倒数为L' = [2,4,13,4,13,13]
,并且S
的每个元素都以正确的顺序出现在L'
中。
我一般如何找到所有回文集?我幼稚的方法是检查L
的幂集的每个元素是否出现在L'
中,但这效率低下,我相信有更好的解决方案。
答案 0 :(得分:2)
我认为我的解决方案与 MC Emperor 的解决方案非常相似,但我专注于不创建诸如列表之类的临时对象。
我使用left
和right
索引选择给定数组的子数组,并检查回文。
public static Set<List<Integer>> findAllPalindromes(int[] arr) {
Set<List<Integer>> res = new LinkedHashSet<>();
for (int length = 1; length < arr.length; length++)
for (int left = 0, right = left + length - 1; right < arr.length; left++, right++)
if (isPalindrome(arr, left, right))
res.add(sublist(arr, left, right));
return res;
}
此方法检查是否具有子阵列回文:
private static boolean isPalindrome(int[] arr, int left, int right) {
for (; left < right; left++, right--)
if (arr[left] != arr[right])
return false;
return true;
}
此方法为给定的子数组创建单独的列表:
private static List<Integer> sublist(int[] arr, int left, int right) {
List<Integer> res = new ArrayList<>(right - left);
for (; left <= right; left++)
res.add(arr[left]);
return res;
}
答案 1 :(得分:0)
您需要执行两个步骤。
首先,您需要找到列表中的所有子列表:
List<Integer> input = Arrays.asList(13, 13, 4, 13, 4, 2);
List<List<Integer>> subLists = new ArrayList<>();
for (int subListSize = 1; subListSize < input.size(); subListSize++) {
for (int startIndex = 0; startIndex < input.size() - subListSize + 1; startIndex++) {
List<Integer> subList = input.subList(startIndex, startIndex + subListSize);
subLists.add(subList);
}
}
// Also test the whole list:
subLists.add(input);
然后,如果列表是回文,则需要检查每个元素。要测试列表是否为回文,必须将元素n
与元素listSize - 1 - n
进行比较。
我们只需要检查一半的元素。
static boolean isPalindrome(List<Integer> subList) {
for (int i = 0; i < subList.size() / 2; i++) {
if (!Objects.equals(subList.get(i), subList.get(subList.size() - 1 - i))) {
return false;
}
}
return true;
}
如果要删除重复项,则可以将元素放入Set
中。