CareerCup之2.1无序链表删除重复元素

【题目】

原文:

2.1 Write code to remove duplicates from an unsorted linked list.

FOLLOW UP

How would you solve this problem if a temporary buffer is not allowed?

译文:

从一个未排序的链表中移除重复的项

进一步地,

如果不允许使用临时的缓存,你如何解决这个问题?

【分析】

(1)如果可以使用额外的存储空间,我们就开一个数组来保存一个元素的出现情况。 对于这种情况,最好的解决方法当然是使用哈希表,但令人非常不爽的是C++标准里是没有 哈希表的(java里有)。所以,在这用一个数组模拟一下就好了。但,这里要注意一个问题, 就是元素的边界,比如链表里存储的是int型变量。那么,如果有负值,这个方法就不奏效 了。而如果元素里的最大值非常大,那么这个数组也要开得很大,而数组中大部分空间是用 不上的,会造成空间的大量浪费。

简言之,如果可以用哈希表,还是用哈希表靠谱。

如下代码遍历一遍链表即可,如果某个元素在数组里记录的是已经出现过, 那么将该元素删除。时间复杂度O(n):

(2)

如果不允许使用临时的缓存(即不能使用额外的存储空间),那需要两个指针,cur做正常的迭代,runner指针遍历cur指针之前的所有元素,判断当前元素的值是否已经出现过。如果出现过就删除cur指向的元素。

【代码一】

/*********************************
*   日期:2014-05-17
*   作者:SJF0115
*   题目: Set Matrix Zeroes
*   来源:CareerCup
**********************************/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

#define N 100000

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

bool Hash[N];

ListNode* DeleteDuplicatesFromUnSortedList(ListNode *head) {
    if(head == NULL || head->next == NULL){
        return head;
    }
    memset(Hash,0,sizeof(Hash));
    ListNode* pre = head;
    ListNode* cur = head->next;

    while(cur != NULL){
        //存在重复元素删除
        if(Hash[cur->val]){
            ListNode* node = cur;
            pre->next = cur->next;
            cur = cur->next;
            delete node;
        }
        else{
            Hash[cur->val] = true;
            pre = cur;
            cur = cur->next;
        }
    }
    return head;
}

int main(){
    int i,j;
    //freopen("C:\\Users\\XIAOSI\\Desktop\\acm.txt","r",stdin);
    ListNode *head = (ListNode*)malloc(sizeof(ListNode));
    head->next = NULL;
    ListNode *node;
    ListNode *pre = head;

    int A[] = {6,5,3,3,6,5,6,7,3,7,1,2,1,4,6,7,2,3};

    for(int i = 0;i < 18;i++){
        node = (ListNode*)malloc(sizeof(ListNode));
        node->val = A[i];
        node->next = NULL;
        pre->next = node;
        pre = node;
    }

    head = DeleteDuplicatesFromUnSortedList(head);

    ListNode* cur = head->next;
    while(cur != NULL){
        printf("%d ",cur->val);
        cur = cur->next;
    }
    return 0;
}

【代码二】

/*********************************
*   日期:2014-05-17
*   作者:SJF0115
*   题目: Set Matrix Zeroes
*   来源:CareerCup
**********************************/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

ListNode* DeleteDuplicatesFromUnSortedList(ListNode *head) {
    if(head == NULL || head->next == NULL){
        return head;
    }
    ListNode* pre = head;
    ListNode* cur = head->next;
    //删除重复元素
    while(cur != NULL){
        ListNode* runner = head->next;
        //判断是否是重复
        while(runner != cur){
            if(runner->val == cur->val){
                ListNode* node = cur;
                //删除node
                pre->next = cur->next;
                cur = pre->next;
                delete node;
                break;
            }
            runner = runner->next;
        }
        //如果上面没有删除元素,需要更新指针
        if(runner == cur){
            pre = cur;
            cur = cur->next;
        }
    }
    return head;
}

