算法必刷系列之查找、排序

文章目录

  • 二分查找
    • 顺序查找
    • 二分查找迭代写法
    • 二分查找递归写法
    • 元素中有重复元素的二分查找
    • 在排序数组中查找元素的第一个和最后一个位置
    • 山脉数组的峰顶索引
    • 旋转数字的最小数字
    • 找缺失数字
    • 优化求平方根
    • 二叉搜索树中搜索指定值
    • 验证二叉搜索树
    • 有序数组转化为二叉搜索树
  • 快速排序
    • 以第一个元素为基准实现快速排序
    • 以最后一个元素为基准实现快速排序
    • 以中间元素为基准实现快速排序
  • 归并排序
    • 归并排序

二分查找

顺序查找

逐个遍历,判断是否是待查找的元素

public int search(int[] array,int key){for(int i=0;i<array.length;i++){if(array[i]==key){return i;}}return -1;
}

二分查找迭代写法

有序数组可用,可作为模板记忆,注意边界

public int binarySearch(int[] array,int key,int low,int high){while (low<= high){int mid = low+((high-low)>>1);if(array[mid]==key){return mid;}else if(array[mid]>key){high = mid - 1;}else if(array[mid]<key){low = mid + 1;}}return -1;
}

二分查找递归写法

有序数组可用,可作为模板记忆,注意边界

public int binarySearch(int[] array,int key,int low,int high){if(low<=high){int mid = low+((high-low)>>1);if(array[mid]==key){return mid;}else if(array[mid]>key){return binarySearch(array,key,low,mid-1);}else if(array[mid]<key){return binarySearch(array,key,mid+1,high);}}return -1;
}

元素中有重复元素的二分查找

基于模板找到元素后,继续向前遍历,找到等于待查找元素在数组中首次出现的位置,如果元素过多,也可使用二分查找方式继续查找

public int binarySearchRe(int[] array, int key, int low, int high) {while (low <= high) {int mid = low + ((high - low) >> 1);if (array[mid] == key) {while (mid >= 0 && array[mid] == key) {mid--;}return mid + 1;} else if (array[mid] > key) {high = mid - 1;} else if (array[mid] < key) {low = mid + 1;}}return -1;
}

在排序数组中查找元素的第一个和最后一个位置

基于模板找到元素后,继续向前、后遍历,找到等于待查找元素在数组中首次出现的位置和最后出现的位置,如果元素过多,也可使用二分查找方式继续查找

public int[] searchRange(int[] nums, int target) {return binarySearch(nums,target,0,nums.length-1);
}public int[] binarySearch(int[] nums,int target,int low,int high){int[] res = new int[]{-1,-1};while(low<=high){int mid = low + ((high-low)>>1);if(nums[mid]==target){int left = mid;while(left>=0&&nums[left]==target){left--;}int right = mid;while(right<nums.length&&nums[right]==target){right++;}res[0] = left+1;res[1] = right-1;return res;}else if(nums[mid]>target){high = mid-1;}else if(nums[mid]<target){low = mid+1;}}return res;
}

山脉数组的峰顶索引

注意山脉的判断条件,高于两侧数据,递增顺序在左侧,递减顺序在右侧

public int peakIndexInMountainArray(int[] arr) {int high = arr.length-2;int low = 1;while(low <= high){int mid = low+((high-low)>>1);if(arr[mid]>arr[mid-1] && arr[mid]>arr[mid+1]){return mid;}else if(arr[mid]>arr[mid-1] && arr[mid]<arr[mid+1]){low = mid+1;}else if(arr[mid]<arr[mid-1] && arr[mid]>arr[mid+1]){high = mid - 1;}}return -1;
}

旋转数字的最小数字

使用二分查找模板,边界值通过测试样例确定

public int findMin(int[] nums) {int low = 0;int high = nums.length - 1;while(low<high){int mid = low+((high-low)>>1);if(nums[mid]>nums[high]){low = mid+1;}else if(nums[mid]<nums[high]){high = mid;}}return nums[low];
}

找缺失数字

使用二分查找模板,边界值通过测试样例确定

public int missingNumber(int[] array){int high = array.length;int low = 0;while (low<=high){int mid = low + ((high - low)>>1);if(array[mid] == mid){low = mid+1;}else{high = mid - 1;}}return low;
}

