977.有序数组的平方
暴力排序:时间复杂度是O(n+nlogn),主要取决于排序的算法复杂度
双指针思路:
数组平方的最大值就在数组的两端,不是最左边就是最右边。考虑两个指针分别指向两端,向中间移动,更大的值赋值到k的位置。k从数组的末端开始往前遍历。
给你一个按 非递减顺序 排序的整数数组
nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
class Solution {
public:
vector<int> sortedSquares(vector<int>& A) {
int k = A.size() - 1;
vector<int> result(A.size(), 0);
for (int i = 0, j = A.size() - 1; i <= j;) { // 注意这里要i <= j,因为最后要处理两个元素
if (A[i] * A[i] < A[j] * A[j]) {
result[k--] = A[j] * A[j];
j--;
}
else {
result[k--] = A[i] * A[i];
i++;
}
}
return result;
}
};
209.长度最小的子数组
主要思想:滑动窗口(不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果)
滑动窗口也可以理解为双指针法的一种
一个for循环做两个for的事情。j表示终止位置,它一步一步向后移动,但如何移动起始位置?
如果集合里面的元素大于s的话,起始位置往后移动。
最终可以实现O(n^2)的时间复杂度降为O(n)
Given an array of positive integers
nums
and a positive integertarget
, return the minimal length of a subarray whose sum is greater than or equal totarget
. If there is no such subarray, return0
instead.
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int length = INT32_MAX; //32位系统size的limits
int left = 0; //窗口起始位置,满足条件的情况下移动
int sum = 0; //滑动窗口数值之和
for(int right = 0; right<nums.size(); right++){ //遍历终止位置
sum+=nums[right];
while(sum>=target){ //满足窗口之和大于target
length = min(length, right-left+1); //取最小子序列的长度
sum-=nums[left];
left++; //移动起始位置
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return length == INT32_MAX? 0:length;
}
};
附加题:
Sliding window slution||using map
Approach: Use a hash map to keep track of the count of each type of fruit within the current window.
If the window contains more than two types of fruits, move the start pointer to the right until the window contains at most two types of fruits. Update the hash map accordingly by decreasing the counts.
If the hash map of start pointer is 0, erase this in map.
- Time complexity:O(n)
- Space complexity:O(1)
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int left = 0;
int len = 0;
unordered_map<int,int> m;
for(int right = 0; right<fruits.size(); right++){
m[fruits[right]]++;
while(m.size()>2){
m[fruits[left]]--;
if (m[fruits[left]] == 0) {
m.erase(fruits[left]);
}
left++;
}
len = max(len, right-left+1);
}
return len;
}
};
还只尝试了最基础的方法写,不知道怎么进一步代码优化:
class Solution {
public:
string minWindow(string s, string t) {
int sLen = s.size();
int tLen = t.size();
if(sLen == 0||tLen ==0||sLen<tLen) return "";
int winFreq[128];
int tFreq[128];
for(char c:t){
tFreq[c]++;
}
int distance = 0;
int minLen = sLen+1;
int begin = 0;
int left=0, right=0;
while(right < sLen){
if(tFreq[s[right]] == 0){
right++;
continue;
}
if(winFreq[s[right]]<tFreq[s[right]]){
distance++;
}
winFreq[s[right]]++;
right++;
while(distance == tLen){
if(right - left < minLen){
minLen = right-left;
begin = left;
}
if(tFreq[s[left]]==0){
left++;
continue;
}
if(winFreq[s[left]]==tFreq[s[left]]){
distance--;
}
winFreq[s[left]]--;
left++;
}
}
return minLen == sLen+1? "":s.substr(begin, minLen);
}
};
59.螺旋矩阵II
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
int startx = 0, starty = 0;
int offset = 1;
int val = 1;
vector<vector<int>> m(n,vector<int>(n,0)); //important
int loop = n/2; // easy to fail use n/2...
while(loop--){
int j=startx;
int i=starty; // initilize inside the while!
for(; j<size-offset; j++){
m[i][j] = val++;
}
for(; i<size-offset; i++){
m[i][j] = val++;
}
for(;j>startx; j--){
m[i][j] = val++;
}
for(;i>starty;i--){
m[i][j] = val++;
}
startx++;
starty++;
offset++;
}
if(n%2==1){
m[n/2][n/2] = val;
}
return m;
}
};