【问题标题】:Check if a linkedlist is palindrome (Recursively)检查链表是否为回文(递归)
【发布时间】:2014-06-21 07:05:37
【问题描述】:

我正在尝试使用下面的代码,但结果总是true;

public boolean isPallindrome(Link link, Link right) {
    if (right == null)
        return true;

    if (!isPallindrome(link, right.getNext())) {
        return false;
    }
    boolean isP1 = right.getData() == link.getData();
    link = link.getNext();
    return isP1;
}

调用:-

System.out.println(link1.isPallindrome(link1.getFirst(), link1.getFirst()));

我认为罪魁祸首是从 rightnull 进行检查的返回值。它可能总是返回true。有人可以建议如何解决这个问题。

【问题讨论】:

  • abcba 是回文,因为ith 字符等于n - ith 字符。您需要检查方法的每次调用的两个方向,但很难说Links 是如何传入的(甚至它们代表什么)。 似乎您正在检查ith 字符是否等于ith 字符,当然它始终是true
  • 你能告诉我们链接是在哪里定义的,或者显示它的定义吗?是单链表还是双链表?
  • 你应该接受这个问题的答案,因为这个页面的浏览量很高,如果问题接受了答案,人们可​​以很容易地找到答案,请接受最高票数的答案,因为它帮助了更多的人人

标签: java algorithm recursion data-structures linked-list


【解决方案1】:

这就是你的算法的样子

boolean flag=true;
public boolean checkPalindrome(List nodeList,boolean flag)
{
    if(flag==false)
        return false;
    if(nodeList.right==null)
        return flag;
    else{
        Node n;//reference for travelling till last node
        //traverse till last node

        //check first and last node

        if(same){
            //delete both nodes;
        }
        else{
            flag=false;
        }
        return checkPalindrome(nodeList,flag)

    }
}

这只是一个你需要向前推进的指针。

如果您再次需要原始列表,那么您可能希望将列表内容复制到其他对象中并在此方法中使用该对象

希望这会有所帮助!

祝你好运!

【讨论】:

  • 如果你只是跟踪一个指向每一端的指针,那么你不需要删除。你也可以return 而不是使用flag
  • 因为它是递归的,所以我们不能保证最后一个元素是否事先与其他元素进行了检查,而且我们也不知道(从问题中)它是否是双向链表,所以我们不能回溯也是。所以认为删除可能是一种中途的方法。
  • 除非问题明确提及,否则我认为我们不应该修改链表。如前所述,正确的是下面的一些 cmets 不需要删除/修改链表。
【解决方案2】:

我可以采用你的方法。 你想要link.getNext() 应该对它之前的调用产生影响。 你能行的。只需更改函数原型即可。

public boolean isPallindrome(Link &link, Link right);

确保您的初始通话没有受到影响。

【讨论】:

    【解决方案3】:

    问题出在:
    链接 = 链接.getNext(); 您在这里的意图是使更改反映在所有递归反向调用中,但您最终所做的是仅在当前堆栈中本地更改引用,发布左链接未反映在后续调用中。

    如果是 C、C++,您可以将参数设置为 Link** left、Link *right 但是对于引用,您需要将左链接设为静态外部。

    【讨论】:

      【解决方案4】:

      老实说,我不遵循您方法的一般逻辑。我想提出一个完全不同的建议,并添加一些假设。

      有问题的列表是双向链接的吗?如果是这样,那么您可以从两端遍历它,从外部向假设回文的任一端工作。如果结果不匹配,那么列表显然不是回文。

      【讨论】:

        【解决方案5】:

        您应该使用 Java 实用程序类(或至少实现接口),并且一定要为 api 添加书签。如果你有一个双向链表(Java 将其称为双端队列),则查找回文串是最快的。不幸的是,这种方法破坏了原件。

        public static boolean <E> isPallindrome(Deque<E> deque) {
            if ( deque.size() <= 1 ) {
                return true;
            }
            E first = deque.removeFirst();
            E last = deque.removeLast();
            if ( deque.size() == 0 ) {
                return first.equals(last);
            }
            return isPallindrome(deque)
        }
        

        如果你想更高级,可以使用迭代器,跳过递归。

        如果您只有一个链接列表,那么您需要一种到达列表末尾的方法。一种方法是跟踪列表的大小。这最终是O(n^2),因为所有getting。

        public static boolean isPallindrome(List<?> list, int size) {
            if ( size <= 1 ) {
                return true;
            }
            if ( ! list.get(0).equals(list.get(size-1)) ) {
                return false;
            }
            return isPallindrome(list.subList(1,size-1));
        }
        

        【讨论】:

          【解决方案6】:

          问题在于您的左指针移动。您将需要在 Java 中使用左指针上的某个容器来刺激双指针(或称其为按引用传递)(始终按值传递)。让我们使用大小为 1 的数组作为容器,它将起作用。我在这里使用不同的名称。

          public class LinkedListS<T> {
          
              protected Node head;
              public boolean isPalindrome()
              {
                  Node storeHead = head;
                  boolean result = isPalindromeUtil(new Node[]{head},head); //have to stimulate pass by reference
                  head = storeHead;
                  return result;
              }
          
              private boolean isPalindromeUtil(Node[] left,Node right)
              {
                  if(right==null)
                      return  true;
          
                  boolean subResult = isPalindromeUtil(left,right.next);
                  if (subResult==false)
                      return false;
          
                  boolean dataCompareResultForCurrentPosition = false;
                  if(left[0].data == right.data)
                      dataCompareResultForCurrentPosition = true;
          
                  left[0]=left[0].next; //critical
          
                  return dataCompareResultForCurrentPosition;
              }
          }
          

          【讨论】:

            【解决方案7】:
                public class PalindromeList {
                static Node left;
                public static void main(String[] args) {
                    Node node = new Node(5);
                    Node node1 = new Node(4, node);
                    Node node2 = new Node(7, node1);
                    Node node4 = new Node(6, node2);
                    Node node5 = new Node(5, node4);
                    left = node5;
                    System.out.println(isPalindrome(node));
                }
            
            
                static boolean isPalindrome(Node right) {
                    if (right == null)
                        return true;
                    boolean isp = isPalindrome(right.next);
                    if (isp == false)
                        return false;
                    boolean isp1 = (right.value == left.value);
                    left = left.next;
                    return isp1;
                }
            }
            

            【讨论】:

              【解决方案8】:

              实际上不断缩小列表。 在下面的代码中,第一次调用将把 head 作为第一个,将 null 作为最后一个。 在随后的调用中,first 将变为 first.next,last 将变为 last,但一个节点的地址字段在列表中的值。

              boolean palindromeCheck(List first, List last)
              {
                  //For even size of List
                  if(first == last)
                      return true;
                  //For odd size of List.
                  if(first.next == last)
                      return true;
                  List newLast = first.next;
                  //Traverse till last element.
                  while(newLast.next != last)
                      newLast = newLast.next;
                  //If value is not same, return false.
                  if(first.val != newLast.val)
                      return false;
                  return palindromCheck( first.next, newLast );
              }
              

              【讨论】:

              • 这是一种完全不同的方法。
              猜你喜欢
              • 2017-12-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-04-24
              • 2012-07-14
              相关资源
              最近更新 更多