递归删除链表中的最后一个匹配项Java

递归删除链表中的最后一个匹配项Java,java,algorithm,recursion,Java,Algorithm,Recursion,我被要求编写一个递归方法来删除某个值的最后一次出现,比如4 在2->3->4->5->4->2之前 在2->3->4->5->2之后 只有最后一次发生。我知道如何删除所有事件,但我不知道它是否是最后一个事件。不允许使用帮助器方法 删除所有事件的一个 class Link{ private int value; private Link next; } 您可以声明指向上次出现的节点的指针,并在到达列表中的最后一个元素时删除该节点。以下步骤说明— 声明两个指针,一个是下一个,就像上

我被要求编写一个递归方法来删除某个值的最后一次出现,比如4

在2->3->4->5->4->2之前 在2->3->4->5->2之后

只有最后一次发生。我知道如何删除所有事件,但我不知道它是否是最后一个事件。不允许使用帮助器方法

删除所有事件的一个

class Link{
    private int value;
    private Link next;
}

您可以声明指向上次出现的节点的指针,并在到达列表中的最后一个元素时删除该节点。以下步骤说明—

  • 声明两个指针,一个是下一个,就像上面的代码一样,另一个可以是temp
  • 像上面的deleteAll方法一样,使用next遍历列表
  • 如果找到要查找的节点,请在案例4中将该节点分配给临时节点
  • 当next为null时,您到达列表末尾now delete,temp中的任何节点都将删除该节点。如果temp仍然为null,则在给定密钥中找不到节点
  • 编辑: 递归情况下可能出现的伪代码:

    public Link deleteAll(){
        if (next == null){
            return value==4? null:this;
        }else{
            if (value == 4){
                return next.deleteAll();
            }
            next = next.deleteAll();
            return this;
        }
    }
    
    以上代码应该能够解决您的问题。我在我的方法中做了一些修改,这从代码中应该很明显,但让我在下面描述一下

    • 我添加了一个prev指针。因为如果我们想删除一个特定的节点,我们需要将它的next分配给prev节点的next。因此,我们需要的是prev节点,而不是要删除的节点

    我认为这种改变也会在迭代方法中遵循。

    没有真正回答你的确切问题,但作为另一种选择,你可以考虑以下内容:

    编写一个递归方法来删除指定值的第一个匹配项,如下所示:

        public void deleteLast(Node node,Node temp,Node prev, int data)
        {
            if(node==null)
            {
              if(temp!=null && temp.next.next!=null){
              temp.next = temp.next.next;}
              if(temp.next.next==null)
              temp.next = null;
              return;
            }
            if(node.data==data)
            {
              temp = prev;
            }
    
            prev = node;
            deleteLast(node.next, temp, prev, int data);
    
        }
    
    public Link deleteFirst(int target) {
      if (value == target) {
        return next;
      }
      next = (next == null) ? null : next.deleteFirst(target);
      return this;
    }
    
    然后您可以编写一个
    reverse()
    方法,作为您认为合适的迭代或递归方法。我没有包括这一点,但谷歌搜索应该会显示一些有用的想法

    最后,从链表中删除最后一次出现的值的方法可以这样写:

        public void deleteLast(Node node,Node temp,Node prev, int data)
        {
            if(node==null)
            {
              if(temp!=null && temp.next.next!=null){
              temp.next = temp.next.next;}
              if(temp.next.next==null)
              temp.next = null;
              return;
            }
            if(node.data==data)
            {
              temp = prev;
            }
    
            prev = node;
            deleteLast(node.next, temp, prev, int data);
    
        }
    
    public Link deleteFirst(int target) {
      if (value == target) {
        return next;
      }
      next = (next == null) ? null : next.deleteFirst(target);
      return this;
    }
    

    请注意,只要您的
    reverse()
    方法是线性复杂度,此操作也将是线性复杂度,尽管常数将高于所需值。

    诀窍是在返回的过程中完成此工作-根本不需要额外的参数、帮助或假设:

    public Link deleteLast(int target) {
      return reverse().deleteFirst(target).reverse();
    }
    

    你有完整的代码和列表初始化吗?这听起来像一个学校项目。因为数据结构不是嵌套的,所以任何理智的人都不会使用递归来解决这个问题(至少如果语言是Java的话不会)。我认为这项任务的想法是,您尝试编写一些代码,然后自己解决这个问题;)<代码>无助手方法。您不允许编写和调用其他方法,或者您不允许使用Internet上的LinkedList jar?@EricDuminil都不允许。只有这一个方法。这很有趣。但是它不适合递归方法,是吗?您需要对列表进行两次解析,才能返回到要删除的节点。您是对的,我的答案并不是针对递归方法的。不过,也可以将其用于递归算法。让我试着给出一个伪代码。请注意,添加参数也允许您通过使用一个参数进行分派来基本上模拟多个方法——因此我怀疑这是否有效,因为赋值的精神是。。。