当前位置: 首页 > news >正文

朝阳网站建设是什么佛山做网络优化的公司

朝阳网站建设是什么,佛山做网络优化的公司,网站建设瀑布流,积分商城网站开发二分查找写在开头算法前提:算法逻辑算法实现简单实现leftright可能超过int表示的最大限度代码分析和变换更多需求:求索引最小的值java二分API应用基础题思考难度方法写在开头 二分查找应该是算比较简单的这种算法了,我本以为还可以。但有时候…

二分查找

  • 写在开头
  • 算法前提:
  • 算法逻辑
  • 算法实现
    • 简单实现
    • left+right可能超过int表示的最大限度
    • 代码分析和变换
    • 更多需求:求索引最小的值
    • java二分API
  • 应用
    • 基础题
    • 思考难度
    • 方法

写在开头

二分查找应该是算比较简单的这种算法了,我本以为还可以。但有时候也没想到过能这么用,最震惊的就是对答案进行二分了。而且有时候不够熟练,还有我遇到的问题都总结一下。

算法前提:

数据需要有序,可以重复元素。

算法逻辑

以升序数列为例,
比较一个元素与数列中的中间位置的元素的大小
1.如果比中间位置的元素大,则继续在后半部分的数列中进行二分查找;
2.如果比中间位置的元素小,则在数列的前半部分进行比较;
3.如果相等,则找到了元素的位置。
每次比较的数列长度都会是之前数列的一半,直到找到相等元素的位置或者最终没有找到要找的元素。

算法实现

简单实现

// 二分查找
public static int binarySearch(int[] a, int target) {int left = 0;int right = a.length - 1;while (left <= right) {int mid = (left + right) / 2;if (a[mid] == target) {return mid;} else if (a[mid] < target) {left = mid + 1;} else {right = mid - 1;}}return -1; 
}

left+right可能超过int表示的最大限度

出现结果:mid算出来为负数。
java中int类型占4个字节的最大值是 231−12^{31}-12311, 即 2147483647
如果超过了表示范围,则会发送越界,则会加到符号位。
那么我们可以进行无符号右移就可以完成除法运算,和解决越界问题了。
(有没有可能超过32位,2个int数相加最大不会大于232−12^{32}-12321,所以一定不会超过int存储)
所以代码修改如下

int mid =(left+right)>>>2;

代码分析和变换

简单实现里面:还是建议把等值放到最后面,因为等值的可能性是最低的,这样也就可以降低判断的次数。
把谁放第一判断,则那一边效率会高一点,如果下代码,如果数据偏右,则效率可能高些。

if (a[mid] < target) {left = mid + 1;
} else if (a[mid] > target) {right = mid - 1;
} else {return mid;
}

最坏情况O(log⁡n)O(\log n)O(logn)
最好情况O(1)O(1)O(1)
空间复杂度O(1)O(1)O(1)

均衡性:每次循环必定需要一次判断

public static int binarySearch(int[] a, int target) {int left = 0;int right = a.length;while (right - left <= 1) {int mid = (left + right) / 2;if (target < a[mid]) {right = mid;} else{left = mid;}}return a[i]==target?i:-1;}return -1; 
}

时间复杂度Ω(log⁡n)\Omega(\log n)Ω(logn)

更多需求:求索引最小的值

public static int binarySearchMin(int[] a, int target){int l=0,r=a.length;while(l < r){int m = (l + r) >>> 1;if (a[m] < target)l = m + 1;elser = m;}return l;
}

注意:如果数据不存在则返回的是切入点
不想这样的话可以

return a[l]==target?l:-(l+1);

java二分API

在Arrays类中有一个binarySearch()的方法可以返回数组中二分查找的结果
使用:

binarySearch(数组,key)

在这里插入图片描述
源代码:和我们实现的差不多。
在这里插入图片描述

格外的api

public static int binarySearch(int[] a, int fromIndex, int toIndex,int key)
fromIndex – 要搜索的第一个元素(包括)的索引 
toIndex – 要搜索的最后一个元素(独占)的索引

应用

基础题

力扣278. 第一个错误的版本
解决:二分求索引最小


public class Solution extends VersionControl {public int firstBadVersion(int n) {int l=1;int r=n;while(l < r){int mid=(l+r)>>>1;if(isBadVersion(mid))r=mid;elsel=mid+1;}return l;}
}

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

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。

public int[] searchRange(int[] nums, int target) {int x = -1, y = -1;int l = 0, r = nums.length - 1;while (l < r) {int m = (l + r) >>> 1;if (nums[m] >= target)r = m;elsel = m + 1;}if (l < 0 || l > nums.length-1||nums[l] != target)return new int[]{x, y};x = l;r = nums.length - 1;while (l < r) {int m = (l + r) >>> 1;if (nums[m] > target)r = m - 1;elsel = m + 1;}y = l - 1;return new int[]{x, y};}

思考难度

leetcode 4. 寻找两个正序数组的中位数
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数.
算法的时间复杂度应该为 O(log(m+n)) 。

分析:
l=n+m为总数
求中位数:

  1. 如果l为奇数,则中位数为(l+1)/2的位置
  2. 如果为偶数,则中位数为(l+1)/2和(l+2)/2的平均数

即求指定位置k的数。

在每次比较k/2位置的2个数组上的数如果n1[k/2]<n2[k/2]则n1上k/2以前的数都在合并k位置之前。
如:
n1=[1,2,4,5,6]
n2=[2,3,5,7,9,11]
l=11 k=6 k/2=3
n1[3]=4<n2[3]=5
则1,2,4都会在合并数组k位置的前面

