二分法

二分法,尺取法,折半枚举,你们到底是什么?

随声附和 提交于 2020-03-08 10:18:03
最近写了一些题,对这三个概念稍微有点混淆,写点东西回忆一下。 二分法 二分法简介 ,将题目要求的量当做目标值,使用两个参数 l , r l,r l , r , l l l 从初始位置(往往是最小值之类的), r r r 从最终位置(往往是最大值),每次判断二者的平均值 m i d = ( l + r ) > > 2 mid=(l+r)>>2 m i d = ( l + r ) > > 2 是不是满足题意,根据该判断更新 l l l 或者 r r r 的值。二分法的应用大概包括以下几部分: 最大化最小值 最大化平均值 查找第 k k k 大的值 最小化第 k k k 大的值 专栏有不少对应的题 尺取法 尺取法简介 ,尺取法是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案。这对下标记为 l , r l,r l , r ,与二分法不同的是, 这里的 l , r l,r l , r 都是从区间的一侧开始的 ,而不是从区间两侧,而且尺取法擅长处理区间相关的问题,比如 大于某阈值的最短连续序列和 小于某阈值的最长连续序列和 最接近某值的连续序列和 同样专栏有不少题 折半枚举 有时候,问题的规模较大,无法枚举所有元素的组合,但能够枚举一半元素的组合。此时,将问题拆成两半后分别枚举,再合并它们的结果这一方法往往非常有效。不同于前两种方法

二分法-最长上升子序列

我是研究僧i 提交于 2020-03-07 15:19:45
思路:使用一个栈来求最长上升子序列的长度,当栈为空或者待插入元素大于栈顶元素时就入栈,否则替换栈中小于等于待插入元素的数并替换,最终栈的长度即为最长上升子序列的长度. 优点:使用二分查找,时间复杂度为O(nlogn). #include<iostream> #include<vector> using namespace std; vector<int> v; int solution(int arr[], int length) { for(int i = 0; i < length; i++) { if(v.size() == 0 || arr[i] > v[v.size() - 1]) //如果栈空或者大于栈顶就入栈 v.push_back(arr[i]); else //查找栈中小于等于arr[i]的元素并替换 { int begin = 0, end = v.size() - 1; int index = -1; while(begin <= end) { int mid = (end - begin) / 2 + begin; if(arr[mid] < arr[i]) begin = mid + 1; else { index = mid; end = mid - 1; } } v[index] = arr[i]; } } } int main() { int arr

二分法插入排序

ぐ巨炮叔叔 提交于 2020-03-06 21:49:30
#include "stdio.h" #include "malloc.h" typedef int KeyType; typedef int DataType; typedef struct { //排序码字段 KeyType key; //记录的其他字段 DataType info; }RecordNode; typedef struct { int n; RecordNode * record; }SortObject; void binSort(SortObject * pvector) { int i,j,left,right,middle; RecordNode temp; for(i=0;i<pvector->n;i++) { temp=pvector->record[i]; left=0; right=i-1; while (left<=right) { middle=(left+right)>>1; if (temp.key<pvector->record[middle].key) { right=middle-1; } else { left=middle+1; } } for(j=i-1;j>=left;j--) { pvector->record[j+1]=pvector->record[j]; } if (left!=i) { pvector-

二分法插入排序

怎甘沉沦 提交于 2020-03-06 21:49:14
一、二分法插入排序 基本思路:每次将一个待排序的数记录下,按其顺序大小,用二分法找到合适位置插入到前面已经排序的字序列(从后向前找到合适位置),直到全部插入排序完为止。 1.1 C实现 #include<stdio.h> #include<stdlib.h> int arr_num[]; int length; void insert_sort(int length) { int i; for(i=1; i<length; i++) { int temp; int low, high, mid; temp = arr_num[i]; low=0; high=i-1; while(low<=high) { mid = (low + high)/2; //通过二分法,找到记录值合适的位置 if(temp>a[mid]) { low = mid+1; } else { high = mid-1; } } //将记录值该在的位置腾出来 for (int j = i - 1; j >= low; j--) { a[j + 1] = a[j]; } // 如果记录值当前位置,就是合适位置则不操作 if (low != i) { a[low] = temp; } } 总结 从未排好的序列中拿出首元素,并把它赋值给temp变量; 从排好的序列中,依次与temp进行比较,如果元素比temp大

二分法

吃可爱长大的小学妹 提交于 2020-03-06 21:48:14
Date:2019-07-25 16:03:14 算法实现 1 /*---------------------------有序数组中查找给定数字x-------------------------*/ 2 #include <stdio.h> 3 4 //left=0, right=n-1 5 int binarySearch(int A[], int left, int right, int x) 6 { 7 int mid; //mid为left和right的中点 8 while(left <= right) 9 { 10 // 11 // 若right超过int型上界的一半,则left+right可能溢出 12 // mid = left + (right - left)/2; 替代 13 // 14 mid = (left+right) / 2; 15 16 if(A[mid] == x) 17 { 18 return mid; 19 } 20 else if(A[mid] > x) //中间数大于x,则往左区间查找 21 { 22 right = mid - 1; 23 } 24 else //中间数小于x,则往右区间查找 25 { 26 left = mid + 1; 27 } 28 } 29 30 return -1; //查找失败,返回-1 31 } 32 33

二分法插入排序