优化求平方根

使用二分查找模板,边界值通过测试样例确定

public int mySqrt(int x) {int low = 1;int high = x;while(low <= high){int num = low + ((high-low)>>1);if(x/num == num){return num;}else if(x/num>num){low = num + 1;}else{high = num - 1;}}return high;
}

二叉搜索树中搜索指定值

二分查找与二叉树的结合,先判断根节点,根据根节点与待查找值的情况判断在左子树或者右子树查找

public TreeNode searchBST(TreeNode root, int val) {if(root==null){return null;}else if(root.val == val){return root;}else if(root.val<val){return searchBST(root.right,val);}else if(root.val>val){return searchBST(root.left,val);}return null;
}

验证二叉搜索树

限定low和high两个范围进行验证,验证左右子树时,根据根节点的值更新low和high

public boolean isValidBST(TreeNode root) {long low = Long.MIN_VALUE;long high = Long.MAX_VALUE;return isValidBST(root,low,high);
}public boolean isValidBST(TreeNode root,long low,long high){if(root==null){return true;}if(root.val<=low || root.val >=high){return false;}return isValidBST(root.left,low,root.val)&&isValidBST(root.right,root.val,high);
}

有序数组转化为二叉搜索树

每次选择中间值作为根节点,再通过左右两个序列创建左右子树

public TreeNode sortedArrayToBST(int[] nums) {return sortedArrayToBST(nums,0,nums.length-1);
}public TreeNode sortedArrayToBST(int[] nums,int left,int right){if(left>right){return null;}int mid = left+((right-left)>>1);TreeNode root = new TreeNode(nums[mid]);root.left = sortedArrayToBST(nums,left,mid-1);root.right = sortedArrayToBST(nums,mid+1,right);return root;
}

快速排序

以第一个元素为基准实现快速排序

快速排序模板1

public void quickSort(int[] array, int left, int right) {if(left<right){int pivot = array[left];int i = right + 1;for (int j = right; j > left; j++) {if (array[j] > pivot) {i--;int temp = array[j];array[j] = array[i];array[i] = temp;}}int pivotIndex = i - 1;int temp = array[left];array[left] = array[pivotIndex];array[pivotIndex] = temp;quickSort(array,left,pivotIndex-1);quickSort(array,pivotIndex+1,right);}
}

以最后一个元素为基准实现快速排序

快速排序模板2

public void quickSort(int[] array, int left, int right) {if (left < right) {int pivot = array[right];int i = left - 1;for (int j = left; j < right; j++) {if (array[j] < pivot) {i++;int temp = array[i];array[i] = array[j];array[j] = temp;}}int pivotIndex = i + 1;int temp = array[pivotIndex];array[pivotIndex] = array[right];array[right] = temp;quickSort(array, left, pivotIndex - 1);quickSort(array, pivotIndex + 1, right);}
}

以中间元素为基准实现快速排序

快速排序模板3

public static void quickSort(int[] array, int start, int end) {if (start >= end) {return;}int left = start;int right = end;int mid = (left + right) / 2;int pivot = array[mid];while (left <= right) {while (left <= right && array[left] < pivot) {left++;}while (left <= right && array[right] > pivot) {right--;}if (left <= right) {int temp = array[left];array[left] = array[right];array[right] = temp;left++;right--;}}quickSort(array, start, right);quickSort(array, left, end);
}

归并排序

归并排序

归并排序模板

public void mergeSort(int[] array, int start, int end, int[] temp) {//2.直至每个序列只包含一个元素,停止划分if (start >= end) {return;}//1.从中间开始,每次划分为两个序列mergeSort(array, start, (start + end) / 2, temp);mergeSort(array, (start + end) / 2 + 1, end, temp);//3。进行有序数组的合并merge(array, start, end, temp);
}public void merge(int[] array, int start, int end, int[] temp) {//找到序列中点int mid = (start + end) / 2;//left遍历左边的序列int left = start;//right遍历右边的序列int right = mid + 1;//index遍历临时数组,存储合并结果int index = 0;//两个序列均从起点到终点进行遍历while (left <= mid && right <= end) {//将两个序列中较小的元素放入临时数组中if (array[left] < array[right]) {temp[index++] =array[left++];}else {temp[index++] =array[right++];}}//此时仅剩一个序列未遍历结束,直接赋值while (left <= mid){temp[index++] =array[left++];}while (right<=end){temp[index++] =array[right++];}//将归并的结果拷贝到原数组for (int i=start;i<=end;i++){array[i] = temp[i];}
}

