# 1.29-。。。 数列

## [ 80 questions / 3 ~= 27 a month..ok.. ]

### 1.29： remove_duplicatesI-III

• focus on III
``````class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
if (nums.empty()) return false;
map<int, int> num2Idx;
// j...i
for (int i=0, j=0; i<nums.size(); ++i) {
if (i-j>k && 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: "<<i<<"; abs(it->first - nums[i])"<<it->first<<"-"<<nums[i]<<"="<<abs(it->first - nums[i])<<"?="<<t<<endl;
num2Idx[nums[i]] = i;
cout<<-2147483647-2147483647<<endl;

}
return false;
}
};
``````

blah

• sort(it1, it2, comparator: default<, use std::greater<int>() for decending)
• unordered_set<int> set1(nums1.begin(), nums1.end());

### - 349] Intersection of Two Arrays

for look up operation

``````   vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> set1(nums1.begin(), nums1.end());
vector<int> 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<int>& nums) {
int n = nums.size();
if (!n) return 0;
vector<int> 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<n; ++curr) {
if (LIS[lasti] < nums[curr]) {
LIS[++lasti] = nums[curr];
} else {
//binary search to find a pos to push: s.t. leftmost pos that nums[pos] > nums[curr]
int low = 0, high = lasti, mid = -1;
while (low<high) {
mid = low + (high-low)/2;
if (LIS[mid] < nums[curr]) {
low = mid+1;
} else {
high = mid;
}
}
LIS[low] = nums[curr];
}
} // end for
return lasti+1;
}
``````

### - 26] Remove Duplicates from Sorted Array

• don't forget corner cases
``````    int removeDuplicates(vector<int>& nums) {
if (nums.size()<2) return nums.size();
int writeri=1; // always point at next to write
}
return writeri;
}
``````

### - 88] Merge Sorted Array

• 因为都要写到array1，所以只担心array2后排完的时候
``````    void merge(vector<int>& nums1, int m, vector<int>& 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

Paste_Image.png
``````    void rotate(vector<int>& nums, int k) {
int n = nums.size();
if (n<2) return;
k %= n;
for (int step=0; step<k && starti<n-1; ++step) {
swap(nums[starti+step], nums[n-k+starti+step]);
}
starti += k;
n -= k;
}
``````
• generate random num:
``````int randNum = rand()%(max-min + 1) + min;
``````

### - 384] Shuffle an Array

• 洗牌算法

2.1，问题

2.2，解决

a,选中第1个元素，将其与n个元素中的任意一个交换(包括第1个元素自己)。这时排序后的第1个元素已经确定。
b,选中第2个元素，将其与n-1个元素中作任意一个交换(包括第2个元素自己)。
c,重复上面步骤，直到剩1个元素为止。

### 1] Two sum I: better

``````    vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> valToIndex;
for (int i=0; i<nums.size(); ++i) {
int diff = target-nums[i];
if (valToIndex.find(diff) != valToIndex.end()) {
return vector<int> {valToIndex[diff], i};
}
valToIndex[nums[i]] = i;
}
return vector<int>{};
}
``````

### 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<int>& nums) {
int n = nums.size();
int maxSum = nums[0];
for (int i=1; i<nums.size(); ++i) {
nums[i] = nums[i-1] < 0? nums[i] : nums[i] + nums[i-1];
maxSum = max(maxSum, nums[i]);
}
return maxSum;
}
``````

### 153] Find Minimum in Rotated Sorted Array

• don't forget when its not rotated
``````   int findMin(vector<int>& 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<endi; ) {
if (starti+1 == endi)
return min(nums[starti], nums[endi]);
int midi = (endi - starti)/2 + starti;
if (nums[starti] < nums[midi]) starti = midi;
else endi = midi;
}
return -1;
}
``````

### 80] Remove Duplicates from Sorted Array II

• how to avoid overwrite self
``````    int removeDuplicates(vector<int>& nums) {
if (nums.size()<2) return nums.size();
int writei = 2;
}
return writei;
}
``````

### 215] Kth Largest Element in an Array

• ehhh don't like 1-indexed..
``````    int findKthLargest(vector<int>& nums, int k) { // k is 1-indexed
if (k>nums.size() || k<1) return -1;
priority_queue<int, std::vector<int>, std::greater<int>> minHeap(nums.begin(), nums.begin()+k);
for (int i=k; i<nums.size(); ++i) {
if (nums[i]>minHeap.top()) {
minHeap.pop();
minHeap.push(nums[i]);
}
}
return minHeap.top();
}
``````

### 81] Search in Rotated Sorted Array II

``````    int search(vector<int>& nums, int target) {
if (nums.empty()) return -1;
int l=0, r=nums.size()-1;
for (; l<r; ) {
int mid = l + (r-l)/2;
if (nums[mid] == target) {
return mid;
} else if (nums[l] <= nums[mid]) {
if (nums[l]<=target && target<nums[mid])
r = mid -1;
else
l = mid + 1;
} else {
if (nums[mid]<target && target<=nums[r])
l = mid + 1;
else
r = mid - 1;
}
}
return l==r && nums[l]==target? l : -1;
}
``````

