LeetCode:First unique number

problem

You have a queue of integers, you need to retrieve the first unique integer in the queue.
Implement the FirstUnique class:
FirstUnique(int[] nums) Initializes the object with the numbers in the queue.
int showFirstUnique() returns the value of the first unique integer of the queue, and returns -1 if there is no such integer.
void add(int value) insert value to the queue.

solution

方法一

思路过程
设计数据结构,用list存储数字,用unique来表示唯一的数字,没有赋值-1
初始化 情况为空和一个数字,多个数字
怎么找到那唯一一个不同的数字:
暴力,每个都查找一遍
add的时候,如何确定添加的数字是不是有让unique改变
判断当前的数字是否和unique相等,相等就查找下一个,不相等不变
因为只有add,所以应当保持填入的序列不变,用一个position记录当前的unique的位置,之前的位置肯定时没有的
那如果我开辟两个集合,一个存入有多个的,一个存入只有一个的,每当发现有重复的添加进来,就把它移到重复的集合中

代码

python

class FirstUnique:

    def __init__(self, nums):
        self.duplicate=set()
        # 必须要有序呀
        self.unique=[]
        self.uniquenumber=-1
        for i in nums:
            if i in self.unique:
                self.duplicate.add(i)
                self.unique.remove(i)
            elif i not in self.duplicate:
                self.unique.append(i)
        if self.unique:
            self.uniquenumber=self.unique.pop(0)

    def showFirstUnique(self) -> int:
        return self.uniquenumber

    def add(self, value: int) -> None:
        if value==self.uniquenumber:
            self.duplicate.add(value)
            if self.unique:
                self.uniquenumber=self.unique.pop(0)
            else :
                self.uniquenumber=-1
        elif value in self.unique:
            self.unique.remove(value)
            self.duplicate.add(value)
        elif value not in self.duplicate:
            if self.uniquenumber==-1:
                self.uniquenumber=value
            else:
                self.unique.append(value)

提交时出错,发现忽略了同时为空的情况,继续修改
time limited,结果超时了

方法二

思路
集合是无序的,但是查找快,而列表是有序的,查找慢,要把列表替换掉,因为列表得查找实在是太慢了
如何保持有序而又查找又快呢?
lettcode中给的hint有些没有看懂
按照提示,创建一个双向环链表,这样可以在有序中快速查找
但是在查找中出logn的,只有字典和集合
我想到以前我做过的一个LeetCode题目,里面得数据结构设计就刚好能完成这样的操作,结构灵活

代码

python

class LinkNode:
    def __init__(self, value=None):
        self.val = value
        self.pre = None
        self.next = None


class FirstUnique:
    def deltetnode(self, node) :
        node.pre.next = node.next
        node.next.pre = node.pre

    def placetoend(self, num):
        node = LinkNode(num)
        node.next = self.head
        node.pre = self.head.pre
        self.head.pre.next = node
        self.head.pre = node
        return node


    def operate(self,value):
        # 如果value在unique中,不需要判断第一个节点了,直接删掉就好
        # 并把返回的值放进duplicate中,删掉在字典中的值
        if value in self.unique:
            self.deltetnode(self.unique[value])
            self.duplicate.add(value)
            del self.unique[value]
        # 如果也不再duplicate中的话,就要把value放到链表末尾
        # 并添加值
        elif value not in self.duplicate:
            self.unique[value] = self.placetoend(value)

    def __init__(self, nums: List[int]):
        self.head = LinkNode()
        self.head.pre = self.head
        self.head.next = self.head
        self.duplicate = set()
        self.unique = {}
        for i in nums:
            self.operate(i)

    def showFirstUnique(self) -> int:
        # 表示链表不为空的话
        if self.head.next != self.head:
            return self.head.next.val
        else:
            return -1

    def add(self, value: int) -> None:
        self.operate(value)

Java

public class FirstUnique {
    LinkNode head = new LinkNode();
    HashMap<Integer, LinkNode> unique = new HashMap<>();
    HashSet<Integer> duplicate = new HashSet<>();

    private class LinkNode {
        int val = -1;
        LinkNode next = null;
        LinkNode pre = null;

        public LinkNode() {

        }

        public LinkNode(int val) {
            this.val = val;
        }
    }

    public void delete(int value ) {
        LinkNode node=unique.remove(value);
        duplicate.add(value);
        node.next.pre = node.pre;
        node.pre.next = node.next;
    }

    public void placeToEnd(int num) {
        LinkNode node = new LinkNode(num);
        node.next = head;
        node.pre = head.pre;
        head.pre.next = node;
        head.pre = node;
        unique.put(num,node);
    }

    public void operate(int value) {
        if (this.unique.containsKey(value)) {
            delete(value);

        } else if (!this.duplicate.contains(value)) {
            placeToEnd(value);
        }
    }

    public FirstUnique(int[] nums) {
        head.next = head;
        head.pre = head;
        for (int i : nums) {
            operate(i);
        }

    }

    public int showFirstUnique() {
//        环,头节点指向自己
        if (head.next != head) {
            return head.next.val;
        }
        return -1;
    }

    public void add(int value) {
        operate(value);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值