代码随想录day2

10 阅读3分钟

学习长度最短子数组计算和螺旋矩阵

最短子数组: 解法一:暴力解法,实际类似与冒泡排序,这种解法耗时长,而且没有利用到之前计算所提供的信息

解法二:双指针法。结合day1的双指针法,这里重新理解一下。双指针实际是两个标记,这两个标记是动态浮动的,而且尽管在双循环内,两个指针都仅最多遍历数组一次,这就实现了对之前sum数据的完整利用,浮动的末尾指针由此克服了反复遍历数组的缺点。

class Solution { public: int minSubArrayLen(int target, vector& nums) { int sum=0; int i=0,j=0; int minLen=INT_MAX; int sublen=0; for(;j<nums.size();j++){ sum+=nums[j]; while(sum>=target){

             sublen=j-i+1;
             minLen=min(minLen,sublen);
             sum=sum-nums[i]; 
             i++;  
        }

    }
   return minLen == INT_MAX ? 0 : minLen;
}

}; 需要注意的是,关于minLen的初值设置应当选择极大值,而不能笼统的设置为数组长度,并增加最后判断来排除数组和最大值小于target的情况。另外,设置的初值建议进行初始化,而不是进行默认处理,不然很容易出现报错。 拓展题目:904,76;

螺旋数组

解法思路:思考每一层循环的不变量,同时通过count进行赋值,这样通过层层迭代既可以完成代码编写。需要在区分奇数和偶数的情况,把特殊情况提出来,同时注意x,y数组每次迭代的上下界。
class Solution {

public: vector<vector> generateMatrix(int n) {

          int starx=0,stary=0;
          int offset=1;
          int count=1;
          int loop=n/2;
          int mid=n/2;
          vector<vector<int>> matrix(n, vector<int>(n));
          while(loop--){
              int x=starx;
              int y=stary;
              for (; y < n - offset; y++) {
                matrix[x][y] = count++;
                     }
        // 2. 填充右列:从上到下(闭区间[startX, n-offset]),y固定为当前值
              for (; x < n - offset; x++) {
                 matrix[x][y] = count++;
                      }
        // 3. 填充底行:从右到左(闭区间[offset, startY]),x固定为当前值
              for (; y > stary; y--) {
                 matrix[x][y] = count++;
                  }
        // 4. 填充左列:从下到上(闭区间[offset, startX]),y固定为startY
               for (; x > starx; x--) {
                  matrix[x][y] = count++;
                  }
                offset++;
                starx++;
                stary++;
          }
           if(n%2==1){
            matrix[mid][mid]=count;
           }
    return matrix;
}

};

76题思路,同样采用双指针形成滑动窗口,难点在于维护hash表,利用数组寻秩访问的特性达到O(1)时间内快速记录访问。 class Solution { public: string minWindow(string s, string t) { if (s.empty() || t.empty() || s.length() < t.length()) { return ""; }

    //假设字符在ASCII码范围内
    int need[128];
    int start=0;
    memset(need, 0, sizeof(need)); // 关键:初始化数组为0,避免随机值
    for (char c : t) { // C++遍历string,无需转字符数组
        need[c]++;
    }
    //定义滑动窗口左右指针
    int left=0,right=0;
    int minlen=INT_MAX;
    int needcount=t.length();

    while(right<s.length()){
     char right_=s[right];
     //比对是否为符合要求字符,并进行记录
     if(need[right_]>0){
        needcount--;
     }
     need[right_]--;
     right++;

     //出现所有字符全部找到的情况时,进行缩减
     while(needcount==0){
        int temp=right-left;
        if(minlen>temp){
            minlen=temp;
            start=left;
        }
        char left_=s[left];
        need[left_]++;
        if(need[left_]>0){
            needcount++;
        }
        left++;
     }
    }
    return minlen == INT_MAX ? "" : s.substr(start, minlen);
}

};