代码随想录算法训练营第二天| 977.有序数组的平方、27. 移除元素

977.有序数组的平方

暴力排序:时间复杂度是O(n+nlogn),主要取决于排序的算法复杂度

双指针思路:

数组平方的最大值就在数组的两端,不是最左边就是最右边。考虑两个指针分别指向两端,向中间移动,更大的值赋值到k的位置。k从数组的末端开始往前遍历。

Leetcode977

给你一个按 非递减顺序 排序的整数数组 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)

Leetcode209

Given an array of positive integers nums and a positive integer target, return the minimal length of a subarray whose sum is greater than or equal to target. If there is no such subarray, return 0 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

Leetcode59

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;
    }
};

第二十二天的算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,使得子数组的和大于等于给定的目标值。这里可以使用滑动窗口的方法来解决问题。使用两个指针来表示滑动窗口的左边界和右边界,通过移动指针来调整滑动窗口的大小,使得滑动窗口中的元素的和满足题目要求。具体实现的代码如下: ```python def minSubArrayLen(self, target: int, nums: List[int]) -> int: left = 0 right = 0 ans = float('inf') total = 0 while right < len(nums): total += nums[right] while total >= target: ans = min(ans, right - left + 1) total -= nums[left] left += 1 right += 1 return ans if ans != float('inf') else 0 ``` 以上就是第二十二天的算法训练营的内容。通过这些题目的练习,可以提升对双指针和滑动窗口等算法的理解和应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值