n1=[5,6]
n2[2,3,5,7,9,11]
此时k=3 k/2=1
比较5和2

所以
n1=[5,6]
n2[3.5,7,9,11]
此时k=2,k/2=1
去掉一个3

k=1
返回2个最开始的小值就行。

问:
1.能不能在k=2的时候返回大值呢?
不行的,如果一个数组1,2另一个3,4就不可用。
2.如果k/2大于一个数组长度呢?
那就取这个数组最后一个就行了,这样要么不用考虑这个数组了,要么长数组会变短。

public double findMedianSortedArrays(int[] nums1, int[] nums2) {int n = nums1.length;int m = nums2.length;int left = (n + m + 1) / 2;int right = (n + m + 2) / 2;//将偶数和奇数的情况合并,如果是奇数,会求两次同样的 k 。return (search(nums1, 0, nums2, 0, left) + search(nums1, 0, nums2, 0, right)) * 0.5; 
}
// a为一个数组,i为这个数组剩下的.b同理
// k 为需要求的数的位置
public int search(int[] a,int i,int[] b,int j,int k){//求剩余长度int l1 = a.length-i;int l2 = b.length-j;//调整l1永远为短的if(l1>l2) return search(b,j,a,i,k);if(l1 == 0) return b[j+k-1];if (k == 1) return Math.min(a[i], b[j]);int q = k/2;//x,y 为索引int x = i + Math.min(q,l1) - 1;int y = j + Math.min(q,l2) - 1;if(a[x] > b[y])return search(a,i,b,y+1,k-(y-j+1));elsereturn search(a,x+1,b,j,k-(x-i+1));
}

方法

leetcode2439. 最小化数组中的最大值
给你一个下标从 0 开始的数组 nums ,它含有 n 个非负整数。
每一步操作中,你需要:
选择一个满足 1 <= i < n 的整数 i ,且 nums[i] > 0 。
将 nums[i] 减 1 。
将 nums[i - 1] 加 1 。
你可以对数组执行任意次上述操作,请你返回可以得到的 nums 数组中最大值最小为多少。

示例 1:

输入:nums = [3,7,1,6]
输出:5
解释:
一串最优操作是:
1. 选择 i = 1 ,nums 变为 [4,6,1,6] 。
2. 选择 i = 3 ,nums 变为 [4,6,2,5] 。
3. 选择 i = 1 ,nums 变为 [5,5,2,5] 。
nums 中最大值为 5 。无法得到比 5 更小的最大值。
所以我们返回 5 。

示例 2:

输入:nums = [10,1]
输出:10
解释:
最优解是不改动 nums ,10 是最大值,所以返回 10 。

提示:
n==nums.lengthn == nums.lengthn==nums.length
2<=n<=1052 <= n <= 10^52<=n<=105
0<=nums[i]<=1090 <= nums[i] <= 10^90<=nums[i]<=109

分析:
这个题目是我第一次遇到二分答案的题目,属实打开了我的新世界了。
对答案进行二分。
1.根据题目要求右边只能降,左边只能升。第一个值可以从后面所有的值里面取过来。
2.所以对一个最大值m是否符合条件,我们可以从左往右遍历,如果这个数k比他小那么,则需要m-k个位置,如果比他大,那么把需要减掉,这时如果需求为负数,则一定不是这个数。

但是最大值如果很大,那么都会是需要位置而没有剪掉的呢?
因为我们二分会去找最小可能,即找到符合的最左边就行。

public int minimizeArrayValue(int[] nums) {int l = 0,r = Integer.MAX_VALUE;while(l < r){int m = (l+r)>>>1;if(check(nums,m))r = m;elsel = m+1;}return r;
}
public static boolean check(int[]a,int m){long count = 0;for(int i:a){if(i<m)count+=m-i;else{count -= i-m;if(count < 0)return false;}}return true;
}
http://www.hengruixuexiao.com/news/12975.html

相关文章:

  • 政府网站建设申论seozou是什么意思
  • 上海网络平台网站搜索引擎网址
  • 新网站做百度百科手机网站优化排名
  • 如何做网赌网站南宁网站建设
  • 营销推广的方法seo虚拟外链
  • 怎么在家开网店挣钱呢站内优化包括哪些
  • php网站制作报价网络营销的新特点
  • 江苏商城网站建设aso安卓优化公司
  • 与有权重网站做友链网络怎么推广自己的产品
  • 北京营销型网站建设价格河南网站公司
  • 哪个网站做的系统好用免费站推广网站在线
  • 品牌网站建设预算长沙正规关键词优化价格从优
  • b2b商城网站公司推广策划方案
  • ideo设计公司上海北京seo排名技术
  • 返利网站怎么做的宁德市教育局官网
  • 好看的网站都找谁做的俄罗斯搜索引擎浏览器
  • 国家建设工程安全质量监督网站全国人大常委会委员长
  • 营销网站首页设计搜索引擎网页
  • 无为网站建设如何在百度免费发布广告
  • 网站空间多少钱一年营销网站建设创意
  • 嘚嘚笔记 wordpress主推windows优化大师有毒吗
  • 广告企业网站模板广州网站建设工作室
  • 报名窗口网站建设韩国热搜榜
  • 做百度手机网站排名百度大数据平台
  • 做网站是用c 吗旅游seo整站优化
  • 国外网站做任务赚钱的seo排名优化关键词
  • h5个人博客网站模板优秀营销软文范例100字
  • 网站推广搜索全媒体广告加盟
  • 接入服务商网站备案管理系统技术规范要求郑州网站推广优化
  • 广东网站开发收费互联网广告代理