【LeetCode】Remove x from (Un)sorted List * 4

来源:互联网 发布:java设计模式视频教程 编辑:程序博客网 时间:2024/05/29 18:17
  1. Remove Linked List Elements 删除链表中的元素
    删除链表中等于给定值val所有节点。

样例
给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1->2->4->5。

标签
链表

Java:

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) { val = x; }* }*/public class Solution {    /*    * @param head: a ListNode    * @param val: An integer    * @return: a ListNode    */    public ListNode removeElements(ListNode head, int val) {        // write your code here        ListNode dummy = new ListNode(0);        dummy.next = head;        head = dummy;        while (head.next != null) {            if (head.next.val == val) {//val为指定元素                head.next = head.next.next;//将当前下一个结点移至下下个结点            }            else {                head = head.next;            }        }        return dummy.next;    }}

2.Remove Duplicates From Unsorted List 无序链表的重复项删除
设计一种方法,从无序链表中删除重复项。(不连续的重复项也删除!但保留第一次出现的结点)

样例
给出 1->3->2->1->4.
返回 1->3->2->4

挑战
如果没有临时缓冲区,如何解决这一问题?

标签
链表

思路:可以考虑 HashSet

Java:

/*** Definition for ListNode* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) {*         val = x;*         next = null;*     }* }*/public class Solution {    /*    * @param head: The first node of linked list.    * @return: Head node.    */    public ListNode removeDuplicates(ListNode head) {        // write your code here        HashSet<Integer> hash = new HashSet<>();        ListNode dummy = new ListNode(0);        dummy.next = head;        head = dummy;        while (head.next != null) {            if (hash.contains(head.next.val)) {                head.next = head.next.next;            }            else {                hash.add(head.next.val);                head = head.next;            }        }        return dummy.next;    }
  1. Remove Duplicates From Sorted List I (删除排序链表中的重复元素 -1)
    Given a sorted linked list, delete all duplicates such that each element appear only once.

Example
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.

Tags
Linked List
Related Problems

(1)Java:

/** * Definition for ListNode * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { *         val = x; *         next = null; *     } * } */public class Solution {    /**     * @param ListNode head is the head of the linked list     * @return: ListNode head of linked list     */    public static ListNode deleteDuplicates(ListNode head) {         // write your code here        if(head == null){            return null;        }        // ListNode dummy = new ListNode(0);        // dummy.next = head;        // head = dummy;        ListNode node = head;         while(node.next != null){            if(node.val == node.next.val){                node.next = node.next.next;            }else{                node = node.next;            }        }        return head;    }  }

(2) 链表中连续重复的元素只保留一个(与上 类似):
Example
原链表:9 -> 9 -> 8 -> 8 -> 8 -> 7 -> 5 -> 3 -> 3 -> 2
结果:9 -> 8 -> 7 -> 5 -> 3 -> 2

(C++版)#include "stdafx.h"#include <iostream>#include <cstdio>using namespace std;typedef struct tagSNode{    int val;    tagSNode* pNext;    tagSNode(int v):val(v),pNext(NULL){}}SNode;void Print(SNode* sn){    SNode* p = sn->pNext;    while (p) {        if(p->pNext != NULL){            cout << p->val << " -> ";        }else{            cout << p->val ;        }        p = p->pNext;    }    cout << endl;}void Destroy(SNode* p){    SNode* next;    while (p) {        next = p->pNext;        delete p;        p = next;    }}void DeleteDuplicateNode(SNode* pHead){    SNode* pPre = pHead->pNext;    SNode* pCur;    while (pPre) {        pCur = pPre->pNext;        if(pCur && pCur->val == pPre->val){            pPre->pNext = pCur->pNext;            delete pCur;        }else{ //二者不相等(重复),则指针向后移            pPre = pCur; //重复元素只保留一个        }    }}int main(){    SNode* pHead = new SNode(0);    int data[] = {2,3,3,5,7,8,8,8,9,9,30};    int size = sizeof(data)/sizeof(int);    for(int i = 0; i < size - 1; i++){        SNode* p = new SNode(data[i]);        p->pNext = pHead->pNext;        pHead->pNext = p;    }    Print(pHead);    DeleteDuplicateNode(pHead);    Print(pHead);    Destroy(pHead);    return 0;}//Version 2void DeleteDuplicateNode2(SNode* pHead) {    SNode* pPre = pHead;    SNode* pCur = pPre->pNext;    SNode* pNext /*= pCur->pNext*/;//因为不知道pCur后面还有没有结点!    while (pCur)    {        pNext = pCur->pNext;        if (pNext && (pCur->value == pNext->value)) {            pPre->pNext = pNext;            delete pCur;            pCur = pNext;            pNext = pCur->pNext;        }else{            pPre = pCur;            pCur = pNext;        }    }}

4.Remove Duplicates From Sorted List II ( 删除排序链表中的重复数字 II )
给定一个排序链表,删除所有重复的元素, 只留下原链表中没有重复的元素
//将连续重复元素全部删除(不保留)

样例
给出 1->2->3->3->4->4->5->null,返回 1->2->5->null
给出 1->1->1->2->3->null,返回 2->3->null

(1)Java:

public class Solution {    public ListNode deleteDuplicates(ListNode head) {        if(head == null || head.next == null)            return head;        ListNode dummy = new ListNode(0);        dummy.next = head;        head = dummy;        while (head.next != null && head.next.next != null) {            if (head.next.val == head.next.next.val) {                int val = head.next.val;                while (head.next != null && head.next.val == val) {                    head.next = head.next.next;                }                        } else {                head = head.next;            }        }        return dummy.next;    }}

(2)C++:

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode *deleteDuplicates(ListNode *head) {        ListNode *root = NULL;        ListNode **ppNext = &root;        while(head) {            if(head->next == NULL || head->next->val != head->val) {                *ppNext = head;                ppNext = &(head->next);                head = head->next;            } else {                int val = head->val;                do {                    head = head->next;                } while(head != NULL && head->val == val);            }        }        *ppNext = NULL;        return root;    }};②完整版 VERSION 2#include "stdafx.h"#include <iostream>#include <cstdio>using namespace std;typedef struct tagSNode{    int value;    tagSNode* pNext;    tagSNode(int v) :value(v), pNext(NULL) {}}SNode;void DeleteDuplicateNode3(SNode* pHead) {    SNode* pPre = pHead;    SNode* pCur = pPre->pNext;    SNode* pNext /*= pCur->pNext*/;//因为不知道pCur后面还有没有结点!    bool bDup ;//不可以一上来默认定义其为false,因为循环中一旦有一次为true,后面会一直为true。    //正确做法是:将bDup在每次循坏时都重置为false!    while (pCur)    {        bDup = false;        pNext = pCur->pNext;        if (pNext && (pCur->value == pNext->value)) {            bDup = true;            pPre->pNext = pNext;            delete pCur;            pCur = pNext;            pNext = pCur->pNext;//此时,已经将重复的数据删除,并指针后移了一次        }        if (bDup) {            pPre->pNext = pNext;//将上一结点的下位指向当前结点(被重复)的下位            delete pCur;//同上,再删除一次(自身)        }        else {//pCur未发现重复,则pPre后移            pPre = pCur;        }        //pCur = pCur->pNext; //WRONG!!! 万一 pCur下一个结点为NULL呢?        pCur = pNext;    }}void Print(SNode* sn) {    SNode* p = sn->pNext;    while (p)    {        if (p->pNext != NULL) {            cout << p->value << " -> ";        }        else {            cout << p->value;        }        p = p->pNext;    }    cout << endl;}void Destroy(SNode* p) {    SNode* next;    while (p) {        next = p->pNext;        delete p;        p = next;    }}int main(){    SNode* pHead = new SNode(0);    int data[] = { 2,3,3,4,5,7,8,8,8,9,9,10 };    int size = sizeof(data) / sizeof(int);    //for (int i = 0; i < size - 1; i++) {     //注意链表结点的下标!!!    for (int i = size - 1; i >= 0; i--) {        SNode* p = new SNode(data[i]);        p->pNext = pHead->pNext;        pHead->pNext = p;    }    Print(pHead);    DeleteDuplicateNode3(pHead);    Print(pHead);    Destroy(pHead);    return 0;}