【LeetCode】設計題 design(共38題)

連接:https://leetcode.com/tag/design/算法

【146】LRU Cache 數組

 

【155】Min Stack 緩存

 

【170】Two Sum III - Data structure design (2018年12月6日,週四)dom

Design and implement a TwoSum class. It should support the following operations: add and find.ide

add - Add the number to an internal data structure.
find - Find if there exists any pair of numbers which sum is equal to the value.學習

Example 1:
add(1); add(3); add(5);
find(4) -> true
find(7) -> false
Example 2:
add(3); add(1); add(2);
find(3) -> true
find(6) -> false

題解:無this

 1 class TwoSum {
 2 public:
 3     /** Initialize your data structure here. */
 4     TwoSum() {
 5         
 6     }
 7     
 8     /** Add the number to an internal data structure.. */
 9     void add(int number) {
10         nums.push_back(number);
11         mp[number]++;
12     }
13     
14     /** Find if there exists any pair of numbers which sum is equal to the value. */
15     bool find(int value) {
16         for (auto ele : nums) {
17             int target = value - ele;
18             if (mp.find(target) != mp.end()) {
19                 if (target == ele && mp[target] >= 2 || target != ele && mp[target] >= 1) {
20                     return true;
21                 }
22             }
23         }
24         return false;
25     }
26     vector<int> nums;
27     unordered_map<int, int> mp;
28 };
29 
30 /**
31  * Your TwoSum object will be instantiated and called as such:
32  * TwoSum obj = new TwoSum();
33  * obj.add(number);
34  * bool param_2 = obj.find(value);
35  */
View Code

 

【173】Binary Search Tree Iterator spa

【208】Implement Trie (Prefix Tree) (之前 trie 專題作過)設計

【211】Add and Search Word - Data structure design 3d

【225】Implement Stack using Queues 

【232】Implement Queue using Stacks 

 

【244】Shortest Word Distance II (2019年2月12日)

Design a class which receives a list of words in the constructor, and implements a method that takes two words word1 and word2 and return the shortest distance between these two words in the list. Your method will be called repeatedly many times with different parameters. 

Example:

Assume that words = ["practice", "makes", "perfect", "coding", "makes"].

Input: word1 = 「coding」, word2 = 「practice」

Output: 3

Input: word1 = "makes", word2 = "coding"

Output: 1

題解:一個map存單詞和對應的下標列表。而後二分查找。

 1 class WordDistance {
 2 public:
 3     WordDistance(vector<string> words) {
 4         n = words.size();
 5         for (int i = 0; i < words.size(); ++i) {
 6             mp[words[i]].push_back(i);
 7         }
 8     }
 9     
10     int shortest(string word1, string word2) {
11         vector<int> & list1 = mp[word1], & list2 = mp[word2];
12         int res = n;
13         for (auto& e : list1) {
14             auto iter = upper_bound(list2.begin(), list2.end(), e);
15             if (iter != list2.end()) {
16                 res = min(res, abs((*iter) - e));
17             }
18             if (iter != list2.begin()) {
19                 --iter;
20                 res = min(res, abs((*iter) - e));
21             }
22         }
23         return res;
24     }
25     unordered_map<string, vector<int>> mp;
26     int n;
27 };
28 
29 /**
30  * Your WordDistance object will be instantiated and called as such:
31  * WordDistance obj = new WordDistance(words);
32  * int param_1 = obj.shortest(word1,word2);
33  */
View Code

 

【251】Flatten 2D Vector 

 

【281】Zigzag Iterator (2019年1月18日,學習什麼是iterator)

給了兩個一維數組,逐個返回他們的元素。

Example:
Input:
v1 = [1,2]
v2 = [3,4,5,6] 
Output: [1,3,2,4,5,6]
Explanation: By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,3,2,4,5,6].

題解:什麼是iterator,就是一個東西它有兩個方法:(1)getNext(), (2) hasNext()

