[ 80 questions / 3 ~= 27 a month..ok.. ]
1.29: remove_duplicatesI-III
- focus on III
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector& nums, int k, int t) {
if (nums.empty()) return false;
map num2Idx;
// j...i
for (int i=0, j=0; ik && num2Idx[nums[j]]==j) {
num2Idx.erase(nums[j++]);
}
auto it=num2Idx.lower_bound(nums[i]-t);
if (it!=num2Idx.end() && abs(it->first - nums[i]) <= t) {//it->first <= nums[i]+t) {
return true;
}
if (it!=num2Idx.end())
cout<<"i: "<first - nums[i])"<first<<"-"<first - nums[i])<<"?="<
blah
- sort(it1, it2, comparator: default<, use std::greater
() for decending) - unordered_set
set1(nums1.begin(), nums1.end());
- 349] Intersection of Two Arrays
for look up operation
vector intersection(vector& nums1, vector& nums2) {
unordered_set set1(nums1.begin(), nums1.end());
vector ret;
for (int i : nums2)
if (set1.erase(i))
ret.push_back(i);
return ret;
}
- Longest Increasing Subsequence
- basic dp: O(n^2)
- w/ binary search to narrow down where to place each num[curr] O(nlogn)
试着构建LIS array来找规律
int lengthOfLIS(vector& nums) {
int n = nums.size();
if (!n) return 0;
vector LIS(n, -1); // stores the actual LIS, initialize [0] to be 1
int lasti = 0; // end pointer points to last char of LIS
LIS[lasti] = nums[0];
for (int curr=1; curr nums[curr]
int low = 0, high = lasti, mid = -1;
while (low
- 26] Remove Duplicates from Sorted Array
- don't forget corner cases
int removeDuplicates(vector& nums) {
if (nums.size()<2) return nums.size();
int writeri=1; // always point at next to write
for (int readeri=1; readeri
- 88] Merge Sorted Array
- 因为都要写到array1,所以只担心array2后排完的时候
void merge(vector& nums1, int m, vector& nums2, int n) {
int writei = m+n-1;
int i=m-1, j=n-1;
while (i>=0 && j>=0)
nums1[writei--] = nums1[i] > nums2[j]? nums1[i--] : nums2[j--];
while (j>=0) nums1[writei--] = nums2[j--];
}
- rotate array
通过不停的交换某两个数字的位置来实现旋转
void rotate(vector& nums, int k) {
int n = nums.size();
if (n<2) return;
k %= n;
for (int step=0; step
- generate random num:
int randNum = rand()%(max-min + 1) + min;
- 384] Shuffle an Array
- 洗牌算法
2.1,问题
很简单:给定一个数组,将其中的元素随机排列。比如给定数组arry=>[1,2,3,4,5]。有A5-5种结果即5!=120种结果
2.2,解决
也很简单,如果用白话来说就是:
a,选中第1个元素,将其与n个元素中的任意一个交换(包括第1个元素自己)。这时排序后的第1个元素已经确定。
b,选中第2个元素,将其与n-1个元素中作任意一个交换(包括第2个元素自己)。
c,重复上面步骤,直到剩1个元素为止。
1] Two sum I: better
vector twoSum(vector& nums, int target) {
unordered_map valToIndex;
for (int i=0; i {valToIndex[diff], i};
}
valToIndex[nums[i]] = i;
}
return vector{};
}
167] Two Sum II - Input array is sorted
use two pointers to narrow down, but also can use binary search to determine one of the bounds. e.g. find smallest num s.t. num + [0] >=target
53] Maximum Subarray
int maxSubArray(vector& nums) {
int n = nums.size();
int maxSum = nums[0];
for (int i=1; i
153] Find Minimum in Rotated Sorted Array
- don't forget when its not rotated
int findMin(vector& nums) {
if (nums.empty()) return -1;
if (nums[0] <= nums[nums.size()-1]) return nums[0];
for (int starti=0, endi=nums.size()-1; starti
80] Remove Duplicates from Sorted Array II
- how to avoid overwrite self
int removeDuplicates(vector& nums) {
if (nums.size()<2) return nums.size();
int writei = 2;
for (int readi=2; readi
215] Kth Largest Element in an Array
- ehhh don't like 1-indexed..
int findKthLargest(vector& nums, int k) { // k is 1-indexed
if (k>nums.size() || k<1) return -1;
priority_queue, std::greater> minHeap(nums.begin(), nums.begin()+k);
for (int i=k; iminHeap.top()) {
minHeap.pop();
minHeap.push(nums[i]);
}
}
return minHeap.top();
}
81] Search in Rotated Sorted Array II
int search(vector& nums, int target) {
if (nums.empty()) return -1;
int l=0, r=nums.size()-1;
for (; l
81] Search in Rotated Sorted Array II
设想一种情形1,1, 1,2,1,1,1,恰好左中右都是1,这时我们 ++左下标,--右下标,为什么这样我们不会将这个值跳过呢?
- 多出了不能确定递增的情况:左=中 或 中=右
bool search(vector& nums, int target) {
if (nums.empty()) return -1;
int l=0, r=nums.size()-1;
while (l
209] Minimum Size Subarray Sum
- method1: O(n)
because the left bound moves O(n) times in worst case
int minSubArrayLen(int s, vector& nums) {
int minLen = INT_MAX;
int acc = 0;
for (int starti=0, endi=0; endi= s) {
minLen = min(minLen, endi-starti+1);
acc -= nums[starti];
++starti;
} else {
acc += nums[endi];
++endi;
}
}
return minLen == INT_MAX? 0 : minLen;
}
- method2: O(nlogn) using binary search
idea: keep a sums array that keep track of accumulated sum, search for lower bound for every qualifying upper bound
// return biggest index i s.t. i<=uppderIndex && [i]<=upperVal
int lowerBound(vector& v, int upperIndex, int upperVal) {
// try to find biggest num <= upperVal
int ret = 0;
for (int lefti=0, righti=upperIndex; lefti<=righti; ) {
int midi = lefti + (righti-lefti)/2;
if (v[midi] > upperVal) {
righti = midi-1;
} else {
ret = max(ret, midi);
lefti = midi + 1;
}
}
return ret;
}
int minSubArrayLen(int s, vector& nums) {
if (nums.empty() || !s) return 0;
vector sums(nums.size()+1, 0);
for (int i=1; i=s) {
// find rightmost index j s.t. j<=i, sums[j]<=[i]-s
int loweri = lowerBound(sums, i-1, sums[i]-s);
// cout<<"search till ["<
152] Maximum Product Subarray
写的时候分情况考虑了,如果碰到负数,正数,0?想要保证posPro>=0, negPro<=0, 越写越复杂因为初始什么值?要用上一轮值的时候?
其实每一步把可能答案先算出来,再compare和assign值。加入新值,新最大候选人:
1)最大负数 X 当前负数
2)最大正数 X 当前正数
3)当前数
int maxProduct(vector& nums) {
if (nums.empty()) return 0;
int posPro = nums[0], negPro = nums[0], ret = nums[0];
for (int i=1; i
- another method
int maxProduct(int A[], int n) { // store the result that is the max we have found so far int r = A[0]; // imax/imin stores the max/min product of // subarray that ends with the current number A[i] for (int i = 1, imax = r, imin = r; i < n; i++) { // multiplied by a negative makes big number smaller, small number bigger // so we redefine the extremums by swapping them if (A[i] < 0) swap(imax, imin); // max/min product for the current number is either the current number itself // or the max/min by the previous number times the current one imax = max(A[i], imax * A[i]); imin = min(A[i], imin * A[i]); // the newly computed max value is a candidate for our global result r = max(r, imax); } return r;}
[13] Roman to Integer
int romanToInt(string s) {
// Ⅰ(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)
// if smaller number (I, X, C) is left of bigger number, + bigger number - smaller number
int ret = 0;
for (int i=s.size()-1; i>=0; --i) {
switch (s[i]) {
case 'I':
ret += i+1
[322] Coin Change
O(amount*n)
- instead of init dp arr as -1, use amount+1 as the invalid state, easier to take min later
int coinChange(vector& coins, int amount) {
if (amount<0) return -1;
// minCoins[amount] gives min #coins
vector minCoins(amount+1, amount+1);
minCoins[0] = 0;
for (int i=1; i
quick sort
int partition(vector& v, int l, int r) {
int pivot = v[(l+r)/2];
swap(v[l], v[(l+r)/2]);
int i=l+1, j=r;
while (i<=j) {
if (v[i]pivot) {
--j;
} else {
if (i& v, int l, int r) {
if (l>=r) return;
int pivoti = partition(v, l, r);
quickSort(v, l, pivoti-1);
quickSort(v, pivoti+1, r);
}