数组中第K大的数的问题可以通过数组排序解决,根据题目中给定的时间、空间复杂福选择合适的排序算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/110732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue el-dialog封装成子组件(组件化)

前言 实际开发过程中我们经常听见组件化开发&#xff0c;但在实际开发过程中&#xff08;没有人审查时&#xff09;怎么方便来 我们有时是因为时间不够&#xff0c;所以把所有代码写在一个页面。当业务逻辑复杂时可能会有1k多行 虽然不能要求自己写出高效复用性高的组件&…

今日最新版早安问候大全,秋天早上好祝福短句,生活顺心,一切开心

天上最美的是星星&#xff0c;关心朋友的是短信&#xff0c;人间最美的是真情&#xff0c;外表留给人的是印象&#xff0c;内心留给人的是感情&#xff0c;珍惜了今天你就拥有了明天&#xff0c;愿你开怀地笑&#xff0c;温柔地睡&#xff01;早安朋友&#xff01; 早晨的阳光…

Leetcode——数组的旋转

189. 轮转数组 class Solution { public:void rotate(vector<int>& nums, int k) {int lennums.size();vector<int> num(len);for(int i0;i<len;i){num[(ik)%len]nums[i];}nums.assign(num.begin(),num.end());} };旋转数组 没看出数学公式gg 正确答案 cl…

JNI查漏补缺(2)JNI动态注册

目录 一、JNI动态注册是什么&#xff1f; 二、JNI动态注册使用步骤 1.新增gMethods数组和JNI_OnLoad函数 2.完整HelloWorld.cpp 3.运行测试 总结 一、JNI动态注册是什么&#xff1f; 静态注册的情况下&#xff0c;java调用的接口和jni层实现的接口有强制的一一对应关系&a…

AI大模型高速发展,Web3还远吗?

在过去的几年里&#xff0c;人工智能&#xff08;AI&#xff09;和Web3技术都经历了令人瞩目的发展。AI大模型&#xff0c;特别是像GPT-3、GPT-4等这样的巨型语言模型&#xff0c;已经成为AI领域的明星&#xff0c;而Web3则代表了下一代互联网的愿景&#xff0c;具有去中心化和…

最近邻插值的原理及实现

1. 介绍 插值算法一般用来做上采样和下采样,最邻近插值算法,是插值算法中最简单的一种。 最邻近插值:将每个目标像素找到距离它最近的原图像素点,然后将该像素的值直接赋值给目标像素。 优点: 实现简单,计算速度快 缺点:插值结果缺乏连续性,可能会产生锯齿状的边缘,对…

scratch时间游戏 2023年9月中国电子学会图形化编程 少儿编程 scratch编程等级考试三级真题和答案解析

目录 scratch时间游戏 一、题目要求 1、准备工作 2、功能实现 二、案例分析

Cocos Creator3.8 项目实战(十)使用 protobuf详细教程

在 Cocos Creator 中使用 protobuf.js 库可以方便地进行协议的序列化和反序列化。 下面是使用 protobuf.js 的详细说明&#xff1a; 一、protobuf环境安装 1、安装 npm protobuf环境安装安装需要使用 npm 命令进行&#xff0c;因此首先需要安装 npm 。 如果你还没安装 npm …

【面试题】2023虹软计算机视觉一面

来源&#xff1a;投稿 作者&#xff1a;LSC 编辑&#xff1a;学姐 1.自我介绍 2.介绍了自己的项目&#xff0c;并提问项目&#xff0c;讲了30分钟 3.介绍centernet&#xff0c;它和其他目标检测模型有什么区别 4.介绍yolov5 5.介绍focal loss 6.双线性插值和最近邻插值的区…

微信一键群发超过200人的方法

在当前社交媒体的大潮中&#xff0c;微信已跻身全球最热门的社交平台之列。对于企业的运营管理来说&#xff0c;微信的管理系统工具发挥着举足轻重的作用。然而&#xff0c;微信自带的群发助手功能最多只能发送消息给200个好友&#xff0c;要是需要发送1000个好友甚至更多&…