本題沒有什麼好說的,直接搞就好了。

 1 class ZigzagIterator {
 2 public:
 3     ZigzagIterator(vector<int>& v1, vector<int>& v2) {
 4         n1 = v1.size();
 5         n2 = v2.size();
 6         this->v1 = v1, this->v2 = v2;
 7     }
 8     int next() {
 9         if (p1 < n1 && p2 < n2) {
10             int ret = cur == 0 ? v1[p1++] : v2[p2++];
11             cur = 1 - cur;
12             return ret;
13         }
14         if (p1 < n1) {
15             return v1[p1++];
16         } 
17         if (p2 < n2) {
18             return v2[p2++];
19         }
20         return -1;
21     }
22     bool hasNext() {
23         return p1 < n1 || p2 < n2;
24     }
25     int cur = 0;
26     int p1 = 0, p2 = 0, n1 = 0, n2 = 0;
27     vector<int> v1, v2;
28 };
29 /**
30  * Your ZigzagIterator object will be instantiated and called as such:
31  * ZigzagIterator i(v1, v2);
32  * while (i.hasNext()) cout << i.next();
33  */
View Code

 

【284】Peeking Iterator (2019年1月18日,學習什麼是iterator)

給了一個 Iterator 的基類,實現 PeekIterator 這個類。它除了有 hashNext() 和 next() 方法以外還有一個方法叫作 peek(),能訪問沒有訪問過的第一個元素,而且不讓它pass。

題解:用兩個變量保存 是否是有一個 peek 元素,peek元素是什麼。每次調用peek方法的時候先查看當前緩存有沒有這個元素,若是有的話就返回,若是沒有的話,就調用 Iterator::next方法獲取當前緩存。 

 1 // Below is the interface for Iterator, which is already defined for you.
 2 // **DO NOT** modify the interface for Iterator.
 3 class Iterator {
 4     struct Data;
 5     Data* data;
 6 public:
 7     Iterator(const vector<int>& nums);
 8     Iterator(const Iterator& iter);
 9     virtual ~Iterator();
10     // Returns the next element in the iteration.
11     int next();
12     // Returns true if the iteration has more elements.
13     bool hasNext() const;
14 };
15 
16 
17 class PeekingIterator : public Iterator {
18 public:
19     PeekingIterator(const vector<int>& nums) : Iterator(nums) {
20         // Initialize any member here.
21         // **DO NOT** save a copy of nums and manipulate it directly.
22         // You should only use the Iterator interface methods.
23         
24     }
25 
26     // Returns the next element in the iteration without advancing the iterator.
27     int peek() {
28         if (hasPeeked) {
29             return peekElement;
30         }
31         peekElement = Iterator::next();
32         hasPeeked = true;
33         return peekElement;
34     }
35 
36     // hasNext() and next() should behave the same as in the Iterator interface.
37     // Override them if needed.
38     int next() {
39         if (hasPeeked) {
40             hasPeeked = false;
41             return peekElement;
42         }
43         return Iterator::next();
44     }
45 
46     bool hasNext() const {
47         if (hasPeeked || Iterator::hasNext()) {
48             return true;
49         }
50         return false;
51     }
52     bool hasPeeked = false; 
53     int peekElement;
54     
55 };
View Code

  

【288】Unique Word Abbreviation 

【295】Find Median from Data Stream 

【297】Serialize and Deserialize Binary Tree 

【341】Flatten Nested List Iterator 

 

【346】Moving Average from Data Stream 

 

【348】Design Tic-Tac-Toe 

 

【353】Design Snake Game 

 

【355】Design Twitter 

 

【359】Logger Rate Limiter (2019年3月13日,週三)

Design a logger system that receive stream of messages along with its timestamps, each message should be printed if and only if it is not printed in the last 10 seconds.

主要就是實現這個 bool shouldPrintMessage(int timestamp, string message) 接口。

題解:用一個 map 作 cache。

 

 1 class Logger {
 2 public:
 3     /** Initialize your data structure here. */
 4     Logger() {
 5         
 6     }
 7     /** Returns true if the message should be printed in the given timestamp, otherwise returns false.
 8         If this method returns false, the message will not be printed.
 9         The timestamp is in seconds granularity. */
10     bool shouldPrintMessage(int timestamp, string message) {
11         if (cache.count(message)) {
12             if (timestamp - cache[message] < 10) {return false;}
13         }
14         cache[message] = timestamp;
15         return true;
16     }
17     unordered_map<string, int> cache;
18 };
19 
20 /**
21  * Your Logger object will be instantiated and called as such:
22  * Logger obj = new Logger();
23  * bool param_1 = obj.shouldPrintMessage(timestamp,message);
24  */
View Code

 

 

