日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

詳解Java實(shí)現(xiàn)分治算法

瀏覽:155日期:2022-08-10 14:29:22
目錄一、前言二、分治算法介紹三、分治算法經(jīng)典問(wèn)題3.1、二分搜索3.2、快速排序3.3、歸并排序(逆序數(shù))3.4、最大子序列和3.5、最近點(diǎn)對(duì)四、結(jié)語(yǔ)一、前言

在學(xué)習(xí)分治算法之前,問(wèn)你一個(gè)問(wèn)題,相信大家小時(shí)候都有存錢(qián)罐的經(jīng)歷,父母親人如果給錢(qián)都會(huì)往自己的寶藏中存錢(qián),我們每隔一段時(shí)間都會(huì)清點(diǎn)清點(diǎn)錢(qián)。但是一堆錢(qián)讓你處理起來(lái)你可能覺(jué)得很復(fù)雜,因?yàn)閿?shù)據(jù)相對(duì)于大腦有點(diǎn)龐大了,并且很容易算錯(cuò),你可能會(huì)將它先分成幾個(gè)小份算,然后再疊加起來(lái)計(jì)算總和就獲得這堆錢(qián)的總數(shù)了

詳解Java實(shí)現(xiàn)分治算法

當(dāng)然如果你覺(jué)得各個(gè)部分錢(qián)數(shù)量還是太大,你依然可以進(jìn)行劃分然后合并,我們之所以這么多是因?yàn)椋?/p> 計(jì)算每個(gè)小堆錢(qián)的方式和計(jì)算最大堆錢(qián)的方式是相同的(區(qū)別在于體量上) 然后大堆錢(qián)總和其實(shí)就是小堆錢(qián)結(jié)果之和。這樣其實(shí)就有一種分治的思想。二、分治算法介紹

分治算法是用了分治思想的一種算法,什么是分治?

分治,字面上的解釋是“分而治之”,就是把一個(gè)復(fù)雜的問(wèn)題分成兩個(gè)或更多的相同或相似的子問(wèn)題,再把子問(wèn)題分成更小的子問(wèn)題……直到最后子問(wèn)題可以簡(jiǎn)單的直接求解,原問(wèn)題的解即子問(wèn)題的解的合并。在計(jì)算機(jī)科學(xué)中,分治法就是運(yùn)用分治思想的一種很重要的算法。分治法是很多高效算法的基礎(chǔ),如排序算法(快速排序,歸并排序),傅立葉變換(快速傅立葉變換)等等。

將父問(wèn)題分解為子問(wèn)題同等方式求解,這和遞歸的概念很吻合,所以在分治算法通常以遞歸的方式實(shí)現(xiàn)(當(dāng)然也有非遞歸的實(shí)現(xiàn)方式)。分治算法的描述從字面上也很容易理解,分、治其實(shí)還有個(gè)合并的過(guò)程:

分(Divide):遞歸解決較小的問(wèn)題(到終止層或者可以解決的時(shí)候停下) 治(Conquer):遞歸求解,如果問(wèn)題夠小直接求解。 合并(Combine):將子問(wèn)題的解構(gòu)建父類(lèi)問(wèn)題

一般分治算法在正文中分解為兩個(gè)即以上的遞歸調(diào)用,并且子類(lèi)問(wèn)題一般是不想交的(互不影響)。當(dāng)求解一個(gè)問(wèn)題規(guī)模很大很難直接求解,但是規(guī)模較小的時(shí)候問(wèn)題很容易求解并且這個(gè)問(wèn)題并且問(wèn)題滿(mǎn)足分治算法的適用條件,那么就可以使用分治算法。

詳解Java實(shí)現(xiàn)分治算法

那么采用分治算法解決的問(wèn)題需要 滿(mǎn)足那些條件(特征) 呢?

1 . 原問(wèn)題規(guī)模通常比較大,不易直接解決,但問(wèn)題縮小到一定程度就能較容易的解決。

2 . 問(wèn)題可以分解為若干規(guī)模較小、求解方式相同(似)的子問(wèn)題。且子問(wèn)題之間求解是獨(dú)立的互不影響。

3 . 合并問(wèn)題分解的子問(wèn)題可以得到問(wèn)題的解。

你可能會(huì)疑惑分治算法和遞歸有什么關(guān)系?其實(shí)分治重要的是一種思想,注重的是問(wèn)題分、治、合并的過(guò)程。而遞歸是一種方式(工具),這種方式通過(guò)方法自己調(diào)用自己形成一個(gè)來(lái)回的過(guò)程,而分治可能就是利用了多次這樣的來(lái)回過(guò)程。

