2021-01-14 Daily-Challenge
Today I have done Copy List with Random Pointer, LRU Cache and leetcode's January LeetCoding Challenge with cpp.
Copy List with Random Pointer
Description
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
The Linked List is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index] where:
val: an integer representingNode.valrandom_index: the index of the node (range from0ton-1) where random pointer points to, ornullif it does not point to any node.
Example 1:

Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]
Example 2:

Input: head = [[1,1],[2,1]]
Output: [[1,1],[2,1]]
Example 3:

Input: head = [[3,null],[3,0],[3,null]]
Output: [[3,null],[3,0],[3,null]]
Example 4:
Input: head = []
Output: []
Explanation: Given linked list is empty (null pointer), so return null.
Constraints:
-10000 <= Node.val <= 10000Node.randomis null or pointing to a node in the linked list.- The number of nodes will not exceed 1000.
Solution
use a unordered_map
class Solution {
public:
Node* copyRandomList(Node* head) {
Node *newHead = new Node(-1);
Node *cur = newHead;
unordered_map<Node*, Node*> mp;
while(head) {
cur->next = new Node(head->val);
mp[head] = cur->next;
cur = cur->next;
cur->random = head->random;
head = head->next;
}
mp[NULL] = NULL;
cur = newHead->next;
while(cur) {
cur->random = mp[cur->random];
cur = cur->next;
}
return newHead->next;
}
};
LRU Cache
Description
Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.
Implement the LRUCache class:
LRUCache(int capacity)Initialize the LRU cache with positive sizecapacity.int get(int key)Return the value of thekeyif the key exists, otherwise return-1.void put(int key, int value)Update the value of thekeyif thekeyexists. Otherwise, add thekey-valuepair to the cache. If the number of keys exceeds thecapacityfrom this operation, evict the least recently used key.
Follow up:
Could you do get and put in O(1) time complexity?
Example 1:
Input
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
Output
[null, null, null, 1, null, -1, null, -1, 3, 4]
Explanation
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // cache is {1=1}
lRUCache.put(2, 2); // cache is {1=1, 2=2}
lRUCache.get(1); // return 1
lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3}
lRUCache.get(2); // returns -1 (not found)
lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3}
lRUCache.get(1); // return -1 (not found)
lRUCache.get(3); // return 3
lRUCache.get(4); // return 4
Constraints:
1 <= capacity <= 30000 <= key <= 30000 <= value <= 104- At most
3 * 104calls will be made togetandput.
Solution
use a list and two unordered_map
code can be more elegant
class LRUCache {
int capacity;
list<int> LRU;
unordered_map<int, list<int>::iterator> position;
unordered_map<int, int> kv;
public:
LRUCache(int capacity) : capacity(capacity) {}
int get(int key) {
if(kv.count(key)) {
LRU.erase(position[key]);
LRU.push_front(key);
position[key] = LRU.begin();
return kv[key];
}
return -1;
}
void put(int key, int value) {
if(kv.count(key)) {
LRU.erase(position[key]);
} else {
if(kv.size() == capacity) {
kv.erase(LRU.back());
position.erase(LRU.back());
LRU.pop_back();
}
}
LRU.push_front(key);
position[key] = LRU.begin();
kv[key] = value;
}
};
January LeetCoding Challenge 14
Description
Minimum Operations to Reduce X to Zero
You are given an integer array nums and an integer x. In one operation, you can either remove the leftmost or the rightmost element from the array nums and subtract its value from x. Note that this modifies the array for future operations.
Return the minimum number of operations to reduce x to exactly 0 if it's possible*, otherwise, return* -1.
Example 1:
Input: nums = [1,1,4,2,3], x = 5
Output: 2
Explanation: The optimal solution is to remove the last two elements to reduce x to zero.
Example 2:
Input: nums = [5,6,7,8,9], x = 4
Output: -1
Example 3:
Input: nums = [3,2,20,1,1,3], x = 10
Output: 5
Explanation: The optimal solution is to remove the last three elements and the first two elements (5 operations in total) to reduce x to zero.
Constraints:
1 <= nums.length <= 1051 <= nums[i] <= 1041 <= x <= 109
Solution
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int len = nums.size();
int sum = 0;
unordered_map<int, int> sumLeft, sumRight;
int pos = 0;
while(pos < len && sum < x) {
sum += nums[pos];
sumLeft[sum] = pos;
pos += 1;
}
pos = len-1;
sum = 0;
while(pos >= 0 && sum < x) {
sum += nums[pos];
sumRight[sum] = pos;
pos -= 1;
}
int answer = INT_MAX;
for(auto [sum, pos] : sumLeft) {
if(sumRight.count(x-sum) && sumRight[x-sum] > pos) answer = min(answer, pos + 1 + len - sumRight[x-sum]);
}
if(sumLeft.count(x)) answer = min(answer, sumLeft[x] + 1);
if(sumRight.count(x)) answer = min(answer, len - sumRight[x]);
return answer == INT_MAX ? -1 : answer;
}
};