2017-03-15 76 views
-2

问题:给定一个值,从链表中删除该值的所有实例。 下面更多信息: JAVA为什么我不能删除链接列表中的事件?

/** 
* Definition for singly-linked list. 
* public class ListNode { 
*  int val; 
*  ListNode next; 
*  ListNode(int x) { val = x; } 
* } 
*/ 
public class Solution { 
    public ListNode removeElements(ListNode head, int val) { 
     ListNode n = head; //1, 2, 6, 3, 4, 5, 6 
     while(n.next == null){ 
      if(n.next.val == val){ 
       n.next = n.next.next; 
      } 
      n = n.next; 
      if(n == null){break;} 
     } 
     return head; 
    } 
} 

自通的参考,应更新不应该吗?

我想:

removeElements([1,2,6,3,4,5,6], 6) 

但它并没有删除任何东西。那么我做错了什么?

+0

https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value –

+2

监守它应该是同时(n.next!= NULL)你也不检查头是否包含你的价值。你错过了很多检查陈述。 –

+1

'while(n.next == null){'如果您将长度为1的列表传递给'removeElements',将会做出非常难看的事情,如果列表长度更长,则会做任何事情。 – Paul

回答

1

有几个问题:

  • 要循环,直到一个节点为null直到不为空(即while(... != null)
  • 你可能要循环,直到n为空,直到n.next为空,否则你会跳过最后一个元素
  • 要检查n.val == valn.next.val == val,否则你会跳过第一个元素
  • 如果你检查n,如果您需要删除n,即prev.next = n.next,您想跟踪前一个节点。
  • 如果要移除第一个元素(头部),则需要替换头部,即返回第二个元素(这可以通过检查prev == null来完成,这将意味着n是当前头部)。
0

正如托马斯在第一点中所提到的那样,您错误地写了while循环。另外,因为你有一个链表,所以你需要跟踪前一个节点(托马斯也提到过)。

public static ListNode removeElements(ListNode head, int val) 
{ 
    ListNode n = head; 
    ListNode prev = null; //the previous node. 
    while (n != null) 
    { 
     if (n.value == val) 
     { 
      //if prev is null it means that we have to delete the head 
      //and therefore we need to advance the head 
      if (prev == null) 
      { 
       head = n.next; 
       prev = null;//remains at null because there's nothing before head 
       n = head;//new head, let's start from here 
      } else 
      { 
       prev.next = n.next; //let's skip the element to delete 
       n = n.next;//let's advance to the next node 
      } 
     } else 
     { 
      //nothing to delete, let's advance to the next node and make 
      //the current node the previous node in the next iteration 
      prev = n; 
      n = n.next; 
     } 

    } 
    return head; 
} 
0

它总是一个很好的做法,用适当的测试案例来解决这些问题。设计可能的测试案例,包括角落案例。然后按照你的算法,看看它是否解决了测试用例的问题。编写代码并干运行它,这将对代码以及逻辑进行完整的检查。

下面是这个问题的案例必须写入测试用例。

  1. 空列表,
  2. 列表与一个元件和值等于要被删除的值
  3. 与一种元素列表和值不等于要被删除
  4. 列表有两个值元素和第一个节点值等于要删除的值
  5. 包含两个元素并且最后一个节点值等于要删除的值的列表
  6. 包含三个元素并且第一个节点值等于被删除
  7. 列表具有三个元件和第二节点值等于所述值被删除
  8. 列表具有三个元件和最后一个节点值等于要被删除

下面的值是代码针对在链表中删除具有给定值的节点的问题。

public ListNode removeElements(ListNode head, int val) { 
     while(head != null && head.val == val){ 
      head = head.next; 
     } 
     if(head == null){ 
      return null; 
     } 
     ListNode node = head; 
     while(node.next != null){ 
      if(node.next.val == val){ 
       node.next = node.next.next; 
      }else{ 
       node = node.next; 
      } 
     } 
     return head; 
} 
+0

前两行'while(head!= null && head.val == val){head = head.next; }' 这个循环完成后,节点减少了很多不是吗?假设我有'1-> 2-> 3-> 1-> null'和期望的'val = 1',那么在循环完成时'head = null'? – sssszzzzzzssszzz

+0

否,因为循环检查头部的值是否等于所需的值,然后只修改头部作为下一个节点,否则第一个循环停止。在你的情况下,head将在第一个循环后的值为2的节点上。 –

相关问题