[LeetCode]2020/11/10

[LeetCode]2020/11/10

LeetCode 209

题目描述

这是一道中等题,寻找长度最小且和为s的子数组

在这里插入图片描述

时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)的解法

可以使用双指针,记录子数组开始处下标start和结尾处下标end。

public int minSubArrayLen(int s, int[] nums) {
    int N = nums.length;
    int start = 0, end = 0;
    int ans = Integer.MAX_VALUE;
    int sum = 0;
    
    while(end < N){
        sum += nums[end];
        while(sum >= s){
            ans = Math.min(ans, end-start+1);
            sum -= nums[start];
            start++;
        }
        end++;
    }
    return ans == Integer.MAX_VALUE?0:ans;
}

时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),空间复杂度为 O ( n ) O(n) O(n)的解法

这个解法开辟了新空间来存储每一个位置的前缀和,形成一个递增的数组。对数组的每一个元素查找从其开始相加和大于s的最短长度。查找利用二分查找法,时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

Java解题技巧

API

  • public static int binarySearch(Object[] a, Object key)
    // 如果数组中存在要查找对象,返回其所在下标
    // 如果不存在则,计算当元素插入到数组的下标index,返回-(index+1)
    
public int minSubArrayLen(int s, int[] nums) {
    int N = nums.length();
    int [] sums = new int[N+1];
    int ans = Integer.MAX_VALUE;
    // 建立前缀和数组
    for (int i = 1; i < N; i++){
        sums[i] = sums[i-1] + nums[i-1];
    }
    
    for (int i = 1; i <= N; i++){
        // 这里target的目的是,看从i开始到和大于s的数的bound在哪
        int target = s + sums[i-1];
        int bound = Arrays.binarySearch(sums, target);
        if (bound < 0)
            bound = -bound-1;
        if (bound <= n){
            ans = Math.min(ans, bound-i+1);
        }
    }
    return ans == Integer.MAX_VALUE? 0:ans;
}
Python解题技巧

API

  • bisect.bisect_left(a, x, lo=0, hi=len(a))

LeetCode 438

题目描述

这是一道中等题,找到字符串中所有字母异位词(anagrams)。

在这里插入图片描述

解题思路

这道题的一个解题思路是采用双指针的滑动窗口法。技巧是创建一个记录字符出现的数组。

public List<Integer> findAnagrams(String s, String p) {
    int slen = s.length();
    int plen = p.length();
    
    List<Integer> res = new ArrayList<>();
    int [] need = new int[26];
    // 初始化need数组
    for (int i = 0; i < plen; i++){
        need[p.charAt(i)-'a'] += 1;
    }
    
    // 统计数组
    int [] tmpneed = new int[26];
    int l = 0, r = 0;
    while( r < slen){
        int curR = s.charAt(r)-'a';
        tmpneed[curR]++;
        r++;
        while(tmpneed[curR] > need[curR]){
            tmpneed[s.charAt(l) - 'a']--;
            l++;
        }
        if (r-l == plen)
            res.add(l);
    }
    return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值