《论文阅读28》OGMM

一、论文 研究领域&#xff1a; 点云配准 | 有监督 部分重叠论文&#xff1a;Overlap-guided Gaussian Mixture Models for Point Cloud Registration WACV 2023 二、概述 概率3D点云配准方法在克服噪声、异常值和密度变化方面表现出有竞争力的性能。本文将点云对的配准问题…

10款远程办公软件,助你事半功倍,晋升快如闪电

选择一个易于使用和方便的远程软件&#xff0c;可以提高团队的整体效率&#xff0c;减少加班&#xff0c;使整个团队更受益。互联网行业从产品经理、UI/从UX设计师到技术开发和测试人员&#xff0c;每一个环节都需要密切沟通和跟踪&#xff0c;在远程沟通中及时发现问题&#x…

power point导出pdf保留字体

在 slides 中用到非自带的字体&#xff0c;如 [1]&#xff0c;想导出成 pdf 文件&#xff08;因为导出成图&#xff0c;如 png&#xff0c;放大会蒙&#xff09;&#xff0c;并在别人电脑里也保留字体。除了让别人也装上相应字体&#xff0c;可以&#xff1a; 参考 [2]&#x…

阿里云/腾讯云国际站账号:私服游戏服务器:阿里云CTO周靖人:AI时代,为什么阿里云一定要做开源

开源技术报告&#xff0c;阿里云私服游戏服务器怎么看待大模型的路径&#xff1f; 随着 Meta 的 Llama2 开源&#xff0c;开源模型&#xff0c;以及聚集大模型开发者的开源社区&#xff0c;正在发挥不可或缺的作用。 一个例子是&#xff0c;上个月 Hugging Face 得到了谷歌、…

“岗课赛证”融通的物联网综合实训室建设方案

一、概述 随着5G技术的普及应用和产业经济的革新发展,物联网产业所呈现的广阔前景带来了对创新型技术技能人才的迫切需求。高职院校物联网专业建设也因此转变为面向国家战略性新兴产业发展需求。当前,“岗位课程竞赛证书”融通的培育理念,是高职院校物联网人才培养和专业优化的…

Anomalib 图像异常检测算法

图像异常检测算法 1.简介1.1. 问题描述1.2. 挑战与需求 2. 图像异常检测定义2.1 异常的定义及类型2.2 图像数据中的异常 3. 图像异常检测技术研究现状4.方法5.安装和使用5.1 安装PyPI 安装本地安装 5.2 训练5.3 特征提取与&#xff08;预训练&#xff09;backones5.4 自定义数据…

大中小企业自招人力及劳务派遣全行业招聘来抖音招聘流量大效果佳

抖音直播招聘报白是通过抖音直播方式展现职位信息&#xff0c;并与求职者进行互动的招聘方式。在抖音平台上&#xff0c;企业或者人力资源公司可以通过直播的形式&#xff0c;将职位以视频直播的方式展现出来。通过抖音直播招聘报白&#xff0c;企业或者人力资源公司可以利用抖…

vue2技能树(4)-插值、动态参数、指令修饰符、计算属性、侦听器

目录 Vue 2插值详解文本插值原始HTML表达式过滤器计算属性数据绑定 Vue 2指令的动态参数、修饰符和缩写动态参数修饰符v-on 修饰符v-bind 修饰符v-model 修饰符 缩写 Vue 2 计算属性和侦听器详解计算属性 (Computed Properties)侦听器 (Watchers) &#x1f44d; 点赞&#xff0…

layui时间编写

1.时间选择器 //日期时间选择器laydate.render({elem: #startTime,type: datetime});WmsPreparationTask.search function () {var queryData {};queryData[startTime] $("#beginTime").val();table.reload(WmsPreparationTask.tableId, {where: queryData, page:…

文本识别工具 TextSniper for Mac有哪些特点

TextSniper 是一款 macOS 平台上的文本提取工具&#xff0c;它可以将屏幕上的文字内容快速转换为可编辑的文本。无论是从图像、视频、PDF 文件还是其他类型的文档中提取文字&#xff0c;TextSniper 都提供了便捷的功能。 以下是 TextSniper的一些主要特点和功能&#xff1a; …