判断回文结构,在删除倒数第k个节点后,是否为回文结构

题目:判断一个链表是否是回文结构。在删除倒数第k个节点(从1开始)后,是否为回文结构。

(回文结构:从头到尾遍历节点的值序列结果,与从尾到头遍历的值序列结果是一样的)

示例 1:

输入: 1->2->5->8->2->1, k=4

输出: false  true

 

我的思考:

一个链表是否回文,依次比较第一个和最后一个,第二个和倒数第二······这样就可以了,

如果一个链表已经是回文,删除倒数第k个节点,再判断回文,就不要比较原来链表中已比较的节点,只需要比较变动的节点。

 

删除节点后是否为回文的判断,大致思路如下:

  * 若原来不是回文,则从头判断
  * 若原来是回文
    1.删除节点在中间,还是回文,直接返回是true;
    2.删除非中间的节点,从变动后节点开始判断是否为回文

  对于这个删除节点k值需要分三类讨论:

  1. k正好是中间节点:可以直接返回true;
  2. k <  原链表长度的一半:从第k个节点开始判断回文;
  3. 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 }
未经授权商用禁止,转载请标明出处,附上原文链接 个人能力有限,若有不足之处欢迎各位大佬指出
原文地址:https://www.cnblogs.com/pong137/p/12751321.html