【362】Design Hit Counter(2019年2月21日, 週四)

 Design Hit Counter which counts the number of hits received in the past 5 minutes.

實現一個類: 主要實現兩個方法

HitCounter counter = new HitCounter();

void hit(int timestamp); // hit at ts

int getHits(int timestamp); //get how many hits in past 5 minutes.

 1 class HitCounter {
 2 public:
 3     /** Initialize your data structure here. */
 4     HitCounter() {
 5         
 6     }
 7     
 8     /** Record a hit.
 9         @param timestamp - The current timestamp (in seconds granularity). */
10     void hit(int timestamp) {
11         while (!que.empty() && que.front() + TIMEGAP <= timestamp) {
12             que.pop();
13         }
14         que.push(timestamp);
15     }
16     
17     /** Return the number of hits in the past 5 minutes.
18         @param timestamp - The current timestamp (in seconds granularity). */
19     int getHits(int timestamp) {
20         while (!que.empty() && que.front() + TIMEGAP <= timestamp) {
21             que.pop();
22         }
23         return que.size();
24     }
25     queue<int> que;
26     const int TIMEGAP = 300;
27 };
28 
29 /**
30  * Your HitCounter object will be instantiated and called as such:
31  * HitCounter obj = new HitCounter();
32  * obj.hit(timestamp);
33  * int param_2 = obj.getHits(timestamp);
34  */
View Code

 

【379】Design Phone Directory (2019年2月21日,週四)

設計一個電話目錄有以下三個功能:

  1. get: Provide a number which is not assigned to anyone.
  2. check: Check if a number is available or not.
  3. release: Recycle or release a number 

題解:我用了一個set,一個queue來實現的。set來存儲使用過的電話號碼。使用queue來存儲刪除後的電話號碼,若是當前queue爲空的話,咱們就用 curNumber 生成一個新的電話號碼。

複雜度分析以下:get: O(logN), check: O(1), release: O(1), beats 80%. 

 1 class PhoneDirectory {
 2 public:
 3     /** Initialize your data structure here
 4         @param maxNumbers - The maximum numbers that can be stored in the phone directory. */
 5     PhoneDirectory(int maxNumbers) {
 6         this->maxNumbers = maxNumbers;
 7     }
 8     
 9     /** Provide a number which is not assigned to anyone.
10         @return - Return an available number. Return -1 if none is available. */
11     int get() {
12         if (que.empty()) {
13             if (curNumber == maxNumbers) {
14                 return -1;
15             }
16             usedNumbers.insert(curNumber);
17             return curNumber++;
18         }
19         int number = que.front();
20         usedNumbers.insert(number);
21         que.pop();
22         return number;
23     }
24     
25     /** Check if a number is available or not. */
26     bool check(int number) {
27         if (usedNumbers.find(number) != usedNumbers.end()) {
28             return false;
29         }
30         return true;
31     }
32     
33     /** Recycle or release a number. */
34     void release(int number) {
35         if (usedNumbers.find(number) == usedNumbers.end()) {return;}
36         usedNumbers.erase(number);
37         que.push(number);
38     }
39     int maxNumbers;
40     unordered_set<int> usedNumbers;
41     int curNumber = 0;
42     queue<int> que;
43 };
44 
45 /**
46  * Your PhoneDirectory object will be instantiated and called as such:
47  * PhoneDirectory obj = new PhoneDirectory(maxNumbers);
48  * int param_1 = obj.get();
49  * bool param_2 = obj.check(number);
50  * obj.release(number);
51  */
View Code

 

【380】Insert Delete GetRandom O(1) 

 

【381】Insert Delete GetRandom O(1) - Duplicates allowed 

 

