Inscription LeetCodeGOGOGO brush 01-- optimization list (hashing the key value to achieve access list)

deadline is the first productive force, just received written notice of a question I now actually have not had time to brush, brush quickly start LeetCode Inscription

Starting from the memories version of the title, is said to be an electrical problem amazon face of this year, have a try

206. Reverse Linked List

Difficulty:

Easy

Ideas:

The list is a simple reversal of the water problem, note that the list may be empty enter this particular case

Code:


/*
Author Owen_Q
*/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head == NULL)
            return NULL;
        int n=1;
        int l[1000010];
        l[0] = head->val;
        while(head->next!=NULL)
        {
            head = head->next;
            l[n++] = head->val;
        }
        ListNode* newHead = new ListNode(l[n-1]);
        ListNode* lastNode = newHead;
        while(n>1)
        {
            n--;
            ListNode* newNode = new ListNode(l[n-1]);
            lastNode->next = newNode;
            lastNode = newNode;
        }
        return newHead;
        
    }
};

146. LRU Cache

Difficulty:

Medium

key point:

Access key value list

Ideas:

Title description is very simple, to O (1) time complexity implement a LRU (Least Recent Used) of the cache. Since it is easy to understand the meaning of problems, the most significant challenge in how the complexity down to a constant level.

The idea is to use a conventional cache memory logical space data structure element by querying key, another data structure memory address space of the cache to simulate the process of updating and deleting the cache. There is no logical space that part of the problem, O (1) query to update all elements ok. However, this part of the address space, how you can quickly locate elements and update the key value element position order, is a more difficult problem.

So, in order to maintain location information, think the key is inserted into the queue, because the queue elements can not quickly find the key value, so you can think of a time when there was no query queue is inserted in the brain, and then mark the elements marked lazy. To be truly new element into the queue result for cache is full, and then click Delete these lazy flags. In this way, we can achieve O (1) query and O (1) update the old elements, however, when a new element is inserted, not only remove the LRU elements, but also all the elements to be marked with signs lazy before, so ie, the time complexity of the upgrade is O (existing operand), so they can be constructed in front of a bunch of garbage useless queries, insert a new element suddenly last seemingly pointless but I can put this card out method case, a lot of lazy logo makes this approach because TLE forced into bankruptcy.

Correct answer:

Re-analysis of the problem, return the two key points this difficult question:

1. Quick Key value of the positioning element

2. Quickly update element position

In order to address 1, commonly used methods map mapping, however, based on C ++ map to achieve red-black tree can only reach O (logn) queries. While another similar data structures unordered_map based hash table implementation, can achieve O (1) query, then the first problem to solve

In order to solve 2, can be implemented using a linked list, C ++ the list can achieve O (1) access to the mobile element and the elements at both ends of the chain.

While at the same time if they wish to solve these two problems, you need to use a method very metaphysics, the list with nested unordered_map

Just think, if every node in the list can be quickly accessed via a hash table, would not that be the perfect solution to these two problems!

It sounds crazy special, but in fact is not impossible. Since you can access from an iterator for the elements of the list, so we can be stored in these iterators unordered_map hash table. In this way, when you need to query the value of a button, using the key to access the hash table to quickly find a list iterator access list. Quickly update the list of elements such that the complexity of the function of all the operations have all been reduced to O (1). Perfect to achieve the optimal value can not be the key to access this defect list!

After want to understand, and quickly go from Coding

STL Knowledge Review:

pair:

pair<key,value>

The key to the cache and the actual value package pairs, pair is a good use of the data structure

May be utilized make_pair (key, value) Constructs a new constructor pair

Pair of access to, use to access the corresponding first key, second to access the corresponding value

list

list<element>

List implementation, using the iterator iterators complete access to the list of elements, and you can use this iterator to delete elements based. Using erase () can be achieved deleted complexity O (1), a position corresponding to the next list element deleted after returning iterator

push_back (), pop_back (), push_up (), pop_up (), respectively, can be achieved across the insert and delete list, no return value

Element insert () can achieve a particular position (specific iterator before) insertion iterator returns the newly inserted element

front (), back () returns the list element ends (non iterator)

clear () Clear the list

size () Returns the size of the list

unordered_map

unordered_map<key,value>

Hash-based implementation, the key value O (1) lookup, disordered array elements

find () function implemented lookup key value, the corresponding element iterator returns. If not found return end () (after a point iterator unordered_map last element)

Using a [] value can be directly implemented key search, insert, update, returns the value corresponding to the value of the element value of the corresponding element value or the modified

After the erase () function may be implemented using the iterator to remove elements, may directly delete key element, the element returns an iterator element

size () Returns the size of the table

clear () Clear Table

Code:


/*
Author Owen_Q
*/

class LRUCache {
public:
    LRUCache(int capacity) {
        n = capacity;
        lru.clear();
        cache.clear();
    }
    
    int get(int key) {
        if(cache.find(key)!=cache.end())
        {
            pair<int,int> temp = *(cache[key]);
            lru.erase(cache[key]);
            cache[key] = lru.insert(lru.begin(),temp);
            return temp.second;
        }
        else
            return -1;
    }
    
    void put(int key, int value) {
        if(cache.find(key)!=cache.end())
        {
            //pair<int,int> temp = *(cache[key]);
            lru.erase(cache[key]);
            //temp.second = value;
            cache[key] = lru.insert(lru.begin(),make_pair(key,value));
            return ;
        }
        else
        {
            cache[key] = lru.insert(lru.begin(),make_pair(key,value));
            if(lru.size()>n)
            {
                cache.erase(lru.back().first);
                lru.pop_back();
            }
            return ;
        }
    }
    
private:
    list<pair<int,int>> lru;
    unordered_map<int, list<pair<int,int>>::iterator> cache;
    int n;
    int len;
    
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

 

Published 97 original articles · won praise 89 · views 20000 +

Guess you like

Origin blog.csdn.net/Owen_Q/article/details/103982750