首页 > 编程语言 >算法基础_1

算法基础_1

时间:2024-01-22 20:44:24浏览次数:34  
标签:scanner nums int 基础 mid 算法 new public

title:(算法基础课) link:(https://www.acwing.com/) cover:(https://cdn.acwing.com/media/activity/surface/log.png)

  • 上课理解思路 -> 下课理解背过代码模板 -> 做3-5遍题目(循环AC)

排序

快速排序

快速排序模板题例题

分治:用一个数来分,不需要必须是中心数
先分完再递归两边

image


import java.util.*;

public class Main{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(); // 数组中元素的个数
		int[] nums = new int[n]; // 定义数组大小
		for(int i=0;i<n;i++){
			nums[i] = sc.nextInt(); // 获取数组元素
		}
		int[] res = quickSort(0,n-1,nums); // 进行快排并把结果保存在res数组中
		for(int i=0;i<n;i++){
			System.out.print(res[i] + " "); // 输出排序后的结果
		}
	}
	public static int[] quickSort(int l,int r,int[] nums){
		// 边界结束条件
		// 写成l==r也是可以的
		if(l>=r){
			return nums;
		}
		int p = nums[(l+r)/2]; // 1. 确定分界点,不能取到nums[r]因为下面划分区间使用的j
		int i = l-1;
		int j = r+1;
		// 2. 调整范围
		while(i<j){
			while(nums[++i]<p); // 从左往右找比p大的数
			while(nums[--j]>p); // 从右往左找比p小的数
			// 此时如果i<j,那么说明找到了满足要求的一组数,交换数组中i,j两个位置的值
			if(i<j){
				int temp = nums[i];
				nums[i] = nums[j];
				nums[j] = temp;
			}
		}
		// 3. 递归处理左右两段[l,j]与[j+1,r],上述while结束后i>=j
		// 分治法
		quickSort(l,j,nums);
		quickSort(j+1,r,nums);
		return nums;
	}
}

第k个数

image




归并排序

归并排序模板题例题

分治:以整个数组的中心点来分
先递归两边再归并
双指针算法,逐个找最小的,存到res数组中
每层都是On,logn分层,总计nlogn

image


import java.util.*;

public class Main {
	public static void main (String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt(); // 数组中元素的个数
		int[] nums = new int[n]; // 定义数组大小
		for (int i = 0; i < n; i++) {
			nums[i] = scanner.nextInt(); // 获取数组中的元素
		}
		merge_sort(0,n-1,nums); // 进行归并排序
		for (int i = 0; i < n; i++) {
			System.out.print(nums[i] + " ");
		}
	}

	public static void merge_sort (int l,int r,int[] nums) {
		if (l>=r) {
			return;
		}
		int mid = (l+r) >> 1;
		int i = l,j = mid + 1; // 两个指针指向两段的首元素
		merge_sort(l,mid,nums); // 左区间[l,mid]
		merge_sort(mid+1,r,nums); // 右区间[mid+1,r]

		int[] temp = new int[r - l + 1]; // 临时数组中存储归并后的数据
		int k = 0; // 临时数组的指针,用来存储已经排序好的下标位置
		while (i <= mid && j <= r) {
			if (nums[i] <= nums[j]) {
				// temp[k] = nums[i]; // 把较小的数存储到临时数组中
				// k++; // 临时数组指针移动
				// i++; // 数组指针移动
				temp[k++] = nums[i++];
			} else {
				temp[k++] = nums[j++];
			}
		}
		// 此时说明i中仍有剩余元素,即j已经走完全路程
		while (i <= mid) {
			temp[k++] = nums[i++]; // 将剩余元素存储到临时数组中
		}
		// 此时说明j中仍有剩余元素,即i已经走完全路程
		while (j <= r) {
			temp[k++] = nums[j++]; // 将剩余元素存储到临时数组中
		}
		// 临时数组归位
		for (int q = l,p = 0; q <= r; q++) {
			nums[q] = temp[p++];
		}
	}
}

逆序对的数量

image




二分法

有单调性可以进行二分,没有也可以

image

整数二分法

  • 第一个大于等于x的数 || 最后一个大于等于x的数

    • l=mid,需要补一个1
      假设此时l=r-1,那么mid=(l+r)/2=l,在刚好true的时候,l=mid=l,[l,r]没变,则死循环。
      如果补1,那么mid=(l+r+1)/2=r,l=mid=r,则刚好结束。
    • r=mid,不需要补一个1
  • 整体逻辑

    • 先正常写,每次写一个mid,写一个check函数,想一下答案怎么划分,如果l=mid,则需要+1
    • check函数:需要选择答案所在的区间,要保证这个区间内部一定有答案

image

  • 起始位置
    image

  • 终结位置
    image


import java.util.*;

public class Main {
	public static void main (String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		int m = scanner.nextInt();
		int[] nums = new int[n];
		for (int i = 0; i < n; i++) {
			nums[i] = scanner.nextInt();
		}

		for (int i = 0; i < m; i++) {
			int x = scanner.nextInt();
			// 首先需要找第一个和它相同的数作为起始位置p
			int p = 0,q = 0; // 起始位置p(第一次出现),结束位置q(最后一次出现)
			int l = 0,r = n-1;
			while (l < r) {
				int mid = (l+r)>>1;
				// 找的是x的起始位置即>=x,更新成[l,mid]
				// 最前面那个满足>=x的数就是二分的位置
				if (nums[mid] >= x) {
					r = mid; // 不用补上+1了
				} else {
					l = mid+1;
				}
			}
			p = r; // 起始位置(nums[l]==nums[r])
			l = 0;
			r = n-1;
			while (l < r) {
				int mid = (l+r+1)>>1;
				// 找的是x的最终位置即<=x,更新成[mid,r]
				// 最后面那个满足<=x的数就是二分的位置
				if (nums[mid] <= x) {
					l = mid; // 需要补上+1
				} else {
					r = mid-1;
				}
			}
			q = r; // 最终位置
			if (nums[q] != x) {
				System.out.println(-1 + " " + -1);
			} else {
				System.out.println(p + " " + q);
			}
		}
	}
}

