class Solution1 {
public:
int firstMissingPositive(int A[], int n) {
for (int i = 0; i < n;) {
if (A[i] == i + 1) {
++i;
}
else if ((A[i] <= i) || (A[i] > n) || (A[A[i] - 1] == A[i])) {
A[i] = A[--n];
}
else {
swap(A[i], A[A[i] - 1]);
}
}
return n + 1;
}
};
void test01() {
int A[] = { 1,5,6,8,18,-1,2,3,4,10 };
int len = sizeof(A) / sizeof(A[0]);
Solution1 s;
int num = s.firstMissingPositive(A, len);
cout << "num= " << num << endl;
}
2.数组:除了二个数出现一次,其他数都出现二次
void test02(int *a,int n) {
int con = 0;
for (int i = 0; i < n; ++i) {
con ^= a[i];
}
int mask = 1;
for (; (con&mask) == 0; mask <<= 1);
int x = 0;
int y = 0;
for (int i = 0; i < n; ++i) {
if (a[i] & mask)
x ^= a[i];
else
y ^= a[i];
}
cout << "x = " << x << endl;
cout << "y = " << y << endl;
}
3.Leetcode84 给出一个直方图,求最大面积矩形。
class Solutin2 {
public:
int largestRectangleArea(vector<int> &height) {
int n = height.size(), result = 0;
stack<int> s;
for (int i = 0; i < n; ++i) {
while ((!s.empty()) && (height[s.top()] >= height[i])) {
int h = height[s.top()];
s.pop();
result = max(result, (i - 1 - (s.empty() ? (-1) : s.top()))*h);
}
s.push(i);
}
while (!s.empty()) {
int h = height[s.top()];
s.pop();
result = max(result, (n - 1 - (s.empty() ? (-1) : s.top()))*h);
}
return result;
}
};
void test03() {
Solutin2 s;
vector<int> vec = { 2,1,5,6,2,3,0 };
int result = s.largestRectangleArea(vec);
cout << "result = " << result << endl;
}
4.滑动窗口的最大值(数组上一个为k的滑动窗口的最大值求解) :运用了双端队列
void MaxNum(vector<int> &vec,vector<int> &b,int k){
deque<int> deq;
for (int i = 0; i < vec.size(); ++i) {
while (!deq.empty() && deq.front() <= i - k)
deq.pop_front(); //过期了扔掉
while (!deq.empty() && vec[deq.back()] <= vec[i])
deq.pop_back(); //太小了扔掉
deq.push_back(i); //注意:入队的是下标
b[i] = vec[deq.front()]; //队头永远是最大的值
}
}
void test04() {
vector<int> vec = { 5,1,3,4,2,6 };
vector<int> b;
b.resize(vec.size());
MaxNum(vec, b, 3);
int i = 0;
for (vector<int>::iterator it = b.begin(); it != b.end(); ++it) {
cout << i++ << ":" << *it << endl;
}
auto Max = max_element(b.begin(), b.end());
cout << "Max = " << *Max << endl;
cout << endl;
}
class Solution6 {
public:
int maxArea(vector<int>& height) {
int best = 0;
int n = height.size();
for (int i = 0, j = n - 1; i < j;) {
best = max(best, min(height[i], height[j])*(j - i));
if (height[i] < height[j])
++i;
else
--j;
}
return best;
}
};
10.给定数组a,求下标对i, j满足a[i] ≤ a[j],并且j – i最大。
int run(vector<int> &a) {
int n = a.size();
vector<int> p(n); //记录前缀最小值
for (int i = 0; i < n; ++i) {
p[i] = ((i == 0) || (a[i] < p[i - 1])) ? a[i] : p[i - 1];
}
int best = 0;
for (int j = n - 1; j > best; --j) {
while ((j > best) && (a[j] >= p[j - best - 1]))
++best;
}
return best;
}
int oneofnumbers(vector<vector<char>> &a) {
int n = a.size();
int best = 0;
for (int i = 0; (best < n) && (i < n); ++i) {
while ((best < n) && (a[i][best] == '1'))
++best;
}
return best;
}
12.Leetcode31题:(C++ STL) Next Permutation 找到字典序里的下一个排列。 12345的下一个是12354,而54321的下一个认为是12345
class Soultion7 {
public:
//算法(二找、一交换、一翻转)
void nextPermutation(vector<int> &nums) {
int n = nums.size();
int x;
for (x = n - 2; (x >= 0) && (nums[x] >= nums[x + 1]); --x)
;
if (x < 0) {
reverse(nums.begin(), nums.end());
return;
}
int y;
for (y = n - 1; nums[y] <= nums[x]; --y)
;
swap(nums[x], nums[y]);
reverse(nums.begin() + x + 1, nums.end());
}
};
void test05() {
vector<int> vec = { 1,2,3,4,5 };
Soultion7 s;
s.nextPermutation(vec);
for (auto res : vec) {
cout << res << " ";
}
cout << endl;
}
13.(codility)给定一个数组A和整数K,问有多少对下标i <= j满足max(A[i…j]) – min(A[i…j]) <= K
//滑动窗口
//用两个单调队列:一个最大值,一个最小值
int solution(vector<int> &A, int K) {
deque<int> qmin, qmax;
int answer = 0;
for (int i = 0, j = 0; i < A.size(); ++i) {
while (j < A.size()) {
while ((!qmin.empty()) && (A[qmin.back()] >= A[j]))
qmin.pop_back();
qmin.push_back(j);
while ((!qmax.empty()) && (A[qmax.back()] <= A[j]))
qmax.pop_back();
qmax.push_back(j);
if (A[qmax.front()] - A[qmin.front()] <= K)
++j;
else
break;
}
if (qmin.front() == i)
qmin.pop_front(); //到期出队
if (qmax.front() == i)
qmax.pop_front();
answer += j - i;
if (answer >= INT_MAX) //题目要求,无关紧要防止溢出
return INT_MAX;
}
return answer;
}
14.绝对众数(一定要超过数组中一半的数)的巧妙实现:
//思路:不相同的两数删除不会改变众数
int MoreOfNumbers(vector<int> &vec) {
int len = vec.size();
int count = 0;
int m = vec[0];
for (int i = 0; i < len; ++i) {
if (count == 0) {
m = vec[i];
count++;
}
else if (m != vec[i]) {
count--;
}
else {
count++;
}
}
int con = 0;
for (auto res : vec) {
if (res == m) {
con++;
}
}
if (con > len / 2) //如果确定数组有绝对众数就不用判断
return m;
return -1;
}
void testMoreOfNumbers() {
vector<int> vec = { 1,2,3,4,7,6,7,1,7,2,7,7,7,7,7};
int res = MoreOfNumbers(vec);
cout << "众数:" << res << endl;
}
15.简单练习:翻转数组简化法
void ReverseArr() {
int arr[] = { 1,2,8,7,4,5 };
int len = sizeof(arr) / sizeof(int);
for (int i = 0, j = len - 1; i < j; swap(arr[i++], arr[j--]));
for (auto res : arr)
cout << res << " ";
cout << endl;
}
1.Leetcode41 数组题:第一个缺失的正整数class Solution1 {public: int firstMissingPositive(int A[], int n) { for (int i = 0; i < n;) { if (A[i] == i + 1) { ++i; } else if ((A[i] <= i) || (A[...