三、分治算法經(jīng)典問(wèn)題

對(duì)于分治算法的經(jīng)典問(wèn)題,重要的是其思想,因?yàn)槲覀兇蟛糠纸柚f歸去實(shí)現(xiàn),所以在代碼實(shí)現(xiàn)上大部分都是很簡(jiǎn)單,而本篇也重在講述思想。

分治算法的經(jīng)典問(wèn)題,個(gè)人將它分成兩大類(lèi):子問(wèn)題完全獨(dú)立和子問(wèn)題不完全獨(dú)立。

1 . 子問(wèn)題完全獨(dú)立就是原問(wèn)題的答案可完全由子問(wèn)題的結(jié)果推出。

2 . 子問(wèn)題不完全獨(dú)立,有些區(qū)間類(lèi)的問(wèn)題或者跨區(qū)間問(wèn)題使用分治可能結(jié)果跨區(qū)間,在考慮問(wèn)題的時(shí)候需要仔細(xì)借鑒下。

3.1、二分搜索

二分搜索是分治的一個(gè)實(shí)例,只不過(guò)二分搜索有著自己的特殊性

序列有序 結(jié)果為一個(gè)值

正常二分將一個(gè)完整的區(qū)間分成兩個(gè)區(qū)間,兩個(gè)區(qū)間本應(yīng)單獨(dú)找值然后確認(rèn)結(jié)果,但是通過(guò)有序的區(qū)間可以直接確定結(jié)果在那個(gè)區(qū)間,所以分的兩個(gè)區(qū)間只需要計(jì)算其中一個(gè)區(qū)間,然后繼續(xù)進(jìn)行一直到結(jié)束。實(shí)現(xiàn)方式有遞歸和非遞歸,但是非遞歸用的更多一些:

public int searchInsert(int[] nums, int target) { if(nums[0]>=target)return 0;//剪枝 if(nums[nums.length-1]==target)return nums.length-1;//剪枝 if(nums[nums.length-1]<target)return nums.length; int left=0,right=nums.length-1; while (left<right) { int mid=(left+right)/2; if(nums[mid]==target) return mid; else if (nums[mid]>target) { right=mid; } else { left=mid+1; } } return left;}3.2、快速排序

快排也是分治的一個(gè)實(shí)例,快排每一趟會(huì)選定一個(gè)數(shù),將比這個(gè)數(shù)小的放左面,比這個(gè)數(shù)大的放右面,然后遞歸分治求解兩個(gè)子區(qū)間,當(dāng)然快排因?yàn)樵诜值臅r(shí)候就做了很多工作,當(dāng)全部分到最底層的時(shí)候這個(gè)序列的值就是排序完的值。這是一種分而治之的體現(xiàn)。

詳解Java實(shí)現(xiàn)分治算法

public void quicksort(int [] a,int left,int right){ int low=left; int high=right; //下面兩句的順序一定不能混,否則會(huì)產(chǎn)生數(shù)組越界!!!very important!!! if(low>high)//作為判斷是否截止條件 return; int k=a[low];//額外空間k,取最左側(cè)的一個(gè)作為衡量,最后要求左側(cè)都比它小,右側(cè)都比它大。 while(low<high)//這一輪要求把左側(cè)小于a[low],右側(cè)大于a[low]。 { while(low<high&&a[high]>=k)//右側(cè)找到第一個(gè)小于k的停止 { high--; } //這樣就找到第一個(gè)比它小的了 a[low]=a[high];//放到low位置 while(low<high&&a[low]<=k)//在low往右找到第一個(gè)大于k的,放到右側(cè)a[high]位置 { low++; } a[high]=a[low]; } a[low]=k;//賦值然后左右遞歸分治求之 quicksort(a, left, low-1); quicksort(a, low+1, right);}3.3、歸并排序(逆序數(shù))

快排在分的時(shí)候做了很多工作,而歸并就是相反,歸并在分的時(shí)候按照數(shù)量均勻分,而合并時(shí)候已經(jīng)是兩兩有序的進(jìn)行合并的,因?yàn)閮蓚€(gè)有序序列O(n)級(jí)別的復(fù)雜度即可得到需要的結(jié)果。而逆序數(shù)在歸并排序基礎(chǔ)上變形同樣也是分治思想求解。

詳解Java實(shí)現(xiàn)分治算法