浮点数二分法

image


import java.util.*;

public class Main {
	public static void main (String[] args) {
		Scanner scanner = new Scanner(System.in);
		double n = scanner.nextDouble();
		// double l = (double)-1e5;
		double l = 0;
		// double r = 1e5*1.0;
		double r = n;
		// 当浮点数区间的长度已经很小的时候就已经可以算作答案了
		// 浮点数也没有边界的问题
		while (r - l > 1e-8) {
			double mid = (l+r)/2;
			if (mid * mid * mid >= n) {
				r = mid;
			} else {
				l = mid;
			}
		}
		System.out.printf("%.6f",l); // 6位小数就写1e-8,4位就写1e-6
	}
}

高精度

高精度加法

image



高精度减法

image



高精度乘法

image



高精度除法

image



前缀和与差分

前缀和

image



image

差分

image



image

双指针算法

image

image

image

位运算

image

离散化

image

区间合并

image

标签:scanner,nums,int,基础,mid,算法,new,public
From: https://www.cnblogs.com/jia-ming/p/17981036

相关文章

  • Johnson 全源最短路算法
    ​ Johnson全源最短路是一种允许带负权边的全源最短路算法。它的主要实现思路即为将原先带负权边的图转化成求一个无负权边的图的全源最短路。​ 我们定义一个新节点\(0\),其中\(0\)节点与其它各节点连接一条边权为\(0\)的边。令\(h_i\)为\(0\)节点到\(i\)节点的最短......
  • STL-算法
    STL-算法目录STL-算法查找统计算法统计查找二分查找排序和通用算法排序随机合并反转复制替换删除算法复制替换删除唯一互换生成和异变算法数值算法关系集合算法交并集实践操作Vector中去重参考资料STL的三大组件:容器(container)算法(algorithm)迭代器(iterator)。STL算法部分......
  • Julia编程基础
    技术背景Julia目前来说算是一个比较冷门的编程语言,主要是因为它所针对的应用场景实在是比较有限,Julia更注重于科学计算领域的应用。而Julia最大的特点,就是官方所宣传的:拥有C的性能,且可以像Python一样便捷的开发。这对于科学计算领域来说确实是一件好事,目前也有一些科学领域的应用......
  • NumPy数据处理基础
    Panadas数据处理基础一、数据结构NumPy中主要有多维数组和矩阵结构。1.1、利用array()函数创建数组numpy.array(object,dtype=None,*,copy=True,order='K',subok=False,ndmin=0,like=None)----object参数来创建数组类型的对象----dtype参数表示数组元素的类型----copy用......
  • 基于项目的协同过滤推荐算法(Item-Based Collaborative Filtering Recommendation Alg
    前言协同过滤推荐系统,包括基于用户的、基于项目的息肉通过率等,今天我们读一篇基于项目的协同过滤算法的论文。今天读的论文为一篇名叫《基于项目的协同过滤推荐算法》(Item-BasedCollaborativeFilteringRecommendationAlgorithms)。摘要Recommendersystemsapplyknowledg......
  • 测试开发技术:Python测试框架Pytest的基础入门
    测试开发技术:Python测试框架Pytest的基础入门  Pytest简介Pytestisamaturefull-featuredPythontestingtoolthathelpsyouwritebetterprograms.Thepytestframeworkmakesiteasytowritesmalltests,yetscalestosupportcomplexfunctionaltesting......
  • 优化Elastic Load Balancing负载均衡算法的实战指南
    在AWS中,ElasticLoadBalancing(ELB)服务是实现负载均衡的关键组件,而TargetGroups则用于管理和路由传入的流量。本篇博文将深入介绍如何通过Boto3(AWSSDKforPython)和ELBv2API来优化TargetGroup的负载均衡算法,以提高系统性能。我们将实现将所有符合条件的TargetGroup的负载均衡......
  • 国产的AI基础设施与国外的差距?仅以grpc与prpc做比较
    搞AI,基础设施包括软件、硬件以及相关生态,多方面,这里只片面的取一个例子来说明国内外在AI基础设施上的区别,注意,这里只是片面截取。高性能的rpc框架是搞AI的一个基础依赖软件,当然,国外也有与之可以替代的mpi框架,不过这两个都是老美的。对于mpi,老美一直是开源的,国内也没有任何一家企......
  • Linux基础45 firewalld防火墙, 参数, 区域配置, 放行策略, 端口转发, 富规则, 防火墙
    firewalld防火墙一、防火墙安全概述在Centos7系统中继承了多款防火墙管理工具,默认启动的是firewalld(动态防火墙管理器)防火墙管理工具,Firewalld支持CLI(命令行)以及(图形)的两种管理方式。对于接触Linux较早的人员对Iptables比较熟悉,但由于Iptables的规则比较的麻烦,并且对网络有......
  • 软件测试基础知识 - 集成测试和系统测试的区别,以及它们的应用场景
    区别1、测试计划和测试用例编制的先后顺序:从V模型来讲,在需求阶段就要制定系统测试计划和测试用例,概要设计的时候做集成测试计划和测试用例,有些公司的具体实践不一样,但是顺序肯定是先做系统测试计划和测试用例,再做集成测试计划和测试用例。2、测试用例的粒度:系统测试用例相对很接......