Top100(下)
栈
| bool isValid(char *s) { |
| int len = strlen(s); |
| if (len % 2 == 1) return false; |
| |
| |
| char *stack = (char *) malloc(sizeof(char) * (len + 1)); |
| int top = 0; |
| for (int i = 0; i < len; ++i) { |
| char cur = s[i]; |
| |
| if (top == 0) { |
| if (cur == ')' || cur == ']' || cur == '}') return false; |
| stack[top++] = cur; |
| continue; |
| } |
| |
| if ((cur == ')' && stack[top - 1] == '(') |
| || (cur == ']' && stack[top - 1] == '[') |
| || (cur == '}' && stack[top - 1] == '{')) { |
| |
| top--; |
| } else { |
| |
| stack[top++] = cur; |
| } |
| } |
| return top == 0; |
| } |
| |
| typedef struct { |
| |
| int *stack; |
| int top; |
| int maxSize; |
| |
| int *minStack; |
| } MinStack; |
| |
| MinStack *minStackCreate() { |
| MinStack *s = (MinStack *) malloc(sizeof(MinStack)); |
| s->stack = (int *) malloc(sizeof(int) * 10); |
| s->minStack = (int *) malloc(sizeof(int) * 10); |
| s->top = 0; |
| s->maxSize = 10; |
| return s; |
| } |
| |
| void minStackPush(MinStack *obj, int x) { |
| |
| if (obj->top == obj->maxSize) { |
| int newSize = (obj->maxSize << 1) - (obj->maxSize >> 2); |
| |
| obj->stack = (int *) realloc(obj->stack, sizeof(int) * newSize); |
| obj->minStack = (int *) realloc(obj->minStack, sizeof(int) * newSize); |
| obj->maxSize = newSize; |
| } |
| |
| |
| if (obj->top == 0 || x < obj->minStack[obj->top - 1]) |
| |
| obj->minStack[obj->top] = x; |
| else |
| |
| obj->minStack[obj->top] = obj->minStack[obj->top - 1]; |
| |
| |
| obj->stack[obj->top++] = x; |
| } |
| |
| void minStackPop(MinStack *obj) { |
| obj->top--; |
| } |
| |
| int minStackTop(MinStack *obj) { |
| return obj->stack[obj->top - 1]; |
| } |
| |
| int minStackGetMin(MinStack *obj) { |
| return obj->minStack[obj->top - 1]; |
| } |
| |
| void minStackFree(MinStack *obj) { |
| free(obj); |
| obj = NULL; |
| } |
| class Solution { |
| public: |
| string decodeString(string s) { |
| stack<char> stk; |
| deque<char> deq; |
| |
| for (int i = 0; i < s.size(); ++i) { |
| while (i < s.size() && s[i] != ']') { |
| stk.emplace(s[i]); |
| i++; |
| } |
| |
| |
| if (s[i] != ']') break; |
| |
| |
| string tempStr; |
| while (stk.top() != '[') { |
| deq.emplace_front(stk.top()); |
| stk.pop(); |
| } |
| |
| stk.pop(); |
| while (!deq.empty()) { |
| tempStr += deq.front(); |
| deq.pop_front(); |
| } |
| |
| |
| int count = 0; |
| while (!stk.empty() && stk.top() >= '0' && stk.top() <= '9') { |
| deq.emplace_front(stk.top()); |
| stk.pop(); |
| } |
| while (!deq.empty()) { |
| count *= 10; |
| count += deq.front() - '0'; |
| deq.pop_front(); |
| } |
| |
| |
| string repeated; |
| for (int j = 0; j < count; ++j) |
| repeated.append(tempStr); |
| |
| |
| for (auto &c: repeated) |
| stk.emplace(c); |
| } |
| |
| |
| string res; |
| deq.clear(); |
| while (!stk.empty()) { |
| deq.emplace_front(stk.top()); |
| stk.pop(); |
| } |
| while (!deq.empty()) { |
| res += deq.front(); |
| deq.pop_front(); |
| } |
| |
| return res; |
| } |
| }; |
| class Solution { |
| public: |
| |
| |
| string decodeString(const string &s) { |
| |
| int multi = 0; |
| string res; |
| stack<int> stack_multi; |
| stack<string> stack_res; |
| |
| for (char c: s) { |
| if (c == '[') { |
| |
| stack_multi.emplace(multi); |
| |
| stack_res.emplace(res); |
| |
| multi = 0; |
| res.clear(); |
| } else if (c == ']') { |
| |
| int cur_multi = stack_multi.top(); |
| stack_multi.pop(); |
| |
| string tmp; |
| for (int i = 0; i < cur_multi; i++) tmp += res; |
| |
| res = stack_res.top() + tmp; |
| stack_res.pop(); |
| } else if (c >= '0' && c <= '9') { |
| |
| multi = multi * 10 + (c - '0'); |
| } else { |
| |
| res.push_back(c); |
| } |
| } |
| return res; |
| } |
| }; |
| class Solution { |
| public: |
| |
| int index = 0; |
| |
| |
| string decodeString(string s) { |
| string res; |
| int multi = 0; |
| while (index < s.size()) { |
| if (s[index] >= '0' && s[index] <= '9') { |
| |
| multi = 10 * multi + s[index] - '0'; |
| } else if (s[index] == '[') { |
| |
| index++; |
| string temp = decodeString(s); |
| |
| while (multi > 0) { |
| res += temp; |
| multi--; |
| } |
| } else if (s[index] == ']') { |
| |
| break; |
| } else { |
| res += s[index]; |
| } |
| index++; |
| } |
| return res; |
| } |
| }; |
| class Solution { |
| public: |
| vector<int> dailyTemperatures(vector<int> &temperatures) { |
| vector<int> res(temperatures.size(), 0); |
| |
| stack<int> stk; |
| |
| for (int i = 0; i < temperatures.size(); ++i) { |
| |
| while (!stk.empty() && temperatures[stk.top()] < temperatures[i]) { |
| int index = stk.top(); |
| stk.pop(); |
| |
| res[index] = i - index; |
| } |
| |
| stk.emplace(i); |
| } |
| return res; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <map> |
| #include <stack> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| int largestRectangleArea(vector<int> &heights) { |
| int len = heights.size(); |
| int res = 0; |
| |
| stack<int> stk; |
| |
| |
| for (int i = 0; i < len; ++i) { |
| while (!stk.empty() && (heights[stk.top()] >= heights[i])) { |
| int popIndex = stk.top(); |
| stk.pop(); |
| int left = stk.empty() ? -1 : stk.top(); |
| int width = i - left - 1; |
| res = max(res, heights[popIndex] * width); |
| } |
| stk.emplace(i); |
| } |
| |
| while (!stk.empty()) { |
| int popIndex = stk.top(); |
| stk.pop(); |
| int left = stk.empty() ? -1 : stk.top(); |
| int width = len - left - 1; |
| res = max(res, heights[popIndex] * width); |
| } |
| |
| return res; |
| } |
| }; |
| class Solution { |
| public: |
| int largestRectangleArea(vector<int> &heights) { |
| int result = 0; |
| |
| stack<int> stk; |
| |
| heights.insert(begin(heights), 0); |
| |
| heights.push_back(0); |
| |
| for (int i = 0; i < heights.size(); i++) { |
| |
| |
| |
| while (!stk.empty() && heights[i] < heights[stk.top()]) { |
| int mid = stk.top(); |
| stk.pop(); |
| |
| int w = i - stk.top() - 1; |
| int h = heights[mid]; |
| result = max(result, w * h); |
| } |
| stk.emplace(i); |
| } |
| return result; |
| } |
| }; |
堆
| |
| class Solution { |
| public: |
| |
| void adjustHeap(vector<int> &array, int currentIndex, int len) { |
| |
| int temp = array[currentIndex]; |
| |
| int leftChildIndex = 2 * currentIndex + 1; |
| |
| |
| while (leftChildIndex <= (len - 1)) { |
| |
| if (leftChildIndex < (len - 1) |
| && (array[leftChildIndex] < array[leftChildIndex + 1])) |
| leftChildIndex++; |
| |
| |
| if (array[leftChildIndex] <= temp) break; |
| |
| array[currentIndex] = array[leftChildIndex]; |
| currentIndex = leftChildIndex; |
| leftChildIndex = 2 * currentIndex + 1; |
| } |
| |
| array[currentIndex] = temp; |
| } |
| |
| int findKthLargest(vector<int> &nums, int k) { |
| |
| |
| for (int i = nums.size() / 2 - 1; i >= 0; i--) { |
| adjustHeap(nums, i, nums.size()); |
| } |
| |
| for (int len = nums.size() - 1, count = k; count > 0; len--, count--) { |
| swap(nums[0], nums[len]); |
| adjustHeap(nums, 0, len); |
| } |
| return nums[nums.size() - k]; |
| } |
| }; |
| |
| class Solution { |
| public: |
| int findKthLargest(vector<int> &nums, int k) { |
| priority_queue<int> heap{begin(nums), end(nums)}; |
| while (k > 1) { |
| heap.pop(); |
| k--; |
| } |
| return heap.top(); |
| } |
| }; |
| |
| class Solution { |
| public: |
| |
| void adjustHeap(vector<int> &nums, int currentIndex, int len) { |
| int temp = nums[currentIndex]; |
| int leftChildIndex = 2 * currentIndex + 1; |
| while (leftChildIndex <= len - 1) { |
| if (leftChildIndex < len - 1 |
| && (nums[leftChildIndex] > nums[leftChildIndex + 1])) |
| leftChildIndex++; |
| if (nums[leftChildIndex] >= temp)break; |
| nums[currentIndex] = nums[leftChildIndex]; |
| currentIndex = leftChildIndex; |
| leftChildIndex = 2 * currentIndex + 1; |
| } |
| nums[currentIndex] = temp; |
| } |
| |
| |
| int findKthLargest(vector<int> &nums, int k) { |
| |
| for (int i = k / 2 - 1; i >= 0; i--) { |
| adjustHeap(nums, i, k); |
| } |
| for (int i = k; i < nums.size(); ++i) { |
| if (nums[0] < nums[i]) { |
| |
| nums[0] = nums[i]; |
| adjustHeap(nums, 0, k); |
| } |
| } |
| |
| return nums[0]; |
| } |
| }; |
| |
| class Solution { |
| public: |
| int findKthLargest(vector<int> &nums, int k) { |
| |
| priority_queue<int, vector<int>, greater<>> heap{begin(nums), begin(nums) + k}; |
| for (int i = k; i < nums.size(); ++i) { |
| if (nums[i] > heap.top()) { |
| heap.pop(); |
| heap.emplace(nums[i]); |
| } |
| } |
| return heap.top(); |
| } |
| }; |
| class Solution { |
| public: |
| int res; |
| int target; |
| |
| |
| void quickSelect(vector<int> &nums, int left, int right) { |
| if (left > right) return; |
| if (left == right) { |
| res = nums[left]; |
| return; |
| } |
| int i = left; |
| int j = right; |
| int pivot = nums[left]; |
| while (i < j) { |
| while (i < j && pivot <= nums[j]) { |
| j--; |
| } |
| if (i < j) { |
| nums[i] = nums[j]; |
| i++; |
| } |
| while (i < j && pivot >= nums[i]) { |
| i++; |
| } |
| if (i < j) { |
| nums[j] = nums[i]; |
| j--; |
| } |
| } |
| nums[i] = pivot; |
| if (i < target) quickSelect(nums, i + 1, right); |
| if (i > target) quickSelect(nums, left, i - 1); |
| if (i == target) res = nums[i]; |
| } |
| |
| int findKthLargest(vector<int> &nums, int k) { |
| |
| target = nums.size() - k; |
| quickSelect(nums, 0, nums.size() - 1); |
| return res; |
| } |
| }; |
| class Solution { |
| public: |
| void adjustHeap(vector<pair<int, int>> &array, int currentIndex, int len) { |
| pair<int, int> temp = array[currentIndex]; |
| int leftChildIndex = 2 * currentIndex + 1; |
| while (leftChildIndex <= (len - 1)) { |
| |
| if (leftChildIndex < (len - 1) |
| && (array[leftChildIndex].second > array[leftChildIndex + 1].second)) |
| leftChildIndex++; |
| if (array[leftChildIndex].second >= temp.second) break; |
| array[currentIndex] = array[leftChildIndex]; |
| array[currentIndex] = array[leftChildIndex]; |
| currentIndex = leftChildIndex; |
| leftChildIndex = 2 * currentIndex + 1; |
| } |
| array[currentIndex] = temp; |
| } |
| |
| vector<int> topKFrequent(vector<int> &nums, int k) { |
| |
| unordered_map<int, int> map; |
| for (auto &num: nums) { |
| map[num]++; |
| } |
| |
| vector<pair<int, int>> heap(begin(map), end(map)); |
| |
| for (int i = k / 2 - 1; i >= 0; i--) { |
| adjustHeap(heap, i, k); |
| } |
| |
| |
| for (int i = k; i < heap.size(); ++i) { |
| |
| if (heap[i].second > heap[0].second) { |
| heap[0] = heap[i]; |
| adjustHeap(heap, 0, k); |
| } |
| } |
| |
| vector<int> res(k); |
| for (int i = 0; i < k; ++i) { |
| res[i] = heap[i].first; |
| } |
| return res; |
| } |
| }; |
| class Solution { |
| public: |
| |
| struct cmp { |
| bool operator()(pair<int, int> &lhs, pair<int, int> &rhs) { |
| return lhs.second > rhs.second; |
| } |
| }; |
| |
| vector<int> topKFrequent(vector<int> &nums, int k) { |
| |
| unordered_map<int, int> map; |
| for (int i = 0; i < nums.size(); i++) { |
| map[nums[i]]++; |
| } |
| |
| |
| auto it = begin(map); |
| |
| advance(it, k); |
| priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> heap{begin(map), it}; |
| |
| while (it != map.end()) { |
| |
| if (it->second > heap.top().second) { |
| heap.pop(); |
| heap.emplace(it->first, it->second); |
| } |
| it++; |
| } |
| |
| |
| vector<int> res; |
| while (!heap.empty()) { |
| res.emplace_back(heap.top().first); |
| heap.pop(); |
| } |
| return res; |
| } |
| }; |
| class Solution { |
| public: |
| |
| vector<int> topKFrequent(vector<int> &nums, int k) { |
| |
| unordered_map<int, int> map; |
| for (auto &num: nums) |
| map[num]++; |
| |
| |
| int maxFrequency; |
| for (auto it = begin(map); it != end(map); it++) |
| maxFrequency = max(maxFrequency, it->second); |
| |
| |
| vector<vector<int>> bucket(maxFrequency + 1); |
| |
| |
| for (auto it = begin(map); it != end(map); it++) { |
| bucket[it->second].emplace_back(it->first); |
| } |
| |
| vector<int> res; |
| for (int i = bucket.size() - 1; i >= 0 && k > 0; i--) { |
| |
| while (!bucket[i].empty()) { |
| res.emplace_back(bucket[i].back()); |
| bucket[i].pop_back(); |
| k--; |
| } |
| } |
| return res; |
| } |
| }; |
| class Solution { |
| public: |
| |
| int target; |
| vector<int> res; |
| |
| |
| void generate(vector<pair<int, int>> &array) { |
| for (int i = target; i < array.size(); ++i) |
| res.emplace_back(array[i].first); |
| } |
| |
| |
| void quickSelect(vector<pair<int, int>> &array, int left, int right) { |
| if (left > right) return; |
| if (left == right) { |
| generate(array); |
| return; |
| } |
| pair<int, int> pivot = array[left]; |
| int i = left; |
| int j = right; |
| while (i < j) { |
| while (i < j && pivot.second <= array[j].second) { |
| j--; |
| } |
| if (i < j) { |
| array[i] = array[j]; |
| i++; |
| } |
| while (i < j && pivot.second >= array[i].second) { |
| i++; |
| } |
| if (i < j) { |
| array[j] = array[i]; |
| j--; |
| } |
| } |
| array[i] = pivot; |
| if (i < target) quickSelect(array, i + 1, right); |
| if (i > target) quickSelect(array, left, i - 1); |
| if (i == target) generate(array); |
| } |
| |
| vector<int> topKFrequent(vector<int> &nums, int k) { |
| |
| unordered_map<int, int> map; |
| for (auto &num: nums) |
| map[num]++; |
| |
| |
| vector<pair<int, int>> array{begin(map), end(map)}; |
| |
| target = array.size() - k; |
| |
| quickSelect(array, 0, array.size() - 1); |
| return res; |
| } |
| }; |
| class MedianFinder { |
| public: |
| |
| priority_queue<int, vector<int>, less<>> maxHeap; |
| |
| priority_queue<int, vector<int>, greater<>> minHeap; |
| |
| MedianFinder() {} |
| |
| void addNum(int num) { |
| |
| if (maxHeap.empty() || num <= maxHeap.top()) { |
| maxHeap.push(num); |
| |
| if (minHeap.size() == maxHeap.size() - 2) { |
| minHeap.push(maxHeap.top()); |
| maxHeap.pop(); |
| } |
| } else { |
| minHeap.push(num); |
| |
| if (minHeap.size() - 1 == maxHeap.size()) { |
| maxHeap.push(minHeap.top()); |
| minHeap.pop(); |
| } |
| } |
| } |
| |
| double findMedian() { |
| if (maxHeap.size() > minHeap.size()) return maxHeap.top(); |
| return (maxHeap.top() + minHeap.top()) / 2.0; |
| } |
| }; |
| |
| class MedianFinder { |
| multiset<int> nums; |
| multiset<int>::iterator left, right; |
| |
| public: |
| MedianFinder() : left(nums.end()), right(nums.end()) {} |
| |
| void addNum(int num) { |
| const size_t n = nums.size(); |
| |
| nums.insert(num); |
| if (!n) { |
| left = right = nums.begin(); |
| } else if (n & 1) { |
| if (num < *left) { |
| left--; |
| } else { |
| right++; |
| } |
| } else { |
| if (num > *left && num < *right) { |
| left++; |
| right--; |
| } else if (num >= *right) { |
| left++; |
| } else { |
| right--; |
| left = right; |
| } |
| } |
| } |
| |
| double findMedian() { |
| return (*left + *right) / 2.0; |
| } |
| }; |
贪心
| int maxProfit(int *prices, int pricesSize) { |
| if (pricesSize == 1) return 0; |
| |
| int res = 0; |
| int min = prices[0]; |
| for (int i = 1; i < pricesSize; ++i) { |
| if (prices[i] < min) { |
| |
| min = prices[i]; |
| } else if (prices[i] - min > res) { |
| |
| res = prices[i] - min; |
| } |
| } |
| return res; |
| } |
| bool res; |
| |
| bool flag; |
| |
| void recursive(int *nums, int numsSize, int left, int right) { |
| if (flag) return; |
| |
| |
| int maxRight = right; |
| for (int i = left; i <= right; ++i) { |
| |
| int nextIndex = nums[i] + i; |
| if (nextIndex > maxRight) maxRight = nextIndex; |
| } |
| |
| if (maxRight >= numsSize - 1) { |
| |
| res = true; |
| flag = true; |
| } else if (maxRight == right) { |
| |
| res = false; |
| flag = true; |
| } else { |
| |
| recursive(nums, numsSize, right + 1, maxRight); |
| } |
| } |
| |
| bool canJump(int *nums, int numsSize) { |
| flag = false; |
| recursive(nums, numsSize, 0, 0); |
| return res; |
| } |
| bool canJump(int *nums, int numsSize) { |
| |
| int rightMax = 0; |
| for (int i = 0; i < numsSize; ++i) { |
| |
| if (rightMax < i) return false; |
| |
| if (rightMax < i + nums[i]) rightMax = i + nums[i]; |
| |
| if (rightMax >= numsSize - 1) return true; |
| } |
| return true; |
| } |
| |
| int jump(int *nums, int numsSize) { |
| |
| int dp[numsSize]; |
| for (int i = 0; i < numsSize; ++i) dp[i] = 0x7fffffff; |
| dp[0] = 0; |
| |
| for (int i = 0; i < numsSize; ++i) { |
| |
| int start = i + 1; |
| int end = nums[i] + i; |
| if (end >= numsSize) end = numsSize - 1; |
| for (int j = start; j <= end; ++j) |
| |
| if (dp[i] + 1 < dp[j]) dp[j] = dp[i] + 1; |
| } |
| return dp[numsSize - 1]; |
| } |
| |
| int steps; |
| |
| bool flag; |
| |
| void recursive(int *nums, int numsSize, int left, int right) { |
| if (flag) return; |
| |
| if (right >= numsSize - 1) { |
| |
| flag = true; |
| return; |
| } |
| |
| |
| steps++; |
| |
| |
| int maxRight = right; |
| for (int i = left; i <= right; ++i) { |
| |
| int nextIndex = nums[i] + i; |
| if (nextIndex > maxRight) maxRight = nextIndex; |
| } |
| |
| recursive(nums, numsSize, right + 1, maxRight); |
| } |
| |
| int jump(int *nums, int numsSize) { |
| steps = 0; |
| flag = false; |
| recursive(nums, numsSize, 0, 0); |
| return steps; |
| } |
| |
| int jump(int *nums, int numsSize) { |
| int left = 0, right = 0; |
| int steps = 0; |
| |
| while (right <= numsSize - 2) { |
| |
| steps++; |
| |
| int rightMax = right; |
| for (int i = left; i <= right; ++i) |
| if (rightMax < nums[i] + i) rightMax = nums[i] + i; |
| left = right + 1; |
| right = rightMax; |
| } |
| return steps; |
| } |
| |
| int jump(int *nums, int numsSize) { |
| int right = 0; |
| int steps = 0; |
| int rightMax = 0; |
| |
| for (int i = 0; i <= numsSize - 2; ++i) { |
| |
| if (rightMax < nums[i] + i) rightMax = nums[i] + i; |
| |
| if (i == right) { |
| right = rightMax; |
| steps++; |
| } |
| } |
| |
| return steps; |
| } |
| |
| struct Pair { |
| |
| int firstPosition; |
| |
| char ch; |
| }; |
| |
| int cmp(const void *a, const void *b) { |
| return (*(struct Pair *) a).firstPosition - (*(struct Pair *) b).firstPosition; |
| } |
| |
| int *partitionLabels(char *s, int *returnSize) { |
| const int sizeOfChar = 26; |
| |
| int firstPositions[sizeOfChar]; |
| |
| int lastPositions[sizeOfChar]; |
| memset(firstPositions, -1, sizeof(firstPositions)); |
| memset(lastPositions, -1, sizeof(lastPositions)); |
| |
| |
| int len = strlen(s); |
| for (int i = 0; i < len; ++i) { |
| if (firstPositions[s[i] - 'a'] == -1) firstPositions[s[i] - 'a'] = i; |
| lastPositions[s[i] - 'a'] = i; |
| } |
| |
| |
| |
| struct Pair *pair = (struct Pair *) malloc(sizeof(struct Pair) * sizeOfChar); |
| |
| int pairSize = 0; |
| for (int i = 0; i < sizeOfChar; ++i) { |
| |
| if (firstPositions[i] == -1) continue; |
| pair[pairSize].firstPosition = firstPositions[i]; |
| pair[pairSize].ch = i + 'a'; |
| pairSize++; |
| } |
| |
| |
| qsort(pair, pairSize, sizeof(struct Pair), cmp); |
| |
| *returnSize = 0; |
| int *res = (int *) malloc(sizeof(int) * len); |
| int index = 0; |
| while (index < pairSize) { |
| |
| int left = pair[index].firstPosition; |
| |
| int right = lastPositions[pair[index].ch - 'a']; |
| |
| index++; |
| |
| while (index < pairSize && pair[index].firstPosition < right) { |
| |
| if (lastPositions[pair[index].ch - 'a'] > right) |
| right = lastPositions[pair[index].ch - 'a']; |
| index++; |
| } |
| |
| res[(*returnSize)++] = right - left + 1; |
| } |
| |
| return res; |
| } |
| int *partitionLabels(char *s, int *returnSize) { |
| int len = strlen(s); |
| |
| int lastPositions[26]; |
| for (int i = 0; i < len; i++) |
| lastPositions[s[i] - 'a'] = i; |
| |
| *returnSize = 0; |
| int *res = malloc(sizeof(int) * len); |
| int left = 0, right = 0; |
| |
| |
| |
| |
| for (int i = 0; i < len; i++) { |
| if (lastPositions[s[i] - 'a'] > right) |
| right = lastPositions[s[i] - 'a']; |
| if (i == right) { |
| res[(*returnSize)++] = right - left + 1; |
| left = right + 1; |
| } |
| } |
| return res; |
| } |
动态规划
| int climbStairs(int n) { |
| int dp[46]; |
| |
| dp[1] = 1; |
| |
| dp[2] = 2; |
| int i = 3; |
| while (i <= n) { |
| |
| |
| dp[i] = dp[i - 2] + dp[i - 1]; |
| i++; |
| } |
| return dp[n]; |
| } |
| |
| int climbStairs(int n) { |
| if (n < 3) return n; |
| int left = 1; |
| int mid = 2; |
| int right; |
| int count = n - 2; |
| while (count-- > 0) { |
| right = left + mid; |
| left = mid; |
| mid = right; |
| } |
| return right; |
| } |
| int **generate(int numRows, int *returnSize, int **returnColumnSizes) { |
| *returnSize = numRows; |
| *returnColumnSizes = (int *) malloc(sizeof(int) * numRows); |
| int **res = (int **) malloc(sizeof(int *) * numRows); |
| for (int i = 0; i < numRows; ++i) { |
| res[i] = (int *) malloc(sizeof(int) * (i + 1)); |
| (*returnColumnSizes)[i] = i + 1; |
| } |
| |
| for (int i = 0; i < numRows; ++i) { |
| res[i][0] = 1; |
| res[i][i] = 1; |
| for (int j = 1; j <= i - 1; ++j) { |
| res[i][j] = res[i - 1][j - 1] + res[i - 1][j]; |
| } |
| } |
| |
| return res; |
| } |
| int max(int a, int b) { |
| return a > b ? a : b; |
| } |
| |
| int rob(int *nums, int numsSize) { |
| if (numsSize == 1) return nums[0]; |
| |
| int dp[numsSize]; |
| dp[0] = nums[0]; |
| dp[1] = max(nums[0], nums[1]); |
| |
| for (int i = 2; i < numsSize; ++i) { |
| |
| |
| dp[i] = max(dp[i-1], dp[i-2] + nums[i]); |
| } |
| |
| return dp[numsSize - 1]; |
| } |
| int max(int a, int b) { |
| return a > b ? a : b; |
| } |
| |
| |
| int rob(int *nums, int numsSize) { |
| int left = 0; |
| int mid = 0; |
| int right = 0; |
| |
| for (int i = 0; i < numsSize; ++i) { |
| right = max(mid, left + nums[i]); |
| left = mid; |
| mid = right; |
| } |
| |
| return right; |
| } |
| int min(int a, int b) { |
| return a > b ? b : a; |
| } |
| |
| int numSquares(int n) { |
| int dp[n + 1]; |
| dp[0] = 0; |
| for (int i = 1; i <= n; ++i) { |
| |
| dp[i] = i; |
| |
| for (int j = 1; j * j <= i; ++j) { |
| |
| |
| dp[i] = min(dp[i], dp[i - j * j] + 1); |
| } |
| } |
| |
| return dp[n]; |
| } |
| |
| |
| bool isPerfectSquare(int x) { |
| int y = sqrt(x); |
| return y * y == x; |
| } |
| |
| |
| bool checkAnswer4(int x) { |
| while (x % 4 == 0) { |
| x /= 4; |
| } |
| return x % 8 == 7; |
| } |
| |
| int numSquares(int n) { |
| if (isPerfectSquare(n)) { |
| return 1; |
| } |
| if (checkAnswer4(n)) { |
| return 4; |
| } |
| for (int i = 1; i * i <= n; i++) { |
| int j = n - i * i; |
| if (isPerfectSquare(j)) { |
| return 2; |
| } |
| } |
| return 3; |
| } |
| class Solution { |
| public: |
| |
| vector<int> count; |
| |
| int recursive(vector<int> &coins, int rem) { |
| if (rem < 0) return -1; |
| if (rem == 0) return 0; |
| |
| if (count[rem - 1] != 0) return count[rem - 1]; |
| |
| int Min = INT_MAX; |
| for (int coin: coins) { |
| |
| int res = recursive(coins, rem - coin); |
| |
| if (res >= 0) Min = min(Min, res + 1); |
| } |
| count[rem - 1] = Min == INT_MAX ? -1 : Min; |
| return count[rem - 1]; |
| } |
| |
| int coinChange(vector<int> &coins, int amount) { |
| if (amount < 1) return 0; |
| count.resize(amount); |
| return recursive(coins, amount); |
| } |
| }; |
| class Solution { |
| public: |
| int coinChange(vector<int> &coins, int amount) { |
| |
| vector<int> dp(amount + 1, amount + 1); |
| |
| dp[0] = 0; |
| |
| for (int sum = 1; sum <= amount; ++sum) { |
| for (auto &coin: coins) { |
| |
| if (coin > sum) continue; |
| |
| dp[sum] = min(dp[sum], dp[sum - coin] + 1); |
| } |
| } |
| return dp[amount] > amount ? -1 : dp[amount]; |
| } |
| }; |
| class Solution { |
| public: |
| bool wordBreak(string s, vector<string> &wordDict) { |
| |
| unordered_set<string> dict; |
| for (auto &word: wordDict) dict.insert(word); |
| |
| |
| vector<bool> dp(s.size() + 1, false); |
| dp[0] = true; |
| for (int i = 1; i <= s.size(); ++i) { |
| for (int j = 0; j < i; ++j) { |
| |
| if (dp[j] && dict.find(s.substr(j, i - j)) != dict.end()) { |
| dp[i] = true; |
| break; |
| } |
| } |
| } |
| |
| return dp[s.size()]; |
| } |
| }; |
| class Solution { |
| public: |
| int lengthOfLIS(vector<int> &nums) { |
| int len = nums.size(); |
| if (len == 0) return 0; |
| vector<int> dp(len, 0); |
| for (int i = 0; i < len; ++i) { |
| dp[i] = 1; |
| for (int j = 0; j < i; ++j) { |
| if (nums[j] < nums[i]) |
| dp[i] = max(dp[i], dp[j] + 1); |
| } |
| } |
| return *max_element(dp.begin(), dp.end()); |
| } |
| }; |
| |
| class Solution { |
| public: |
| int lengthOfLIS(vector<int> &nums) { |
| int length = 1, len = nums.size(); |
| if (len == 0) return 0; |
| vector<int> d(len + 1, 0); |
| d[length] = nums[0]; |
| for (int i = 1; i < len; ++i) { |
| if (nums[i] > d[length]) { |
| d[++length] = nums[i]; |
| } else { |
| |
| int l = 1, r = length, pos = 0; |
| while (l <= r) { |
| int mid = (l + r) >> 1; |
| if (d[mid] < nums[i]) { |
| pos = mid; |
| l = mid + 1; |
| } else { |
| r = mid - 1; |
| } |
| } |
| d[pos + 1] = nums[i]; |
| } |
| } |
| return length; |
| } |
| }; |
| int min(int a, int b) { |
| return a > b ? b : a; |
| } |
| |
| int max(int a, int b) { |
| return a > b ? a : b; |
| } |
| |
| int maxProduct(int *nums, int numsSize) { |
| int res = nums[0]; |
| |
| int minDP = nums[0]; |
| int maxDP = nums[0]; |
| |
| |
| for (int i = 1, curMin, curMax; i < numsSize; ++i) { |
| curMin = min(nums[i], min(nums[i] * minDP, nums[i] * maxDP)); |
| curMax = max(nums[i], max(nums[i] * minDP, nums[i] * maxDP)); |
| minDP = curMin; |
| maxDP = curMax; |
| res = max(res, maxDP); |
| } |
| return res; |
| } |
| class Solution { |
| public: |
| bool canPartition(vector<int> &nums) { |
| int len = nums.size(); |
| if (len < 2) return false; |
| |
| int sum = accumulate(nums.begin(), nums.end(), 0); |
| int maxNum = *max_element(nums.begin(), nums.end()); |
| if (sum & 1) return false; |
| int target = sum / 2; |
| if (maxNum > target) return false; |
| |
| vector<vector<int>> dp(len, vector<int>(target + 1, 0)); |
| for (int i = 0; i < len; i++) dp[i][0] = true; |
| dp[0][nums[0]] = true; |
| for (int i = 1; i < len; i++) { |
| int num = nums[i]; |
| for (int j = 1; j <= target; j++) { |
| if (j >= num) { |
| dp[i][j] = dp[i - 1][j] | dp[i - 1][j - num]; |
| } else { |
| dp[i][j] = dp[i - 1][j]; |
| } |
| } |
| } |
| return dp[len - 1][target]; |
| } |
| }; |
| int longestValidParentheses(char *s) { |
| int len = strlen(s); |
| if (len <= 1) return 0; |
| |
| |
| int dp[len]; |
| for (int i = 0; i < len; ++i) dp[i] = 0; |
| int max = 0; |
| for (int i = 1; i < len; ++i) { |
| |
| if (s[i] == '(') { |
| dp[i] = 0; |
| continue; |
| } |
| |
| int index = i - 1 - dp[i - 1]; |
| |
| if (index >= 0) { |
| char ch = s[index]; |
| if (ch == '(') { |
| dp[i] = dp[i - 1] + 2; |
| if (index - 1 >= 0) dp[i] += dp[index - 1]; |
| } else { |
| dp[i] = 0; |
| } |
| } else { |
| dp[i] = 0; |
| } |
| |
| if (dp[i] > max) max = dp[i]; |
| } |
| return max; |
| } |
多维动态规划
| int uniquePaths(int m, int n) { |
| |
| int dp[m][n]; |
| |
| |
| |
| for (int i = 0; i < m; ++i) dp[i][0] = 1; |
| |
| for (int i = 0; i < n; ++i) dp[0][i] = 1; |
| |
| for (int i = 1; i < m; ++i) { |
| for (int j = 1; j < n; ++j) { |
| |
| |
| dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; |
| } |
| } |
| return dp[m - 1][n - 1]; |
| } |
| int min(int a, int b) { |
| return a > b ? b : a; |
| } |
| |
| |
| int minPathSum(int **grid, int gridSize, int *gridColSize) { |
| int rowSize = gridSize; |
| int columnSize = *gridColSize; |
| |
| int dp[columnSize]; |
| dp[0] = grid[0][0]; |
| |
| for (int i = 1; i < columnSize; ++i) |
| dp[i] = dp[i - 1] + grid[0][i]; |
| |
| for (int i = 1; i < rowSize; ++i) { |
| |
| dp[0] += grid[i][0]; |
| |
| for (int j = 1; j < columnSize; ++j) |
| dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]; |
| } |
| |
| return dp[columnSize - 1]; |
| } |
| class Solution { |
| public: |
| string longestPalindrome(string s) { |
| int len = s.length(); |
| |
| vector<vector<bool>> dp(len, vector<bool>(len, false)); |
| |
| |
| for (int i = 0; i < len; ++i) dp[i][i] = true; |
| |
| |
| int start{}, length{1}; |
| |
| for (int gap = 1; gap < len; ++gap) { |
| for (int i = 0; i + gap < len; ++i) { |
| int j = i + gap; |
| |
| bool inner = gap == 1 || dp[i + 1][j - 1]; |
| |
| dp[i][j] = (s[i] == s[j]) && inner; |
| |
| if (dp[i][j]) { |
| start = i; |
| length = gap + 1; |
| } |
| } |
| } |
| |
| return s.substr(start, length); |
| } |
| }; |
| class Solution { |
| public: |
| int start{}, length{1}; |
| int len{}; |
| |
| |
| void expand(string s, int left, int right) { |
| while (left >= 0 && right < len) { |
| |
| if (s[left] != s[right]) break; |
| |
| left--; |
| right++; |
| } |
| if (right - left - 1 > length) { |
| start = left + 1; |
| length = right - left - 1; |
| } |
| } |
| |
| |
| string longestPalindrome(string s) { |
| len = s.length(); |
| |
| for (int i = 0; i < len; ++i) { |
| |
| expand(s, i, i); |
| |
| expand(s, i, i + 1); |
| } |
| |
| return s.substr(start, length); |
| } |
| }; |
| |
| class Solution { |
| public: |
| int expand(const string &s, int left, int right) { |
| while (left >= 0 && right < s.size() && s[left] == s[right]) { |
| --left; |
| ++right; |
| } |
| return (right - left - 2) / 2; |
| } |
| |
| string longestPalindrome(string s) { |
| int start = 0, end = -1; |
| string t = "#"; |
| for (char c: s) { |
| t += c; |
| t += '#'; |
| } |
| t += '#'; |
| s = t; |
| |
| vector<int> arm_len; |
| int right = -1, j = -1; |
| for (int i = 0; i < s.size(); ++i) { |
| int cur_arm_len; |
| if (right >= i) { |
| int i_sym = j * 2 - i; |
| int min_arm_len = min(arm_len[i_sym], right - i); |
| cur_arm_len = expand(s, i - min_arm_len, i + min_arm_len); |
| } else { |
| cur_arm_len = expand(s, i, i); |
| } |
| arm_len.push_back(cur_arm_len); |
| if (i + cur_arm_len > right) { |
| j = i; |
| right = i + cur_arm_len; |
| } |
| if (cur_arm_len * 2 + 1 > end - start) { |
| start = i - cur_arm_len; |
| end = i + cur_arm_len; |
| } |
| } |
| |
| string ans; |
| for (int i = start; i <= end; ++i) { |
| if (s[i] != '#') { |
| ans += s[i]; |
| } |
| } |
| return ans; |
| } |
| }; |
| int max(int a, int b) { |
| return a > b ? a : b; |
| } |
| |
| int **dp; |
| int length1; |
| int length2; |
| |
| |
| int recursive(char *s1, char *s2, int len1, int len2) { |
| if (len1 == 0 || len2 == 0) return 0; |
| if (dp[len1][len2] != -1) return dp[len1][len2]; |
| if (s1[len1 - 1] == s2[len2 - 1]) { |
| dp[len1][len2] = recursive(s1, s2, len1 - 1, len2 - 1) + 1; |
| } else { |
| |
| dp[len1][len2] = max(recursive(s1, s2, len1 - 1, len2), recursive(s1, s2, len1, len2 - 1)); |
| } |
| return dp[len1][len2]; |
| } |
| |
| int longestCommonSubsequence(char *text1, char *text2) { |
| length1 = strlen(text1); |
| length2 = strlen(text2); |
| dp = (int **) malloc(sizeof(int *) * (length1 + 1)); |
| for (int i = 0; i <= length1; ++i) { |
| dp[i] = (int *) malloc(sizeof(int) * (length2 + 1)); |
| memset(dp[i], -1, sizeof(int) * (length2 + 1)); |
| } |
| |
| return recursive(text1, text2, length1, length2); |
| } |
| int max(int a, int b) { |
| return a > b ? a : b; |
| } |
| |
| int longestCommonSubsequence(char *text1, char *text2) { |
| int length1 = strlen(text1); |
| int length2 = strlen(text2); |
| int dp[length1 + 1][length2 + 1]; |
| |
| for (int i = 0; i <= length1; ++i) dp[i][0] = 0; |
| for (int i = 0; i <= length2; ++i) dp[0][i] = 0; |
| |
| for (int len1 = 1; len1 <= length1; ++len1) { |
| for (int len2 = 1; len2 <= length2; ++len2) { |
| if (text1[len1 - 1] == text2[len2 - 1]) |
| dp[len1][len2] = dp[len1 - 1][len2 - 1] + 1; |
| else |
| dp[len1][len2] = max(dp[len1 - 1][len2], dp[len1][len2 - 1]); |
| } |
| } |
| |
| return dp[length1][length2]; |
| } |
| int max(int a, int b) { |
| return a > b ? a : b; |
| } |
| |
| int longestCommonSubsequence(char *text1, char *text2) { |
| char *s1, *s2; |
| |
| if (strlen(text1) < strlen(text2)) { |
| s1 = text2; |
| s2 = text1; |
| } else { |
| s1 = text1; |
| s2 = text2; |
| } |
| int length1 = strlen(s1); |
| int length2 = strlen(s2); |
| |
| int dp[length2 + 1]; |
| |
| memset(dp, 0, sizeof(int) * (length2 + 1)); |
| for (int len1 = 1; len1 <= length1; ++len1) { |
| |
| int leftUp = dp[0]; |
| |
| int temp; |
| for (int len2 = 1; len2 <= length2; ++len2) { |
| temp = dp[len2]; |
| if (s1[len1 - 1] == s2[len2 - 1]) |
| |
| dp[len2] = leftUp + 1; |
| else |
| |
| dp[len2] = max(dp[len2 - 1], dp[len2]); |
| leftUp = temp; |
| } |
| } |
| return dp[length2]; |
| } |
| int min(int a, int b) { |
| return a > b ? b : a; |
| } |
| |
| |
| int editDistance(char *s1, char *s2, int a, int b, int c) { |
| int len1 = strlen(s1); |
| int len2 = strlen(s2); |
| |
| int dp[len1 + 1][len2 + 1]; |
| |
| dp[0][0] = 0; |
| |
| for (int i = 1; i <= len2; ++i) |
| dp[0][i] = i * a; |
| |
| for (int i = 1; i <= len1; ++i) |
| dp[i][0] = i * b; |
| |
| for (int i = 1; i <= len1; ++i) { |
| for (int j = 1; j <= len2; ++j) { |
| |
| |
| |
| |
| |
| |
| |
| |
| int p1 = 0x7fffffff; |
| if (s1[i - 1] == s2[j - 1]) |
| p1 = dp[i - 1][j - 1]; |
| int p2 = 0x7fffffff; |
| if (s1[i - 1] != s2[j - 1]) |
| p2 = dp[i - 1][j - 1] + c; |
| int p3 = dp[i][j - 1] + a; |
| int p4 = dp[i - 1][j] + b; |
| dp[i][j] = min(min(p1, p2), min(p3, p4)); |
| } |
| } |
| return dp[len1][len2]; |
| } |
| |
| int minDistance(char *word1, char *word2) { |
| return editDistance(word1, word2, 1, 1, 1); |
| } |
| int min(int a, int b) { |
| return a > b ? b : a; |
| } |
| |
| |
| int editDistance(char *s1, char *s2, int a, int b, int c) { |
| int len1 = strlen(s1); |
| int len2 = strlen(s2); |
| |
| int dp[len1 + 1][len2 + 1]; |
| |
| dp[0][0] = 0; |
| |
| for (int i = 1; i <= len2; ++i) |
| dp[0][i] = i * a; |
| |
| for (int i = 1; i <= len1; ++i) |
| dp[i][0] = i * b; |
| |
| for (int i = 1; i <= len1; ++i) { |
| for (int j = 1; j <= len2; ++j) { |
| |
| if (s1[i - 1] == s2[j - 1]) { |
| |
| dp[i][j] = dp[i - 1][j - 1]; |
| } else { |
| |
| dp[i][j] = min(min(dp[i - 1][j - 1] + c, dp[i][j - 1] + a), dp[i - 1][j] + b); |
| } |
| } |
| } |
| return dp[len1][len2]; |
| } |
| |
| |
| int minDistance(char *word1, char *word2) { |
| return editDistance(word1, word2, 1, 1, 1); |
| } |
| int min(int a, int b) { |
| return a > b ? b : a; |
| } |
| |
| |
| int editDistance(char *s1, char *s2, int a, int b, int c) { |
| int len1 = strlen(s1); |
| int len2 = strlen(s2); |
| int dp[len2 + 1]; |
| |
| dp[0] = 0; |
| |
| for (int i = 1; i <= len2; ++i) |
| dp[i] = i * a; |
| |
| int leftUp; |
| int backup; |
| for (int i = 1; i <= len1; ++i) { |
| leftUp = (i - 1) * b; |
| |
| dp[0] = i * b; |
| for (int j = 1; j <= len2; ++j) { |
| backup = dp[j]; |
| |
| if (s1[i - 1] == s2[j - 1]) { |
| |
| dp[j] = leftUp; |
| } else { |
| |
| dp[j] = min(min(leftUp + c, dp[j - 1] + a), dp[j] + b); |
| } |
| leftUp = backup; |
| } |
| } |
| return dp[len2]; |
| } |
| |
| |
| int minDistance(char *word1, char *word2) { |
| return editDistance(word1, word2, 1, 1, 1); |
| } |
技巧
| int singleNumber(int *nums, int numsSize) { |
| int XOR = nums[0]; |
| for (int i = 1; i < numsSize; ++i) { |
| XOR ^= nums[i]; |
| } |
| return XOR; |
| } |
| |
| |
| int majorityElement(int *nums, int numsSize) { |
| int candidate = nums[0]; |
| int count = 0; |
| |
| for (int i = 0; i < numsSize; ++i) { |
| |
| |
| if (nums[i] == candidate) { |
| count++; |
| continue; |
| } |
| |
| |
| |
| if (count == 0) { |
| candidate = nums[i]; |
| count++; |
| continue; |
| } |
| |
| |
| |
| count--; |
| } |
| return candidate; |
| } |
| void swap(int *nums, int left, int right) { |
| int temp = nums[left]; |
| nums[left] = nums[right]; |
| nums[right] = temp; |
| } |
| |
| void sortColors(int *nums, int numsSize) { |
| int left = 0, right = numsSize - 1; |
| |
| while (left <= right) { |
| while (left <= right && nums[left] == 0) left++; |
| while (left <= right && nums[right] == 2) right--; |
| if (left > right) break; |
| |
| |
| if (nums[left] == 1) { |
| int index = left + 1; |
| |
| while (index <= right && nums[index] == 1) index++; |
| if (index > right) break; |
| |
| if (nums[index] == 0) { |
| swap(nums, left, index); |
| left++; |
| } else if (nums[index] == 2) { |
| swap(nums, right, index); |
| right--; |
| } |
| } else if (nums[left] == 2) { |
| swap(nums, left, right); |
| right--; |
| } |
| } |
| } |
| void swap(int *nums, int left, int right) { |
| int temp = nums[left]; |
| nums[left] = nums[right]; |
| nums[right] = temp; |
| } |
| |
| void sortColors(int *nums, int numsSize) { |
| if (numsSize == 1) return; |
| |
| int left = 0; |
| |
| int right = numsSize - 1; |
| int index = 0; |
| |
| while (index <= right) { |
| if (nums[index] == 0) { |
| |
| swap(nums, left, index); |
| left++; |
| |
| if (left > index) index = left; |
| } else if (nums[index] == 2) { |
| |
| swap(nums, right, index); |
| right--; |
| } else if (nums[index] == 1) { |
| |
| index++; |
| } |
| } |
| } |
| void swap(int *nums, int left, int right) { |
| int temp = nums[left]; |
| nums[left] = nums[right]; |
| nums[right] = temp; |
| } |
| |
| void sortColors(int *nums, int numsSize) { |
| int left = 0; |
| int right = numsSize - 1; |
| int index = 0; |
| while (index <= right) { |
| |
| while (index <= right && nums[index] == 2) { |
| swap(nums, index, right); |
| right--; |
| } |
| |
| if (nums[index] == 0) { |
| swap(nums, index, left); |
| left++; |
| } |
| index++; |
| } |
| } |
| void swap(int *nums, int left, int right) { |
| int temp = nums[left]; |
| nums[left] = nums[right]; |
| nums[right] = temp; |
| } |
| |
| void reverseArray(int *nums, int left, int right) { |
| while (left < right) |
| swap(nums, left++, right--); |
| } |
| |
| |
| |
| |
| |
| void nextPermutation(int *nums, int numsSize) { |
| int left = numsSize - 2; |
| |
| while (left >= 0 && nums[left] >= nums[left + 1]) |
| left--; |
| |
| if (left >= 0) { |
| int right = numsSize - 1; |
| |
| while (right >= 0 && nums[left] >= nums[right]) |
| right--; |
| swap(nums, left, right); |
| } |
| |
| |
| reverseArray(nums, left + 1, numsSize - 1); |
| } |
| |
| int findDuplicate(int *nums, int numsSize) { |
| int slow = 0, fast = 0; |
| slow = nums[slow]; |
| fast = nums[nums[fast]]; |
| while (slow != fast) { |
| |
| slow = nums[slow]; |
| |
| fast = nums[nums[fast]]; |
| } |
| fast = 0; |
| while (slow != fast) { |
| slow = nums[slow]; |
| fast = nums[fast]; |
| } |
| return slow; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步