private static void mergesort(int[] array, int left, int right) { int mid=(left+right)/2; if(left<right) { mergesort(array, left, mid); mergesort(array, mid+1, right); merge(array, left,mid, right); }}private static void merge(int[] array, int l, int mid, int r) { int lindex=l;int rindex=mid+1; int team[]=new int[r-l+1]; int teamindex=0; while (lindex<=mid&&rindex<=r) {//先左右比較合并 if(array[lindex]<=array[rindex]) { team[teamindex++]=array[lindex++]; } else { team[teamindex++]=array[rindex++]; } } while(lindex<=mid)//當(dāng)一個(gè)越界后剩余按序列添加即可 { team[teamindex++]=array[lindex++]; } while(rindex<=r) { team[teamindex++]=array[rindex++]; } for(int i=0;i<teamindex;i++) { array[l+i]=team[i]; }}3.4、最大子序列和

最大子序列和的問(wèn)題我們可以使用動(dòng)態(tài)規(guī)劃的解法,但是也可以使用分治算法來(lái)解決問(wèn)題,但是最大子序列和在合并的時(shí)候并不是簡(jiǎn)單的合并,因?yàn)樽有蛄泻蜕婕暗揭粋€(gè)長(zhǎng)度的問(wèn)題,所以正確結(jié)果不一定全在最左側(cè)或者最右側(cè),而可能出現(xiàn)結(jié)果的區(qū)域?yàn)椋?/p> 完全在中間的左側(cè) 完全在中間的右側(cè) 包含中間左右兩個(gè)節(jié)點(diǎn)的一個(gè)序列

用一張圖可以表示為:

詳解Java實(shí)現(xiàn)分治算法

所以在具體考慮的時(shí)候需要將無(wú)法遞歸得到結(jié)果的中間那個(gè)最大值串的結(jié)果也算出來(lái)參與左側(cè)、右側(cè)值得比較。

力扣53. 最大子序和在實(shí)現(xiàn)的代碼為:

public int maxSubArray(int[] nums) { int max=maxsub(nums,0,nums.length-1); return max;}int maxsub(int nums[],int left,int right){ if(left==right)return nums[left]; int mid=(left+right)/2; int leftmax=maxsub(nums,left,mid);//左側(cè)最大 int rightmax=maxsub(nums,mid+1,right);//右側(cè)最大 int midleft=nums[mid];//中間往左 int midright=nums[mid+1];//中間往右 int team=0; for(int i=mid;i>=left;i--) {team+=nums[i];if(team>midleft) midleft=team; } team=0; for(int i=mid+1;i<=right;i++) {team+=nums[i];if(team>midright) midright=team; } int max=midleft+midright;//中間的最大值 if(max<leftmax)max=leftmax; if(max<rightmax)max=rightmax; return max;}3.5、最近點(diǎn)對(duì)

最近點(diǎn)對(duì)是一個(gè)分治非常成功的運(yùn)用之一。在二維坐標(biāo)軸上有若干個(gè)點(diǎn)坐標(biāo),讓你求出最近的兩個(gè)點(diǎn)的距離,如果讓你直接求那么枚舉暴力是個(gè)非常非常大的計(jì)算量,我們通常采用分治的方法來(lái)優(yōu)化這種問(wèn)題。

詳解Java實(shí)現(xiàn)分治算法

如果直接分成兩部分分治計(jì)算你肯定會(huì)發(fā)現(xiàn)如果最短的如果一個(gè)在左一個(gè)在右會(huì)出現(xiàn)問(wèn)題。我們可以?xún)?yōu)化一下。

在具體的優(yōu)化方案上,按照x或者y的維度進(jìn)行考慮,將數(shù)據(jù)分成兩個(gè)區(qū)域,先分別計(jì)算(按照同方法)左右區(qū)域內(nèi)最短的點(diǎn)對(duì)。然后根據(jù)這個(gè)兩個(gè)中較短的距離向左和向右覆蓋,計(jì)算被覆蓋的左右點(diǎn)之間的距離,找到最小那個(gè)距離與當(dāng)前最短距離比較即可。

詳解Java實(shí)現(xiàn)分治算法

這樣你就可以發(fā)現(xiàn)就這個(gè)一次的操作(不考慮子情況),左側(cè)紅點(diǎn)就避免和右側(cè)大部分紅點(diǎn)進(jìn)行距離計(jì)算(O(n2)的時(shí)間復(fù)雜度)。事實(shí)上,在進(jìn)行左右區(qū)間內(nèi)部計(jì)算的時(shí)候,它其實(shí)也這樣遞歸的進(jìn)行很多次分治計(jì)算。如圖所示:

詳解Java實(shí)現(xiàn)分治算法

這樣下去就可以節(jié)省很多次的計(jì)算量。