【432】All O`one Data Structure 

【460】LFU Cache 

【588】Design In-Memory File System 

【604】Design Compressed String Iterator 

 

【622】Design Circular Queue (2018年12月12日,算法羣,用數組實現隊列)

設計用數組實現節省空間的環形隊列。

題解:用個size來標記如今隊列裏面有幾個元素,(不要用rear和front的關係來判斷,否則一大一小還有環很是容易出錯)。

 1 class MyCircularQueue {
 2 public:
 3     /** Initialize your data structure here. Set the size of the queue to be k. */
 4     MyCircularQueue(int k) {
 5         que.resize(k);
 6         capacity = k;
 7         front = rear = 0;
 8         size = 0;
 9     }
10     
11     /** Insert an element into the circular queue. Return true if the operation is successful. */
12     bool enQueue(int value) {
13         if (size == capacity) {return false;}
14         ++size;
15         rear = rear % capacity;
16         que[rear++] = value;
17         return true;
18     }
19     
20     /** Delete an element from the circular queue. Return true if the operation is successful. */
21     bool deQueue() {
22         if (size == 0) {return false;}
23         --size;
24         front = (front + 1) % capacity;
25         return true;
26     }
27     
28     /** Get the front item from the queue. */
29     int Front() {
30         if (size == 0) {return -1;}
31         return que[front];
32     }
33     
34     /** Get the last item from the queue. */
35     int Rear() {
36         if (size == 0) {return -1;}
37         rear = rear % capacity;
38         return rear == 0 ? que[capacity-1] : que[rear-1];
39     }
40     
41     /** Checks whether the circular queue is empty or not. */
42     bool isEmpty() {
43         return size == 0;
44     }
45     
46     /** Checks whether the circular queue is full or not. */
47     bool isFull() {
48         return size == capacity;
49     }
50     int front, rear, size, capacity;
51     vector<int> que;
52 };
53 
54 /**
55  * Your MyCircularQueue object will be instantiated and called as such:
56  * MyCircularQueue* obj = new MyCircularQueue(k);
57  * bool param_1 = obj->enQueue(value);
58  * bool param_2 = obj->deQueue();
59  * int param_3 = obj->Front();
60  * int param_4 = obj->Rear();
61  * bool param_5 = obj->isEmpty();
62  * bool param_6 = obj->isFull();
63  */
View Code

 

【631】Design Excel Sum Formula 

【635】Design Log Storage System 

【641】Design Circular Deque 

【642】Design Search Autocomplete System 

【705】Design HashSet 

【706】Design HashMap 

【707】Design Linked List 

 

【716】Max Stack (2019年1月19日,谷歌決戰複習,2 stacks || treemap + double linked list)

設計一個棧,能實現棧的基本操做,push 和 pop,而且能返回棧中的最大元素,還能彈出棧中的最大元素。

題解:我能想到 2 stack 的方法。和155題同樣的。 

 1 class MaxStack {
 2 public:
 3     /** initialize your data structure here. */
 4     MaxStack() {
 5         
 6     }
 7     
 8     void push(int x) {
 9         stk.push(x);
10         if (maxStk.empty()) {
11             maxStk.push(x);
12         } else {
13             maxStk.push(max(x, peekMax()));
14         }
15     }
16     
17     int pop() {
18         int ret = stk.top();
19         stk.pop();
20         maxStk.pop();
21         return ret;
22     }
23     
24     int top() {
25         return stk.top();
26     }
27     
28     int peekMax() {
29         return maxStk.top();
30     }
31     
32     int popMax() {
33         stack<int> buffer;
34         int max = maxStk.top();
35         while (!stk.empty() && stk.top() != max) {
36             buffer.push(pop());
37         }
38         pop();
39         while (!buffer.empty()) {
40             push(buffer.top());
41             buffer.pop();
42         }
43         return max;
44     }
45     stack<int> stk, maxStk;
46 };
47 
48 /**
49  * Your MaxStack object will be instantiated and called as such:
50  * MaxStack obj = new MaxStack();
51  * obj.push(x);
52  * int param_2 = obj.pop();
53  * int param_3 = obj.top();
54  * int param_4 = obj.peekMax();
55  * int param_5 = obj.popMax();
56  */
View Code

可是treemap方法是什麼,彷佛跟lru cache 相似。

相關文章
相關標籤/搜索