Categories
不学无术

LeetCode 138. Copy List with Random Pointer

思路

《剑指Offer》#26
基本步骤是:

  1. 在每个节点后面,拷贝一个相同的节点:A->A’->B->B’…
  2. 拷贝随机节点,即A’->random是A->random->next
  3. 分离拷贝后的链表

代码

(脑抽了一下,break和continue打错,看了半天)

/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    void makeNodeDup(RandomListNode* head){
        //make copy of linked node
        while(head!=NULL){
            RandomListNode* replica = new RandomListNode(head->label);
            replica->next = head->next;
            head->next = replica;
            head = replica->next;
        }
    }
    void copyRandomLink(RandomListNode* head){
        //copy random link in new-generated replicas
        while(head != NULL){
            if(head->random == NULL){
                head = head->next->next;
                continue;
            }
            RandomListNode* replica = head->next;
            replica->random = head->random->next;
            head = replica->next;
        }
    }
    RandomListNode* detachReplica(RandomListNode* head){
        RandomListNode* replicaHead = NULL;
        while(head != NULL){
            RandomListNode* replica = head->next;
            if(replicaHead == NULL){
                replicaHead = replica;
            }
            head->next = replica->next;
            if(replica->next != NULL){
                replica->next = replica->next->next;
            } else {
                replica->next = NULL;
            }
            head = head->next;
        }
        return replicaHead;
    }
    RandomListNode *copyRandomList(RandomListNode *head) {
        makeNodeDup(head);
        copyRandomLink(head);
        return detachReplica(head);
    }
};

 

Categories
不学无术

LeetCode 146. LRU Cache

思路

双向链表+哈希表实现,要明白STL里的<map>是红黑树实现的,亲测速度不够,要用真.哈希表:<unordered_map>
可能有人要问,为啥不用单向链表?我的理解是为了删除元素的时候不用从头搜索。
当然,针对这道题是可以用单向链表的,即“删除”最无用节点的时候,对链表不作处理,而只是从哈希表里把值删掉。反正在搜索的时候也是直接查的哈希表。副作用是这个链表会越来越长。
另外,不想自己实现双向链表的话,可以用<list>

代码

struct LinkedNode{
    int key;
    LinkedNode* next;
    LinkedNode* prev;
    LinkedNode(int _key = -1){
        key = _key;
        next = NULL;
        prev = NULL;
    }
};
class LRUCache{
private:
    LinkedNode* pHeader;
    LinkedNode* pEnd;
    unordered_map<int, int> keyValueMap;
    int cap;
public:
    LRUCache(int capacity) {
        cap = capacity;
        pHeader = new LinkedNode(); //dummy node
        pEnd = new LinkedNode();
        pHeader->next = pEnd;
        pEnd->prev = pHeader;
    }
    void refreshQueue(int key){
        LinkedNode* pNode = pHeader;
        while(pNode->next != NULL){
            if(pNode->next->key == key)
                break;
            pNode = pNode->next;
        }
        //Move pNode->next to head
        LinkedNode* pPrevNode = pNode;
        LinkedNode* pHitNode = pNode->next;
        LinkedNode* pNextNode = pHitNode->next;
        pPrevNode->next = pNextNode;
        pNextNode->prev = pPrevNode;
        pHeader->next->prev = pHitNode;
        pHitNode->prev = pHeader;
        pHitNode->next = pHeader->next;
        pHeader->next = pHitNode;
    }
    int removeLast(){
        //Remove the last item and return its key
        LinkedNode* pToRemove = pEnd->prev;
        int key = pToRemove->key;
        LinkedNode* pPrev = pToRemove->prev;
        pPrev->next = pEnd;
        pEnd->prev = pPrev;
        delete pToRemove;
        return key;
    }
    int get(int key) {
        if(keyValueMap.count(key) > 0){
            //Change priority queue
            refreshQueue(key);
            //Get value
            return keyValueMap[key];
        } else {
            return -1;
        }
    }
    void insert(int key){
        LinkedNode* pNext = pHeader->next;
        LinkedNode* pNewNode = new LinkedNode(key);
        pNewNode->next = pNext;
        pNewNode->prev = pHeader;
        pHeader->next = pNewNode;
        pNext->prev = pNewNode;
    }
    void set(int key, int value) {
        if(keyValueMap.count(key)){
            keyValueMap[key] = value; //set key
            //Refresh queue
            refreshQueue(key);
        } else {
            if(keyValueMap.size() == cap){
                int oldKey = removeLast();
                keyValueMap.erase(oldKey);
            }
            keyValueMap[key] = value;
            insert(key);
        }
    }
};

 

Categories
不学无术

LeetCode 328. Odd Even Linked List

Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes.
You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity.
Example:
Given 1->2->3->4->5->NULL,
return 1->3->5->2->4->NULL.
Note:
The relative order inside both the even and odd groups should remain as it was in the input.
The first node is considered odd, the second node even and so on …

思路

既然是要O(n)时间复杂度,并且O(1)空间复杂度,基本就能想到要用俩指针了。其中一个指针指向当前的奇数位元素,另一个指向偶数位的。
LeetCode328
大概就是这个意思啦,然后指针不断往前挪动。注意要保存偶数指针的头,因为奇数结束之后要串上偶数的~

代码

里面的oddTail是为了防止链表长度为奇数的时候,里面currOdd指针走到NULL的情况。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if(head == NULL || head->next == NULL)
            return head;
        ListNode* currOdd = head;
        ListNode* currEven = head->next;
        ListNode* evenHead = currEven;
        ListNode* oddTail = currOdd;
        while(currOdd != NULL && currEven != NULL){
            currOdd->next =currEven->next;
            if(currOdd->next != NULL)
                currEven->next = currOdd->next->next;
            oddTail = currOdd;
            currOdd = currOdd->next;
            currEven = currEven->next;
        }
        if(currOdd != NULL)
            currOdd->next = evenHead;
        else
            oddTail->next = evenHead;
        return head;
    }
};