但是這種分治會(huì)存在一種問(wèn)題就是二維坐標(biāo)可能點(diǎn)都聚集某個(gè)方法某條軸那么可能效果并不明顯(點(diǎn)都在x=2附近對(duì)x分割作用就不大),需要注意一下。

ac的代碼為:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.io.StreamTokenizer;import java.util.ArrayList;import java.util.Arrays;import java.util.Comparator;import java.util.List;public class Main { static int n; public static void main(String[] args) throws IOException {StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));//List<node>list=new ArrayList(); while(in.nextToken()!=StreamTokenizer.TT_EOF) { n=(int)in.nval;if(n==0) {break;} node no[]=new node[n]; for(int i=0;i<n;i++) { in.nextToken();double x=in.nval; in.nextToken();double y=in.nval;// list.add(new node(x,y)); no[i]=new node(x,y); } Arrays.sort(no, com); double min= search(no,0,n-1); out.println(String.format('%.2f', Math.sqrt(min)/2));out.flush(); } } private static double search(node[] no, int left,int right) {int mid=(right+left)/2;double minleng=0;if(left==right) {return Double.MAX_VALUE;}else if(left+1==right) {minleng= (no[left].x-no[right].x)*(no[left].x-no[right].x)+(no[left].y-no[right].y)*(no[left].y-no[right].y);}else minleng= min(search(no,left,mid),search(no,mid,right));int ll=mid;int rr=mid+1;while(no[mid].y-no[ll].y<=Math.sqrt(minleng)/2&&ll-1>=left) {ll--;}while(no[rr].y-no[mid].y<=Math.sqrt(minleng)/2&&rr+1<=right) {rr++;}for(int i=ll;i<rr;i++){ for(int j=i+1;j<rr+1;j++) {double team=0;if(Math.abs((no[i].x-no[j].x)*(no[i].x-no[j].x))>minleng) {continue;}else{ team=(no[i].x-no[j].x)*(no[i].x-no[j].x)+(no[i].y-no[j].y)*(no[i].y-no[j].y); if(team<minleng)minleng=team;} }}return minleng;} private static double min(double a, double b) {// TODO 自動(dòng)生成的方法存根return a<b?a:b; } static Comparator<node>com=new Comparator<node>() {@Overridepublic int compare(node a1, node a2) { // TODO 自動(dòng)生成的方法存根 return a1.y-a2.y>0?1:-1;}}; static class node {double x;double y;public node(double x,double y){ this.x=x; this.y=y;} }}四、結(jié)語(yǔ)

到這里,分治算法就講這么多了,因?yàn)榉种嗡惴ㄖ匾谟诶斫馄渌枷耄€有一些典型的分治算法解決的問(wèn)題,例如大整數(shù)乘法、Strassen矩陣乘法、棋盤(pán)覆蓋、線性時(shí)間選擇、循環(huán)賽日程表、漢諾塔等問(wèn)題你可以自己研究其分治的思想和原理。

