算法笔记(自用)

断断续续刷了不少的leetcode题目了,但是算法一点长进都没有,还是一个小白(简单题重拳出击,中等题唯唯诺诺,困难题看不懂);究其根本原因,就是自己没有好好认真的学习,既缺乏系统性的学习,也没有做记录,刷过了就忘了,同类题型不会做。现将自己刷题学习的过程记录下来,留做以后翻阅,内容比较混乱,自用。

二分查找

二分查找从入门到入睡

二分查找的题目中,看到有序性,可以考虑二分查找
复杂度为 O(logn)
主要是理解边界问题,记录两种常见情况
左闭 left+1,右闭 right-1
[left,right] 判断条件 <=
[left,right) 判断条件 <

相关题目
题目难度
278. 第一个错误的版本简单
374. 猜数字大小简单
34. 在排序数组中查找元素的第一个和最后一个位置中等
658. 找到 K 个最接近的元素中等

求最大公因数(辗转相除法)

求数字a和b的最大公因数

写法一:循环

    public int gcd (int a, int b) {
        while(b > 0){
            int c= a % b;
            a = b;
            b = c;
        }
        return a;
    }

写法二:递归

 public int gcd(int a, int b){
	    if(b == 0) return a;
	    return gcd(b,a % b);
    }

双指针和滑动窗口

通常我们把窗口大小不固定的叫双指针,固定的叫滑动窗口,使用双指针的要求是单调性

同向双指针

题目

长度最小的子数组
这道题第一反应是两层循环,暴力枚举求和,取最小的满足值,复杂度为O(n2),
但是其实在循环中,有很多的求和是不必要的,比如说已经找到一个长度为x的连续子数组满足,其实就没有必要在算那些大于x的连续子数组了,想象一个在缩小的滑动窗口,复杂度为O(n)

以target = 7, nums = [2,3,1,2,4,3] 为例
遍历右端点
l = 0  r = 0  [2]  sum = 2 <7
l = 0  r = 1  [2,3] sum = 5<7
l = 0  r = 2  [2,3,1] sum = 6<7

l = 0  r = 3  [2,3,1,2] sum = 8>7 满足  记录下ans = 4  此时窗口的大小就是4,不用考虑>4的了,此时收缩左边的端点,看是否仍然可以符合 
l = 1  r = 3  [3,1,2]  sum = 6<7  不满足,恢复长度为4的窗口,往右移动一下,

l = 1  r = 4  [3,1,2,4] sum = 10>7 满足   ans = 4 继续收缩
l = 2  r = 4  [1,2,4]  sum = 7=7  满足  ans = 3 继续收缩
l = 3  r = 4  [2,4]  sum=6<7 不满足,恢复长度为3的窗口,往右移动一下,

l = 3  r = 5 [2,4,3]  sum = 9 >7 满足 ans = 3 继续收缩
l = 4  r = 5 [4,3] sum = 7=7 满足  ans = 2 继续收缩
l = 5  r = 5 [3] sum = 3<7

所以最后的结果就是 ans = 2
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int ans = Integer.MAX_VALUE;
        int sum = 0;
        int left = 0;
        for(int right=0;right<nums.length;right++){
            sum += nums[right];
            while(sum>=target){
                ans = Math.min(ans,right-left+1);
                sum -= nums[left];
                left++;
            }
        }
        return ans==Integer.MAX_VALUE?0:ans;
    }
}
其他题目

乘积小于 K 的子数组

无重复字符的最长子串

最大连续 1 的个数

替换子串得到平衡字符串

将 x 减到 0 的最小操作数

埃氏筛

	//求10e6内的质数
    static int n = 1000000;
    static HashSet<Integer> set = new HashSet<>();
    static{
        boolean[] is_prime = new boolean[n+1];
        for(int i=2;i<=n;i++){
            if(!is_prime[i]){
                set.add(i);
            }
            for(int j=i;j<=n/i;j++){   //防止溢出
                is_prime[i*j] = true;  //不是质数
            }
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值