题目:判断一个链表是否是回文结构。在删除倒数第k个节点(从1开始)后,是否为回文结构。
(回文结构:从头到尾遍历节点的值序列结果,与从尾到头遍历的值序列结果是一样的)
示例 1:
输入: 1->2->5->8->2->1, k=4
输出: false true
我的思考:
一个链表是否回文,依次比较第一个和最后一个,第二个和倒数第二······这样就可以了,
如果一个链表已经是回文,删除倒数第k个节点,再判断回文,就不要比较原来链表中已比较的节点,只需要比较变动的节点。
删除节点后是否为回文的判断,大致思路如下:
* 若原来不是回文,则从头判断
* 若原来是回文
1.删除节点在中间,还是回文,直接返回是true;
2.删除非中间的节点,从变动后节点开始判断是否为回文
对于这个删除节点k值需要分三类讨论:
- k正好是中间节点:可以直接返回true;
- k < 原链表长度的一半:从第k个节点开始判断回文;
- k > 原链表长度的一半:从第size()(原链表长度)- k个节点判断回文。
以上三种情况可以简化为一个判断:先判断是否为中间节点,是则判断为是回文;否则从第Math.min(k - 1, list.size() - k + 1)个节点(从0开始)开始判断。
当然这个简化需要考虑到原链表长度是奇数还是偶数,我就不过多赘述了,以下是我写的简陋的解答:
1 import java.util.*; 2 3 public class Palindrome { 4 private static boolean isPalindrome(List<Integer> list) { 5 for (int i = 0; i < list.size() / 2; i++) { 6 if (list.get(i).intValue() != list.get(list.size() - i - 1).intValue()) { 7 return false; 8 } 9 } 10 return true; 11 } 12 13 private static boolean isPalindrome(List<Integer> list, int k) {// k表示从第几位开始1 2 3··· 这里的list是被删除节点后的 14 for (int i = Math.min(k - 1, list.size() - k + 1); i < list.size() / 2; i++) { 15 if (list.get(i).intValue() != list.get(list.size() - i - 1).intValue()) { 16 return false; 17 } 18 } 19 return true; 20 } 21 22 // 删除链表倒数第K个元素 23 private static void removNodeByNumber(List<Integer> list, int k) { 24 list.remove(list.size() - k); 25 // Iterator<Integer> iterator = list.iterator(); 26 // for (int i = 0; iterator.hasNext(); k--) { 27 // iterator.next(); 28 // if (i == list.size() - k ) { 29 // iterator.remove(); 30 // } 31 // } 32 } 33 34 public static void main(String[] args) { 35 int[] arr = { 1, 2, 5, 8, 2, 1 }; 36 List<Integer> list = new LinkedList<>(); 37 int k = 4;// 要删除的倒数第k位 从1开始 38 boolean flag; 39 for (int n : arr) 40 list.add(n); 41 42 // System.out.println(list.toString() + list.size()); 43 flag = isPalindrome(list); 44 System.out.println(flag); 45 /* 46 * 若原来不是回文,则从头判断 47 * 若原来是回文 48 * 1.删除节点在中间,还是回文 49 * 2.删除非中间的节点,从第i=min(k-1, size()-k)开始判断回文 50 */ 51 if (k <= 0 || k > list.size() ) { 52 throw new IllegalArgumentException("k值异常"); 53 } 54 if (!flag) { 55 removNodeByNumber(list, k); 56 // System.out.println(list.toString() + list.size()); 57 System.out.println(isPalindrome(list)); 58 } else if (k == list.size()/2 + list.size() % 2 || list.size() % 2 == 0 && k == list.size()/2 + 1) { 59 System.out.println(flag); 60 removNodeByNumber(list, k); 61 // System.out.println(list.toString() + list.size()); 62 } else { 63 removNodeByNumber(list, k); 64 // System.out.println(list.toString() + list.size()); 65 System.out.println(isPalindrome(list, k)); 66 } 67 } 68 }