int main(){
    int i,j;
    //freopen("C:\\Users\\XIAOSI\\Desktop\\acm.txt","r",stdin);
    ListNode *head = (ListNode*)malloc(sizeof(ListNode));
    head->next = NULL;
    ListNode *node;
    ListNode *pre = head;

    int A[] = {6,5,3,3,6,5,6,7,3,7,1,2,1,4,6,7,2,3};
    //输入
    for(int i = 0;i < 18;i++){
        node = (ListNode*)malloc(sizeof(ListNode));
        node->val = A[i];
        node->next = NULL;
        pre->next = node;
        pre = node;
    }
    //删除重复元素
    head = DeleteDuplicatesFromUnSortedList(head);
    //输出
    ListNode* cur = head->next;
    while(cur != NULL){
        printf("%d ",cur->val);
        cur = cur->next;
    }
    return 0;
}

CareerCup之2.1无序链表删除重复元素

时间: 2025-01-15 22:24:28

CareerCup之2.1无序链表删除重复元素的相关文章

链表有环判断,快慢指针两种方法/合并链表/删除重复元素/二分递归和while

public static boolean hasCycle(ListNode head) { if (head == null || head.next == null) { return false; } ListNode slow = head; ListNode fast = head.next; while (slow != fast) { if (slow.next == null) return false; slow = slow.next; if (fast.next == n

【LeetCode-面试算法经典-Java实现】【082-Remove Duplicates from Sorted List II(排序链表中删除重复元素II)】

[082-Remove Duplicates from Sorted List II(排序链表中删除重复元素II)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example, Given 1->2->

数据结构之 线性表---单链表的操作B(先逆序+再删除重复元素)

数据结构上机测试2-2:单链表操作B Time Limit: 1000MS Memory limit: 65536K 题目描述 按照数据输入的相反顺序(逆位序)建立一个单链表,并将单链表中重复的元素删除(值相同的元素只保留最后输入的一个). 输入 第一行输入元素个数n: 第二行输入n个整数. 输出 第一行输出初始链表元素个数: 第二行输出按照逆位序所建立的初始链表: 第三行输出删除重复元素后的单链表元素个数: 第四行输出删除重复元素后的单链表. 示例输入 10 21 30 14 55 32 63

c++ 链表删除重复的数据

//List.h #include <iostream> typedef int dataType; struct Node{ Node():data(0),pNextNode(NULL){} //结点构造函数 dataType data; Node* pNextNode; }; class List{ private: Node *head; //作为链表唯一的头指针 int size; //链表长度 public: List(){head=new Node;size=0;} bool is

删除排序链表的重复元素(Java实现)

1.删除排序链表的重复元素I 1.1题目: 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 示例 1: 输入: 1->1->2输出: 1->2 示例 2: 输入: 1->1->2->3->3输出: 1->2->3 代码结果: /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(i

C语言 &#183; 删除重复元素

算法提高 11-2删除重复元素 时间限制:10.0s   内存限制:256.0MB 问题描述 为库设计新函数DelPack,删除输入字符串中所有的重复元素.不连续的重复元素也要删除. 要求写成函数,函数内部使用指针操作. 样例输入 1223445667889 样例输出 13579 样例输入 else 样例输出 ls 数据规模和约定 字符串数组最大长度为100. 1 /* 2 思路: 3 将字符串存入字符数组a中,设将值拷贝给数组b,遍历b的每个元 4 素,与a中的每个元素比较,有相同则b中对应元

iOS数组的去重,判空,删除元素,删除重复元素 等

一: 去重 有时需要将NSArray中去除重复的元素,而存在NSArray中的元素不一定都是NSString类型.今天想了想,加上朋友的帮助,想到两种解决办法,先分述如下. 1.利用NSDictionary的AllKeys(AllValues)方法 可以将NSArray中的元素存入一个字典,然后利用AllKeys或者AllValues取得字典的所有键或值,这些键或值都是去重的. 示例代码: NSArray *arr = @[@111,@222,@111]; NSMutableDictionary

list删除重复元素

方法一:循环元素删除// 删除ArrayList中重复元素public static void removeDuplicate1(List list) {for ( int i = 0 ; i < list.size() - 1 ; i ++ ) {for ( int j = list.size() - 1 ; j > i; j -- ) {if (list.get(j).equals(list.get(i))) {list.remove(j);}}}System.out.println(li

arrayList的合并以及删除重复元素

arrayList的合并: package listTest;//arrayList的合并 import java.util.ArrayList; public class arrayListTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub addList(); } private static void addList() { int i