方法1
// 时间复杂度: O(log n)
// 空间复杂度: O(1)
class Solution {
public:
int search(vector<int>& nums, int target) {
int n = nums.size();
int left = 0;
int right = n-1;
while(left <= right){
int mid = left+((right-left)/2);
if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}else{
return mid;
}
}
return -1;
}
};
方法2
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while(left < right){// 等于时无意义
int mid = left + (right-left)/2;
if(nums[mid] > target){
right = mid;
}else if(nums[mid] < target){
left = mid+1;
}else{
return mid;
}
}
return -1;
}
};
// 时间复杂度: O(log n)
// 空间复杂度: O(1)
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int n = nums.size();
int left = 0;
int right = n-1;
while(left <= right){
int mid = left + ((right-left)/2);
if(nums[mid] > target){
right = mid-1;
}else if(nums[mid] < target){
left = mid + 1;
}else{
return mid;// 等于数组中某个存在元素
}
}
return right+1;// 其它三种情况
}
};
class Solution {
public:
/*
nums: 5 7 7 8 8 10
index: 0 1 2 3 4 5
*/
int getLeftBorder(vector<int>& nums,int target){
int left = 0;
int right = nums.size()-1;
int ret = -2;
while(left <= right){
int mid = left + (right-left)/2;
if(nums[mid] >= target){
right = mid - 1;
ret = right;
}else{
left = mid + 1;
}
}
return ret;
}
int getRightBorder(vector<int>& nums,int target){
int left = 0;
int right = nums.size()-1;
int ret = -2;
while(left <= right){
int mid = left + (right-left)/2;
if(nums[mid] > target){
right = mid - 1;
}else{
left = mid + 1;
ret = left;
}
}
return ret;
}
vector<int> searchRange(vector<int>& nums, int target) {
int leftBorder = getLeftBorder(nums,target);
int rightBorder = getRightBorder(nums,target);
if(leftBorder == -2 || rightBorder == -2){// 情况三
return {-1,-1};
}
if(rightBorder - leftBorder > 1){
return {leftBorder+1,rightBorder-1};// 情况二
}
return {-1,-1};// 情况一
}
};
// 时间复杂度 O(logn)
// 空间复杂度 o(1)
class Solution {
public:
int mySqrt(int x) {
int left = 0;
int right = x;
int ret = -1;
while(left <= right){
int mid = left + (right-left)/2;
if((long long)mid * mid <= x){
ret = mid;
left = mid + 1;
}else{
right = mid -1;
}
}
return ret;
}
};
// 时间复杂度 O(logn)
// 空间复杂度 O(1)
class Solution {
public:
bool isPerfectSquare(int num) {
int left = 0;
int right = num;
while(left <= right){
int mid = left + (right-left)/2;
if((long long)mid*mid < num){
left = mid + 1;
}else if((long long)mid* mid > num){
right = mid - 1;
}else{
return true;
}
}
return false;
}
};
// 时间复杂度O(n²)
// 空间复杂度O(1)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
/*3 3 2 2 3 3
3 3 2 3 3
*/
int n = nums.size();
for(int i = 0 ; i < n ;i++){
if(nums[i] == val){
for(int j = i+1;j < n;j++){
nums[j-1] = nums[j];
}
i--;// 后面整体前移,i也前移
n--;
}
}
return n;
}
};
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n = nums.size();
int slowIndex = 0;
for(int fastIndex = 0;fastIndex < n;fastIndex++){
if(nums[fastIndex] != val){// 找到目标值了,慢指针就不动了
nums[slowIndex++] = nums[fastIndex];// 把后面不是目标值的替换上来
}
}
return slowIndex;
}
};
// 时间复杂度 O(n)
// 空间复杂度 O(1)
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int slow = 1;
int fast = 1;
int n = nums.size();
if(n == 0){
return 0;
}
while( fast < n){
if(nums[fast] != nums[fast-1]){
nums[slow++] = nums[fast];
}
fast++;
}
// 从题目中可以看出,根据新的长度来遍历数组进行判断
return slow;
}
};
// 时间复杂度O(N)
// 空间复杂度O(1)
class Solution {
public:
void moveZeroes(vector<int>& nums) {
// 在不赋值数组的情况下原地对数组进行操作
int n = nums.size();
if(n == 0)return ;
int fast = 0;
int slow =0;
while(fast < n){
if(nums[fast] != 0){
swap(nums[slow++],nums[fast]);
}
fast++;
}
}
};
// 时间复杂度O(n)
// 空间复杂度O(m+n) 貌似
class Solution {
public:
string build(string s){
int n = s.size();
int slow = 0;
for(int fast = 0;fast < n;fast++){
if(s[fast] != '#'){
s[slow] = s[fast];
slow++;
}else if(slow > 0){
slow--;
}
}
return s.substr(0,slow);
}
bool backspaceCompare(string s, string t) {
return build(s) == build(t);
}
};
// 时间复杂度 O(m+n) 即O(n)
// 空间复杂度 O(m+n)
class Solution {
public:
string build(string s){
stack<char>st;
for(char c:s){
if(c != '#'){// 刚开始这里多了个条件,st.empty()然后把我坑了。
st.push(c);
}else if(c == '#' && !st.empty()){
st.pop();
}
}
string ret = "";
while(!st.empty()){
ret += st.top();
st.pop();
}
return ret;
}
bool backspaceCompare(string s, string t) {
return build(s) == build(t);
}
};
// 时间复杂度 O(n)
// 空间复杂度 O(n)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int i = 0;
int j = nums.size() - 1;
int k = nums.size() - 1;
vector<int>ret(nums.size());
while(i <= j){
if(nums[j]*nums[j] > nums[i]*nums[i]){
ret[k--] = nums[j]*nums[j];
j--;
}else{
ret[k--] = nums[i] * nums[i];
i++;
}
}
return ret;
}
};
// 时间复杂度 O(n+nlogn)
// 空间复杂度 O(n)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
for(int i = 0; i < n;i++){
nums[i] *= nums[i];
}
sort(nums.begin(),nums.end());
return nums;
}
};
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
int ret = INT_MAX;// 结果
int sum = 0;// 窗口内元素之和
int i = 0;// 窗口的左侧
int subLength = 0;// 窗口的长度
for(int j = 0; j < n ; j++){
sum += nums[j];
while(sum >= target){// 维护窗口
subLength = j - i + 1;
ret = ret > subLength?subLength:ret;
sum -= nums[i++];
}
}
return ret == INT_MAX ? 0 : ret;
}
};
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
public:
int totalFruit(vector<int>& fruits) {
unordered_map<int,int>mp;
int n = fruits.size();
int ret = 0;// 保存结果,摘取的水果数量
for(int i = 0,j = 0;i < n; i++){
mp[fruits[i]]++;// 摘取水果
while(mp.size() > 2){// 维护滑动窗口
int cur = fruits[j++];
if(--mp[cur] == 0)mp.erase(cur);// 将水果篮中的一种水果拿光了,这时栏中又只剩两种水果了
}
ret = max(ret,i-j+1);// 求长度,即数量
}
return ret;
}
};
// 时间复杂度O(n)
// 空间复杂度O(m+n) 貌似
class Solution {
public:
string minWindow(string s, string t) {
//ts为统计我们需要的字符与其对应的数量,ss为我们维护的滑动窗口
unordered_map<char,int>ts,ss;
// 先统计要查找字符串中各个字符的数量
for(char& c:t)ts[c]++;
int n = s.size();
string ret;
int cnt = 0;// 统计当前应该收集元素的个数
for(int i = 0,j=0;i<n;i++){
ss[s[i]]++;
// 统计收集的指定元素数量和,即找到t中的所有字符,在s中。
if(ss[s[i]] <= ts[s[i]])cnt++;
// 窗口收缩,如果当前的元素s[j](窗口左边界)收集的数量已经大于我们需要的,那就收缩左边界。或者去掉t中没有的元素。
while(ss[s[j]] >ts[s[j]])ss[s[j++]]--;
if(cnt == t.size()){// 每种元素都收集到了,开始计算长度
if(ret.empty() || i-j+1 < ret.size()){// 减少计算次数,如果没计算过或找到更小的连续子数组,才计算,收集结果。
ret = s.substr(j,i-j+1);
}
}
}
return ret;
}
};
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>>ret(n,vector<int>(n,0));
int starX = 0;// 每圈开头
` int starY = 0;
int loop = n / 2;// 转几圈
int mid = n / 2;// 矩阵中间的位置
int count = 1;// 每个元素值
int offset = 1;// 收缩个数
// 顺时针转
int i = 0,j =0;
while(loop--){
i = starX;
j = starY;
// 左闭右开
for(j = starY;j < n-offset;j++){
ret[starX][j] = count++;
}
for(i = starX;i < n-offset;i++){
ret[i][j] = count++;
}
for(;j > starY;j--){
ret[i][j] = count++;
}
for(;i > starX;i--){
ret[i][j] = count++;
}
offset++;
starX++;
starY++;
}
if(n % 2){// 给中间位置单独赋值
ret[mid][mid] = count;
}
return ret;
}
};
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int rc = matrix.size()-1;// 行数-下边界
int cc = matrix[0].size()-1;// 列数-右边界
int row = 0;// 标记当前行-上边界
int col = 0;// 标记当前列-左边界
vector<int>ret;
while(true){
for(int i = col;i <= cc;i++){
ret.push_back(matrix[row][i]);
}
if(++row > rc)break;// 收缩上边界
for(int i = row;i <= rc;i++){
ret.push_back(matrix[i][cc]);
}
if(--cc < col)break;// 收缩右边界
for(int i = cc;i >= col;i--){
ret.push_back(matrix[rc][i]);
}
if(--rc < row)break;// 收缩下边界
for(int i = rc;i>= row;i--){
ret.push_back(matrix[i][col]);
}
if(++col > cc)break;// 收缩左边界
}
return ret;
}
};
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int>ret;
if(matrix.empty())return ret;
int rc = matrix.size()-1;// 下
int cc = matrix[0].size()-1;// 右
int row = 0;//上
int col = 0;// 左
while(true){
for(int i = col;i <=cc;i++){
ret.push_back(matrix[row][i]);
}
if(++row > rc)break;
for(int i = row;i <= rc;i++){
ret.push_back(matrix[i][cc]);
}
if(--cc < col)break;
for(int i = cc; i >= col;i--){
ret.push_back(matrix[rc][i]);
}
if(--rc < row)break;
for(int i = rc; i >= row;i--){
ret.push_back(matrix[i][col]);
}
if(++col > cc)break;
}
return ret;
}
};