半世苍凉 提交于 2020-03-06 21:47:22
二分法插入排序 算法思想简单描写叙述: 在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们 中间的那个元素比,假设小,则对前半再进行折半,否则对后半 进行折半,直到left>right,然后再把第i个元素前1位与目标位置之间 的全部元素后移,再把第i个元素放在目标位置上。 二分法没有排序,仅仅有查找。所以当找到要插入的位置时。移动必须从最后一个记录開始,向后移动一位,再移动倒数第2位,直到要插入的位置的记录移后一位。 二分插入排序是稳定的,平均时间O(n 2 ) void binsort( ref int [] data1) 1 、二分法查找插入位置   假设 R[i]<R[m] 成立,那右指针就要向左移动中间指针一位,否则,左指针要向左移动中间指针一位。重复查找,直到左指针大于右指针时停止。 2 、后移,有点迷惑,什么时候须要后移呢?有哪些记录须要移动呢?   尽管我们非常清楚的知道,我们须要后移那些排序码大于 R[i] 的记录,但难免会问自己这样几个问题。事实上它相当于须要移动从 i-1 到左指针的记录。 3 、插入   由 1 中得到的左指针事实上就是元素要插入的位置。 4 、算法 { int left,right,num; int middle,j; for ( int i = 1;i < data1.Length;i++) { // 准备 left = 0;

java 实现二分法

谁说胖子不能爱 提交于 2020-03-06 21:46:38
http://www.cnblogs.com/vanezkw/archive/2012/06/29/2569470.html JDK里面的二分法实现。二分法的实现有多种今天就给大家分享两种。一种是递归方式的,一种是非递归方式的。先来看看一些基础的东西。 1、算法概念。 二分查找算法也称为折半搜索、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。请注意这种算法是建立在有序数组基础上的。 2、算法思想。 ①搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束; ②如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。 ③如果在某一步骤数组为空,则代表找不到。 这种搜索算法每一次比较都使搜索范围缩小一半。 3、实现思路。 ①找出位于数组中间的值,并存放在一个变量中(为了下面的说明,变量暂时命名为temp); ②需要找到的key和temp进行比较; ③如果key值大于temp,则把数组中间位置作为下一次计算的起点;重复① ②。 ④如果key值小于temp,则把数组中间位置作为下一次计算的终点;重复① ② ③。 ⑤如果key值等于temp,则返回数组下标,完成查找。 4、实现代码。 /** * description : 二分查找。 * @autor kwzhang * modify :2012-6

排序算法之二分法(折半)插入排序算法

安稳与你 提交于 2020-03-06 21:45:58
基本思想 折半插入排序的基本思想与直接插入排序一样,在插入第 i ( i ≥ 1 ) 个元素时,前面 i − 1 个元素已经排好序。差别在于寻找插入位置的方法不同。折半插入排序是採用折半查找法来寻找插入位置的。 折半查找法的基本思路是:用待插元素的值与当前查找序列的中间元素的值进行比較,以当前查找序列的中间元素为分界,确定待插元素是在当前查找序列的左边还是右边,假设是在其左边。则以该左边序列为当前查找序列。右边也相似。依照上述方法,递归地处理新序列。直到当前查找序列的长度小于1时查找过程结束。 代码 //待排数据存储在数组a中。以及待排序列的左右边界 public void BinaryInsertSort(int[] a, int left, int right) { int low, middle, high; int temp; for (int i = left + 1; i <= right; i++) { temp = a[i]; low = left; high = i - 1; while (low <= high) { middle = (low + high) / 2; if (a[i] < a[middle]) high = middle - 1; else low = middle + 1; } for (int j = i - 1; j >= low; j

python-使用递归实现二分法

巧了我就是萌 提交于 2020-03-06 21:45:38
在上一篇中简单介绍了递归的使用, 请戳这里 。 在此篇中,主要介绍如何用递归实现二分法。 在使用二分法之前,首先要有个前提,那就是这个数组必须是 有序数组 。主要的思路为:   ①先取出数组中的一个中间值, 和我们需要找的数字进行对比,如果恰好相等,则说明找到该数字,如果数组的中间值大于需要查找的数组,接下来的查找范围就为中间值之前的数组。反之为中间值之后的数组  ②对数组不断的缩小范围,最后当数组中只有一个数字时,再进行比较,如果相等,则找到,否则需要查找的数字就不在我们的数组中。 代码如下: def binary_search(data_source, find_number): """定义二分法""" mid = int(len(data_source)/2) #先取数组中的中间值 if len(data_source) > 1: #判断整个数组中的数字个数 if data_source[mid] > find_number: print('data is left of %s' % data_source[mid]) binary_search(data_source[:mid], find_number) elif data_source[mid] < find_number: print('data is right of %s' % data_source[mid])

二分法查找算法 (递归)

眉间皱痕 提交于 2020-03-06 21:45:23
有一由小到大排列的数组m[],数组大小为n,请用二分法查找算法找出与关键数key相等的元素,若查找成功返回元素在数组中的位置,没找到返回-1. 1 // 二分查找.cpp 2 3 #include "stdafx.h" 4 #include <string> 5 6 int search(int m[],int key,int low,int high) 7 { 8 int mid=(low+high)/2; 9 if (low>high) 10 return -1; 11 if (key==m[mid]) 12 return mid; 13 else if (key<m[mid]) 14 return search(m,key,low,mid-1); 15 else 16 return search(m,key,mid+1,high); 17 } 18 19 void main() 20 { 21 int a[]={1,2,5,7,9,12,16}; 22 int i,len; 23 len=sizeof(a)/sizeof(a[0])-1; 24 i=search(a,12,0,len); 25 printf("%d\n",i); 26 } 来源: https://www.cnblogs.com/xingele0917/archive/2012/10/04/2711628