### 81] Search in Rotated Sorted Array II

• 多出了不能确定递增的情况：左=中 或 中=右
``````    bool search(vector<int>& nums, int target) {
if (nums.empty()) return -1;
int l=0, r=nums.size()-1;
while (l<r) {
int mid = l+(r-l)/2;
if (nums[mid] == target) {
return true;
} else if (nums[l] < nums[mid]) {
if (nums[l]<=target && target<nums[mid])
r = mid -1;
else l = mid + 1;
} else if (nums[mid] < nums[r]) {
if (nums[mid]<target && target<=nums[r])
l = mid + 1;
else
r = mid - 1;
} else if (nums[l] == nums[mid]) {
++l;
} else {
--r;
}
}
return l==r && nums[l]==target;
}
``````

### 209] Minimum Size Subarray Sum

• method1: O(n)
because the left bound moves O(n) times in worst case
``````    int minSubArrayLen(int s, vector<int>& nums) {
int minLen = INT_MAX;
int acc = 0;
for (int starti=0, endi=0; endi<nums.size(); ) {
if (acc + nums[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<int>& 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<int>& nums) {
if (nums.empty() || !s) return 0;
vector<int> sums(nums.size()+1, 0);
for (int i=1; i<sums.size(); ++i) sums[i] = sums[i-1] + nums[i-1];

int minLen = INT_MAX;
for (int i=1; i<sums.size(); ++i) {
if (sums[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 ["<<i-1<<"]"<<" for sums[i]-s "<<sums[i]-s<<"--get ["<<loweri<<"] "<<sums[loweri]<<endl;
int lefti = loweri+1; // easier to understand
minLen = min(minLen, i-lefti+1);
}
}
return minLen==INT_MAX? 0 : minLen;
}
``````

### 152] Maximum Product Subarray

1）最大负数 X 当前负数
2）最大正数 X 当前正数
3）当前数

``````    int maxProduct(vector<int>& nums) {
if (nums.empty()) return 0;
int posPro = nums[0], negPro = nums[0], ret = nums[0];
for (int i=1; i<nums.size(); ++i) {
int pro1 = posPro * nums[i];
int pro2 = negPro * nums[i];
posPro = max(max(pro1, pro2), nums[i]);
negPro = min(min(pro1, pro2), nums[i]);
ret = max(ret, posPro);
}
return ret;
}
``````
• 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<s.size() && s[i+1]!='I'? -1 : 1;
break;
case 'X':
ret += i+1<s.size() && s[i+1]!='I' && s[i+1]!='V'  && s[i+1]!='X' ? -10 : 10;
break;
case 'C':
ret += i+1<s.size() && (s[i+1]=='M' || s[i+1]=='D') ? -100 : 100;
break;
case 'M':
ret += 1000;
break;
case 'V':
ret += 5;
break;
case 'L':
ret += 50;
break;
case 'D':
ret += 500;
break;
}
}
return ret;
}
``````

### [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<int>& coins, int amount) {
if (amount<0) return -1;

// minCoins[amount] gives min #coins
vector<int> minCoins(amount+1, amount+1);
minCoins[0] = 0;
for (int i=1; i<amount+1; ++i) {
for (int& coin : coins) {
// continue if cannot break the change using this coin
if (i-coin<0) continue;
minCoins[i] = min(minCoins[i], minCoins[i-coin]+1);
}
}
return minCoins[amount]==amount+1? -1 : minCoins[amount];
}
``````

### quick sort

``````int partition(vector<int>& 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) {
++i;
} else if (v[j]>pivot) {
--j;
} else {
if (i<j) swap(v[i++], v[j--]);
}
}
swap(v[i-1], v[l]);
return i-1;
}

void quickSort(vector<int>& 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);
}
``````

### 推荐阅读更多精彩内容

• 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪：刷leetcod...
土汪阅读 11,764评论 0 33
• 不支持上传文件，所以就复制过来了。作者信息什么的都没删。对前端基本属于一窍不通，所以没有任何修改，反正用着没问题就...
全栈在路上阅读 1,620评论 0 2
• 今天，我又听说了一起压力型自杀事件。 91年的大学生，在面对职场和人际关系的问题中压力无法消解，最终选择了跳楼。 ...
耳羽荷阅读 197评论 0 1
• 文丨十四 遇见大白的时候，他已经六十岁了。没有什么冲动怜悯，把大白捡回家，就是图个伴。 他不是没有老婆孩子，可是人...
Lillianico阅读 138评论 2 0
• 今天是除夕夜，可是我一点都没有感受到新年的快乐，家里的琐事，自己的烦恼影响到睡觉都在紧皱眉头。 一个人的脸色好坏不...
是change阅读 76评论 0 0