首页 > 其他分享 >LeetCode刷题笔记

LeetCode刷题笔记

时间:2023-09-10 13:44:47浏览次数:47  
标签:right int mid 笔记 力扣 刷题 LeetCode left

算法

1.差分数组+前缀和

1589. 所有排列中的最大和 - 力扣(LeetCode)

对于每一次遍历都有m个数需要加1,如果对这些数遍历,则需要O(m)复杂度,此时可以记录这m个数的差分数组:

image-20230711150301362

这样就可以把时间复杂度缩小到O(1),之后求前缀和就可以得到原来的数组。

2.线性筛(欧拉筛)求素数

2601. 质数减法运算 - 力扣(LeetCode)

public int[] findPrime(int max){
    boolean[] isNotPrime = new boolean[max];//数的范围
    int[] primes = new int[n];//质数大小
    int cnt = 0;
    for( int i = 2; i < max; i++){
        if(!isNotPrime[i]) primes[cnt++] = i;
        for(int j = 0;j < cnt && primes[j] * i < max;j++){
            isNotPrime[primes[j] * i] = true;
            if(i % primes[j] == 0) break;
        }
    }
    return primes;
}

3.二分查找

二分法的 5 种经典应用 - 力扣(LeetCode)

求边界

2563. 统计公平数对的数目 - 力扣(LeetCode)

技巧:

求一个数在区间[left,right]时,可以转化为:(<=right) - (<= left - 1)

求两个数之和在区间[left,right]时,可以转化为:

​ 遍历其中一个数num1,求(<=right - num1) - (<= left - num1 - 1)

//普通的二分查找 left = -1; right = length; 开区间
public int binarySort(int[] nums, int left, int right, int value){
    while(left + 1 < right) {
        int mid = (left + right) >>> 1;
        if(value < nums[mid]){
            right = mid;
        } else if (value == nums[mid]) {
            return mid;
        } else{
            left = mid;
        }
    }
    return -1;
}	

//通用模板>= 
//left = -1; right = length; 开区间
public int binarySearch(int[] nums, int left, int right, int value){
    while(left + 1 < right) {
        int mid = (left + right) >>> 1;
        if(value <= nums[mid]){
            right = mid;
        }  else{
            left = mid;
        }
    }
    return right;
}
//求>: binarySort(nums,left,right,value + 1);
//求<: binarySort(nums,left,right,value) - 1;
//求<=: binarySort(nums,left,right,value + 1) - 1;

最大化最小值/最小化最大值

2517. 礼盒的最大甜蜜度 - 力扣(LeetCode)

2439. 最小化数组中的最大值 - 力扣(LeetCode)

第k大/第k小

668. 乘法表中第k小的数 - 力扣(LeetCode)

以上两种的思路:

利用二分查找符合条件的数,根据是否满足题意来收缩数的范围!

878. 第 N 个神奇数字 - 力扣(Leetcode)

image-20230714154814416

题解:

根据容斥原理,给定一个能被a或b整除的数num:

n = num/a + num/b - num/(a和b的最小公倍数)

所以该题目可以利用二分查找,通过容斥原理计算对应第几个神奇数字,如果该数大于预期的n,则缩小数的范围继续进行二分查找。

class Solution {
    public int nthMagicalNumber(int n, int a, int b) {
        long left = Math.min(a,b);
        long right = (long)n * Math.min(a,b);

        while(left + 1 < right){
            long mid = (left + right) >>> 1;
            long cnt = mid / a + mid / b - mid * greatestCommonDivisor(a,b)/(a * b);
            if(cnt >= n){
                right = mid;//缩小数的范围
            }else{
                left = mid;
            }
        }
        return (int)(right % 1000000007L);
    }
    private int greatestCommonDivisor(int a, int b){//最小公倍数
        int r = Math.max(a,b);
        int l = Math.min(a,b);
        while(l != 0){
            int temp = l;
            l = r % l;
            r = temp;
        }
        return r;
    }
}

4.双指针

快慢指针

相向指针

11. 盛最多水的容器 - 力扣(Leetcode)

image-20230714153539673

题解:

利用双指针从数组两侧向中间靠拢,根据两端线的长度进行收缩,以left > right为例,有两种情况:

①如果移动left指针,容量可能会变小(移动后的left < right)或者不变(移动后的left >=right);

②如果移动right指针,容量可能会变大(移动后的right > 原来的right)、变小(移动后的right < 原来的right)或者不变(移动后的right不变);

所以要想求得最优解,可以通过移动线的长度较小的那一段,求所有面积的最大值即可。

