2021-01-16 Daily-Challenge
Today is Saturday, I gonna review the tasks I've done this week, and finish today's leetcode's January LeetCoding Challenge with cpp
.
LeetCode Review
Reverse Nodes in k-Group
reversing nodes group every k steps instead of get length and reverse
class Solution {
ListNode* reverseKNodes(ListNode* head, int k) {
ListNode *tail = nullptr;
ListNode *next;
while(k--) {
next = head->next;
head->next = tail;
tail = head;
head = next;
}
return tail;
}
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode *newHead = new ListNode();
ListNode *cur = head;
ListNode *newTail = newHead;
while(cur) {
// cout << cur << ' ' << cur->val << endl;
bool longEnough = true;
ListNode *groupHead = cur;
for(int i = 0; i < k; ++i) {
if(!cur) {
longEnough = false;
break;
}
cur = cur->next;
}
if(longEnough) {
newTail->next = reverseKNodes(groupHead, k);
while(newTail->next) newTail = newTail->next;
} else {
newTail->next = groupHead;
}
}
return newHead->next;
}
};
Merge Sorted Array
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
while(m && n) {
if(nums1[m-1] > nums2[n-1]) {
nums1[m+n-1] = nums1[m-1];
m -= 1;
} else {
nums1[m+n-1] = nums2[n-1];
n -= 1;
}
}
while(n) {
nums1[n-1] = nums2[n-1];
n -= 1;
}
}
};
Best Time to Buy and Sell stock
class Solution {
public:
int maxProfit(vector<int>& prices) {
int mmin = prices.front();
int answer = 0;
for(auto i : prices) {
mmin = min(i, mmin);
answer = max(answer, i - mmin);
}
return answer;
}
};
Add Two Numbers
too easy to review
Boats to Save People
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
sort(people.begin(), people.end());
int begin = 0, end = people.size()-1;
int answer = 0;
while(begin < end) {
if(people[begin]+people[end] <= limit) {
begin += 1;
}
end -= 1;
answer += 1;
}
if(begin == end) answer += 1;
return answer;
}
};
Nth Magical Number
class Solution {
const int MOD = 1e9 + 7;
int gcd(int a, int b) { return b ? gcd(b, a%b): a; }
int count(int x, int a, int b) {
return x / a + x / b;
}
public:
int nthMagicalNumber(int n, int a, int b) {
long long answer = 0;
long long lcm = a / gcd(a, b) * b;
long long round = lcm / a + lcm / b - 1;
answer = (lcm * (n / round)) % MOD;
int rest = n % round;
long long begin = 0, end = lcm-1;
while(begin < end) {
int mid = (begin + end) / 2;
if(count(mid, a, b) < rest) {
begin = mid + 1;
} else {
end = mid;
}
}
answer = (answer + begin) % MOD;
return answer;
}
};
Minimum Operations to Reduce X to Zero
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
unordered_map<int, int> sumLeft, sumRight;
int len = nums.size();
int sum = 0;
for(int i = 0; i < len; ++i) {
sum += nums[i];
sumLeft[sum] = i+1;
}
sumLeft[0] = 0;
sum = 0;
for(int i = 1; i <= len; ++i) {
sum += nums[len-i];
sumRight[sum] = i;
}
sumRight[0] = 0;
int answer = INT_MAX;
for(auto [sum, cnt] : sumLeft) {
if(sumRight.count(x-sum) && cnt+sumRight[x-sum] <= len) answer = min(answer, cnt+sumRight[x-sum]);
}
return answer == INT_MAX ? -1 : answer;
}
};
Get Maximum in Generated Array
class Solution {
public:
int getMaximumGenerated(int n) {
if(!n) return n;
vector<int> nums(n+2);
nums[1] = 1;
for(int i = 1; i*2-2 < n; ++i) {
nums[i+i-1] = nums[i] + nums[i-1];
nums[i*2] = nums[i];
}
int answer = 0;
for(auto i : nums) answer = max(answer, i);
return answer;
}
};
Copy List with Random Pointer
not using unordered_map
class Solution {
public:
Node* copyRandomList(Node* head) {
Node *cur = head;
while(cur) {
Node *newNode = new Node(cur->val);
newNode->next = cur->next;
newNode->random = cur->random;
cur->next = newNode;
cur = cur->next->next;
}
cur = head;
while(cur) {
cur = cur->next;
if(cur->random != nullptr) cur->random = cur->random->next;
cur = cur->next;
}
Node *newHead = new Node(-1);
Node *newCur = newHead;
cur = head;
while(cur) {
newCur->next = cur->next;
cur->next = cur->next->next;
newCur = newCur->next;
cur = cur->next;
}
return newHead->next;
}
};
LRU Cache
more method, but seems not more elegant.
class LRUCache {
int capacity;
list<int> LRU;
unordered_map<int, int> kv;
unordered_map<int, list<int>::iterator> position;
void update(int key) {
LRU.erase(position[key]);
add(key);
}
void add(int key) {
LRU.push_front(key);
position[key] = LRU.begin();
}
void evict_last() {
kv.erase(LRU.back());
position.erase(LRU.back());
LRU.pop_back();
}
public:
LRUCache(int capacity) : capacity(capacity) {}
int get(int key) {
if(kv.count(key)) {
update(key);
return kv[key];
}
return -1;
}
void put(int key, int value) {
if(kv.count(key)) {
update(key);
} else {
if(LRU.size() == capacity) evict_last();
add(key);
}
kv[key] = value;
}
};
Reverse Words in a String
class Solution {
public:
string reverseWords(string s) {
reverse(s.begin(), s.end());
int len = s.length();
bool hasSpace = true;
int newLength = 0;
for(int i = 0; i < len; ++i) {
if(s[i] != ' ' || !hasSpace) {
if(s[i] == ' ') hasSpace = true;
else hasSpace = false;
s[newLength] = s[i];
newLength += 1;
}
}
if(!newLength) return "";
if(s[newLength-1] == ' ') newLength -= 1;
s.resize(newLength);
len = newLength;
int begin = -1, end = -1;
for(int i = 0; i < len; ++i) {
if(s[i] != ' ') {
if(begin == -1) begin = i;
end = i+1;
} else {
if(begin != -1 && begin != end-1) {
reverse(s.begin()+begin, s.begin()+end);
}
begin = -1;
end = -1;
}
}
if(begin != -1 && begin != end-1) reverse(s.begin()+begin, s.begin()+end);
return move(s);
}
};
Spiral Matrix
one dimensional, but more ugly
class Solution {
int moves[4];
vector<bool> visit;
int cols;
int total;
void init() {
moves[0] = 1;
moves[1] = cols;
moves[2] = -1;
moves[3] = -cols;
}
bool check(int pos, int direction) {
return (direction == 0 && !((pos+1) % cols)) || \
(pos + moves[direction] >= total) || \
(direction == 2 && !(pos % cols)) || \
(pos + moves[direction] < 0) || \
visit[pos+moves[direction]];
}
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
cols = matrix.front().size();
total = cols * matrix.size();
init();
visit.resize(total);
vector<int> answer;
int direction = 0, pos = 0;
while(answer.size() < total) {
answer.push_back(matrix[pos/cols][pos%cols]);
visit[pos] = true;
int turns = 0;
while(turns < 4 && check(pos, direction)) {
turns += 1;
direction = (direction + 1) % 4;
}
pos += moves[direction];
}
return move(answer);
}
};
January LeetCoding Challenge 16
Description
Kth Largest Element in an Array
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
Example 1:
Input: [3,2,1,5,6,4] and k = 2
Output: 5
Example 2:
Input: [3,2,3,1,2,4,5,5,6] and k = 4
Output: 4
Note: You may assume k is always valid, 1 ≤ k ≤ array's length.
Solution
the algorithm behind kth element is partition of quicksort, complexity of the algorithm is $O(n)$ by amortization analysis
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
nth_element(nums.begin(), nums.begin()+k-1, nums.end(), greater<int>());
return nums[k-1];
}
};