騰訊2020-05春招補錄筆試
這個題可以按分治思想,把問題簡化爲找到最小值,分成兩部分,在每個部分內繼續找最小值劃分
首先看一下算法分析:
我們有兩種刷法,橫着刷與豎着刷
核心思想就是利用上面兩種方法把最短的刷完遞歸
①只利用橫着刷把最短刷完然後遞歸
爲什麼要全用橫着刷而不是橫豎混刷?
因爲如果第一次橫着刷以後再豎着刷的話,接下來就是遞歸,
如果在子問題中先橫着刷的話那麼還不如在上一次中直接橫着再刷一道,這樣並不會影響總次數。
如果子問題豎着刷的話,接着遞歸在新的子問題中如果橫着刷的話還不如在上一次的上一次中直接橫着再刷一道,這樣並不會影響總次數。
那麼一直這樣分析下去最後我們發現結果就是橫着刷把最短刷完然後遞歸
②豎着一次刷完最短然後遞歸
import org.junit.Test;
public class AVL {
@Test
public void Test()
{
int array[]={1,1,9999,1,1};
System.out.println(BrushSticks(array,0,4,0));
}
//算法的思想就是分治法
//刷的方法分爲兩種橫刷與豎刷代表將left-right範圍內的值減去dx
//遞歸的出口是left>right
int BrushSticks(int array[],int left ,int right,int dx){
if(left>right){
return 0;
}else{
//橫着全部刷完
int min_index = Find_MiniIndex(array,left,right);
//由於這一下刷下去可能會存在一樣的最小短板
int nums = 0;
int a,b;
int i = left;
//將各個子區間遞歸
while(i<=right){
while(i<=right&&array[i]==array[min_index]){
i++;
}
a=i;
while(i<=right&&array[i]>array[min_index]){
i++;
}
b=i-1;
nums+=BrushSticks(array,a,b,array[min_index]+dx);
}
nums+=array[min_index]-dx;
//直接豎着刷
int nums1=BrushSticks(array,left,min_index-1,dx)+BrushSticks(array,min_index+1,right,dx)+1;
return (nums>nums1)?nums1:nums;
}
}
int Find_MiniIndex(int[] arr,int left,int right){
int min = arr[left];
int min_index = left;
for(int i=left;i<=right;i++){
if(arr[i]<min){
min = arr[i];
min_index = i;
}
}
return min_index;
}
}