class Solution {
    public int maxArea(int[] height) {
        int left = 0;
        int right = height.length - 1;
        int maxArea = -1;
        while(left < right){
            int area = (right - left) * Math.min(height[left], height[right]);
            maxArea = Math.max(maxArea,area);
            if(height[left] < height[right]){//缩小线段长度比较小的那一段
                left++;
            }else{
                right--;
            }
        }
        return maxArea;
    }
}

滑动窗口

1004. 最大连续1的个数 III - 力扣(Leetcode)

image-20230717134342540

题解

标签:right,int,mid,笔记,力扣,刷题,LeetCode,left
From: https://www.cnblogs.com/wuzhimao/p/17691089.html

相关文章

  • 学习linux系统中的一些笔记(持续更新)
    快捷键: CTRL+ALT+T 打开终端 CTRL+SHIFT+T 新建标签页 ALT+数字N 终端中切换到第N个标签页 TAB 终端中命令补全,输入开头补全 上下键盘 切换命令历史 CTRL+C 中断程序运行Linux命令 命令格式:command[option][arguments](选项和参数) 其中选项(option)是......
  • 二分笔记
    二分优点,加快在有序数列中,蓝红区域的扩展,朴素算法缓慢进行.如何扩展,用灰色区域的中点来判断,然后扩展颜色区域,灰色区域会不断减少,只要logn次就能把灰色区域长度缩小为0  l在哪里,哪里就是蓝色,r同理,假设没有蓝色区域,赋值0(保留了一个位置)会导致,扩展过程中,红色......
  • CMU15721 笔记:Project 1 - Foreign Data Wrapper
    CMU15-721Project1-ForeignDataWrapperPre2003年,SQL标准中增加了一个访问远程数据的规范,称为外部数据的SQL管理(SQL/MED)。从9.1版开始,PostgreSQL就开始开发这个特性来实现SQL/MED的一部分。在SQL/MED中,远程服务器上的表称为外部表。PostgreSQL的外部数据包裹......
  • 第一、二章学习笔记
    Unix/Linux系统编程学习笔记第一章、第二章知识点归纳以及最有收获的内容一.进程与线程Unix/Linux系统中,进程是程序的执行实例,而线程是进程内的执行单元。进程之间通常是独立的,而线程共享进程的资源。最大的收获是理解了进程与线程之间的区别,以及它们如何协同工作。进程(Proc......
  • 《阿里大数据之路》读书笔记:第三章 数据同步
    第三章数据同步数据同步技术含义:不同系统间的数据流转,有多种不同的应用场景。应用场景:同类型不同集群数据库之间的数据同步主数据库与备份数据库之间的数据备份主系统与子系统之间的数据更新不同地域、不同数据库类型之间的数据传输交换大数据系统中的数据同步数据从业务系统同步......
  • 学习笔记-计算机病毒对抗技术-高级反病毒
    虚拟机技术1、虚拟CPU2、虚拟进程环境3、虚拟执行进程代码虚拟机在反病毒领域中的应用1、处理变形病毒2、基于虚拟机技术的行为判定病毒与虚拟机的对抗云查杀技术启发式扫描技术1、动态启发式2.静态启发式主动防御技术1、获得SSDT表2、在SSDT表中定位要替换的函数地址的位置3、使用......
  • Python学习笔记-Python判断语句
    布尔类型和比较运算符布尔类型进行判断,只有2个结果:是否程序中,如何描述:是或否?使用:布尔类型。Python中常用的6种值(数据)的类型类型描述说明数字(Number)支持整数(int)浮点数(float)复数(complex)布尔(bool)整数(int),如10、-10浮点数(float),如13.14、-13.14复数(complex),如4+3j,以j结尾表示复数布尔(bool)......
  • #yyds干货盘点# LeetCode程序员面试金典:用栈实现队列
    题目:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实现 MyQueue 类:voidpush(intx) 将元素x推到队列的末尾intpop() 从队列的开头移除并返回元素intpeek() 返回队列开头的元素booleanempty() 如果队列为空,返回 true ......
  • #yyds干货盘点# LeetCode程序员面试金典:等差数列划分
    1.简述:如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。例如,[1,3,5,7,9]、[7,7,7,7] 和 [3,-1,-5,-9] 都是等差数列。给你一个整数数组 nums ,返回数组 nums 中所有为等差数组的 子数组 个数。子数组 是数组中的一个连续序列。 示例1......
  • 离散数学笔记——集合
    离散数学笔记——集合集合的概念集合是由一些确定的元素所组成的整体,其中的元素可以是任何事物定义:A={a1,a2,a3,...,an}表示集合的名称,{}表示集合的符号。a1,a2,a3,...an表示集合中的元素x∈A表示元素x属于集合A集合的特点集合没有重复元素集合......