代码随想录算法训练营第二天| 977.有序数组的平方 209.长度最小的子数组 904. 水果成篮 76. 最小覆盖子串 59.螺旋矩阵II

977.有序数组的平方

977.有序数组的平方

class Solution {
    public int[] sortedSquares(int[] nums) {
        //分为暴力破解法和双指针法:双指针法思路:创建一个新的数组,旧数组的平方要么在两端,不可能在中间,所以用i指向旧数组头,j指向新数组的尾部
        int i = 0;
        int j = nums.length-1;
        int index = j;
        int[] newarry = new int[j+1];
        while(i <= j){
            if (nums[i] * nums[i] < nums[j] * nums[j]){
                newarry[index] = nums[j] * nums[j];
                j--;
            }
            else{

                newarry[index] = nums[i] * nums[i];
                i++;
            }
            index--;
        }
        return newarry;
    }
}

209.长度最小的子数组

209.长度最小的子数组

//暴力算法  不推荐 O(n^2)
class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int result = INT32_MAX; // 最终的结果
        int sum = 0; // 子序列的数值之和
        int subLength = 0; // 子序列的长度
        for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
            sum = 0;
            for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
                sum += nums[j];
                if (sum >= s) { // 一旦发现子序列和超过了s,更新result
                    subLength = j - i + 1; // 取子序列的长度
                    result = result < subLength ? result : subLength;
                    break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
                }
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == INT32_MAX ? 0 : result;
    }
};

在本题中实现滑动窗口,主要确定如下三点:

  1. 窗口内是什么?
  2. 如何移动窗口的起始位置?
  3. 如何移动窗口的结束位置?
//滑动窗口算法
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //使用滑动窗口解法
        int sum = 0;//滑动窗口内部的数组和
        int i = 0;//滑动窗口起始位置
        int j = 0;//滑动窗口结束位置
        //通过先确定滑动窗口的结束位置,再不断改变滑动窗口的起始位置
        int result = Integer.MAX_VALUE;
        int sublenth = 0;//滑动窗口的宽度
        for(j = 0; j < nums.length; j++){
            sum += nums[j];
            while( sum >= target){
                sublenth = j - i + 1;
                result = result < sublenth ? result : sublenth;
                sum -= nums[i++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 :result;
    }
}

904. 水果成篮

904. 水果成篮
本题使用了Java中的hashmap和滑动窗口的结合,注意hashmap中的get(),put(),getOrDefault() 等方法

class Solution {
    public int totalFruit(int[] fruits) {
        //hashmap + 滑动窗口  hashmap中存储的键值对是(窗口内)果树的种类-果树的棵树
        int left = 0;
        int right = 0;
        int ans = 0;
        Map<Integer,Integer> cnt = new HashMap<Integer,Integer>();
        for (right = 0; right < fruits.length; right++){
            cnt.put(fruits[right],cnt.getOrDefault(fruits[right],0) + 1);
            while(cnt.size() > 2){
                //如果说hashmap中存储了2个以上的键值对,则从Left开始缩小滑动窗口
                //首先将hashmap中以fruits[left]为键的值减1
                cnt.put(fruits[left],cnt.getOrDefault(fruits[left],0)-1);
                if(cnt.get(fruits[left])==0){
                    //如果hashmap中以fruits[left]为键的键值的个数为0,则删除该键值对
                    cnt.remove(fruits[left]);
                }
                left++;
            }
            ans = Math.max(ans, right - left + 1);
        }
        return ans;

    }
}

76. 最小覆盖子串

76. 最小覆盖子串
难度较高

class Solution {
    Map<Character,Integer> ori = new HashMap<Character,Integer>();
     Map<Character,Integer> cnt = new HashMap<Character,Integer>();
    
    public String minWindow(String s, String t) {
        //使用滑动窗口算法,首先将t目标字符串映射到ori中,键值对
        int tLen = t.length();
        for ( int i = 0; i < tLen; i++){
            char c = t.charAt(i);
            ori.put(c,ori.getOrDefault(c,0)+1);
        }
        int l = 0 ,r = -1;
        int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
        int sLen = s.length();
        while(r < sLen){
            ++r;
            if(r < sLen && ori.containsKey(s.charAt(r))){
                cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r),0)+1);
            }
            while(check() && l <= r){
                if(r - l + 1 < len){
                    len = r - l + 1;
                    ansL = l;
                    ansR = l + len; 
                }
                if(ori.containsKey(s.charAt(l))){
                    cnt.put(s.charAt(l),cnt.getOrDefault(s.charAt(l),0) -1);
                }
                l++;
            }
        }
        return ansL == -1 ? ""  :s.substring(ansL,ansR);
    }
    //check()函数的原理还不是很清楚
     public boolean check() {
        Iterator iter = ori.entrySet().iterator(); 
        while (iter.hasNext()) { 
            Map.Entry entry = (Map.Entry) iter.next(); 
            Character key = (Character) entry.getKey(); 
            Integer val = (Integer) entry.getValue(); 
            if (cnt.getOrDefault(key, 0) < val) {
                return false;
            }
        } 
        return true;
    }


}

59.螺旋矩阵II

59.螺旋矩阵II
使用模拟的方法生成螺旋矩阵:left to right, top to bottom, right to left ,bottom to top


class Solution {
    public int[][] generateMatrix(int n) {
        int l = 0, r = n - 1, t = 0, b = n - 1;
        int[][] mat = new int[n][n];
        int num = 1, tar = n * n;
        while(num <= tar){
            for(int i = l; i <= r; i++) mat[t][i] = num++; // left to right.
            t++;
            for(int i = t; i <= b; i++) mat[i][r] = num++; // top to bottom.
            r--;
            for(int i = r; i >= l; i--) mat[b][i] = num++; // right to left.
            b--;
            for(int i = b; i >= t; i--) mat[i][l] = num++; // bottom to top.
            l++;
        }
        return mat;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值