为什么我不能删除链表中的事件?

时间:2017-03-15 15:37:44

标签: java algorithm data-structures linked-list

问题:在给定值的情况下,从链接列表中删除该值的所有实例。 以下更多信息: 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)

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

3 个答案:

答案 0 :(得分:1)

有几个问题:

  • 你想循环直到节点为空,直到不为空(即while( ... != null)
  • 您可能希望循环直到n为空,直到n.next为空,否则您将跳过最后一个元素
  • 您要检查n.val == val而不是n.next.val == val,否则您将跳过第一个元素
  • 如果您选中n,则需要跟踪上一个节点,以防需要删除n,即prev.next = n.next
  • 如果要移除第一个元素(头部),则需要更换头部,即返回第二个元素(这可以通过选中prev == null来完成,这意味着n是现任主管)。

答案 1 :(得分:0)

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

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;
}

答案 2 :(得分:0)

使用适当的测试用例解决这些问题始终是一种很好的做法。设计可能的测试用例,包括角落案例。然后按照您的算法查看它是否解决了测试用例的问题。编写代码并干运行,这将对代码和逻辑进行健全性检查。

以下是必须编写测试用例的此问题的案例。

  1. 空列表,
  2. 列出一个元素,值等于要删除的值
  3. 列出一个元素且值不等于要删除的值
  4. 列出两个元素,第一个节点值等于要删除的值
  5. 列出两个元素,最后一个节点值等于要删除的值
  6. 列出三个元素,第一个节点值等于要删除的值
  7. 包含三个元素的列表,第二个节点值等于要删除的值
  8. 列出三个元素,最后一个节点值等于要删除的值
  9. 以下是在链表中删除具有给定值的节点的问题的代码。

    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;
    }