以上就是詳解Java實(shí)現(xiàn)分治算法的詳細(xì)內(nèi)容,更多關(guān)于詳解Java實(shí)現(xiàn)分治算法的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩欧美三区| 日韩一区网站| 国产精品久久久久av蜜臀| 国产午夜久久av| 久久久亚洲欧洲日产| 国产aⅴ精品一区二区四区| 四虎国产精品免费观看| 日韩三区在线| 国产亚洲精品久久久久婷婷瑜伽| 免费成人av在线播放| 日韩动漫一区| 欧美日韩伊人| 国产精久久一区二区| 国产精品久久久久久久久久10秀| 日本精品在线中文字幕| 久久亚洲不卡| 久久不卡国产精品一区二区| 日本一区二区高清不卡| 亚洲午夜91| 亚洲区国产区| 91一区二区三区四区| 午夜久久黄色| 91精品国产一区二区在线观看 | 蜜桃视频一区二区三区| 日本午夜精品久久久久| 乱一区二区av| 不卡在线一区二区| 日韩av成人高清| 黄色在线网站噜噜噜| 国产毛片一区| 久久超碰99| 伊人精品视频| 国产精品观看| 夜夜嗨网站十八久久| 国产免费av国片精品草莓男男 | 精品国产aⅴ| 亚洲天堂成人| 欧美aaaaaa午夜精品| 亚洲手机在线| 国产精品亚洲产品| 夜夜嗨av一区二区三区网站四季av| 国产精品久久久久久久久久白浆| 午夜国产精品视频| 国产一区二区三区成人欧美日韩在线观看| 欧美日韩激情在线一区二区三区| 国产欧美亚洲精品a| 亚洲黄页一区| 成人午夜亚洲| 日韩欧美美女在线观看| 999久久久精品国产| 国产精品一国产精品| 99久久亚洲精品| 国产精品调教| 蜜臀国产一区二区三区在线播放| 高清一区二区| 日韩在线电影| 在线亚洲免费| 日韩在线欧美| 国产精品videossex| 亚洲三区欧美一区国产二区| 国产在线日韩| 91亚洲一区| 精品网站999| 久久国产生活片100| 国产亚洲毛片在线| 91看片一区| 麻豆精品蜜桃视频网站| 亚洲精品福利| 婷婷亚洲五月| 日韩伦理一区| 国产成人77亚洲精品www| 日韩高清二区| 亚洲乱亚洲高清| 99精品99| 91超碰国产精品| 亚洲午夜在线| 黑森林国产精品av| 精品欧美视频| 国产精品v亚洲精品v日韩精品| 日本一区二区中文字幕| 国产精品日本| 香蕉久久夜色精品国产| 欧美日韩在线网站| 亚洲人成在线网站| 麻豆mv在线观看| 国产精品yjizz视频网| 成人午夜网址| 婷婷综合六月| 日本精品在线中文字幕| 欧美精品日日操| 日韩福利一区| 日韩av免费| 久久国产欧美| 不卡av一区二区| 亚洲一区二区毛片| 久久福利精品| 中文不卡在线| 日本欧美一区二区在线观看| 日韩福利视频导航| 欧美日韩亚洲一区在线观看| 国产日韩欧美高清免费| 国产日韩欧美一区二区三区| 国产日韩欧美一区| 另类综合日韩欧美亚洲| 久久精品人人| 蜜臀国产一区| 欧美在线资源| 亚洲不卡视频| 国产精品巨作av| 成人在线黄色| 免费欧美一区| 亚洲一区二区三区久久久| 亚洲69av| 国产另类在线| 国产成人精品亚洲线观看| 欧美日韩中文一区二区| 国产精品日本| 久久国产麻豆精品| 欧美xxxx中国| 日韩一区二区久久| 美国三级日本三级久久99 | 国产另类在线| 国产一区二区三区四区大秀 | 日本亚洲三级在线| 国产日韩一区二区三区在线| 国产一区精品福利| 亚洲二区在线| 日韩三级久久| 91偷拍一区二区三区精品| 五月天久久网站| 欧美亚洲一区二区三区| 91亚洲国产成人久久精品| 99国产精品免费视频观看| 亚洲欧美日韩一区在线观看| 国产精品一区二区中文字幕| 国产成人在线中文字幕| 91精品蜜臀一区二区三区在线 | 日本国产亚洲| а√天堂8资源中文在线| 亚洲欧美视频| 精品日韩一区| 视频一区视频二区中文字幕| 国产精品大片| 黑丝一区二区三区| 麻豆精品视频在线| 国产精品日本| 国产精品免费99久久久| 亚洲二区精品| 欧美韩一区二区| 久久国产精品毛片| 国产精品国产一区| 少妇精品久久久| 久久精品国内一区二区三区水蜜桃| 日韩中文字幕无砖| 久久久久国产精品一区三寸| 日韩国产精品久久久久久亚洲| 在线中文字幕播放| 亚洲va久久久噜噜噜久久| 捆绑调教日本一区二区三区| 亚洲精品成人一区| 久久久久久久久久久妇女| 亚洲精选成人| 久久国产主播| 精品一区二区三区亚洲| 日精品一区二区三区| 影视先锋久久| 福利一区二区三区视频在线观看| 亚洲精品护士| 好吊视频一区二区三区四区| 精品成人18| 日韩av一区二区在线影视| 激情五月色综合国产精品| 欧美黑人做爰爽爽爽| 蜜臀久久99精品久久久久宅男| 色婷婷色综合| 久久国产精品免费精品3p| 欧美91视频| 国产拍在线视频| 久久中文字幕导航| 欧美精选视频一区二区| 久久中文在线| 国产精品一区二区三区四区在线观看 | 成人午夜亚洲| 国产欧美一区二区三区精品观看 | 国产精品亚洲二区| 老牛国产精品一区的观看方式| 日韩久久视频| 四虎国产精品免费观看| 美女性感视频久久| 国产探花一区| 日韩 欧美一区二区三区| 99视频+国产日韩欧美| 日韩精品一区二区三区免费观影 | 亚洲高清久久| 精品国产亚洲日本| 美女久久久精品| 国产精品一区三区在线观看| 视频一区日韩精品| 亚洲三级av| 亚州av一区|