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