日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《剑指offer》--二维数组中的查找、从头到尾打印链表、重建二叉树、旋转数组的最小数字

發(fā)布時間:2024/9/30 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《剑指offer》--二维数组中的查找、从头到尾打印链表、重建二叉树、旋转数组的最小数字 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、二維數(shù)值中的查找:

1、題目:

在一個二維數(shù)組中(每個一維數(shù)組的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數(shù),輸入這樣的一個二維數(shù)組和一個整數(shù),判斷數(shù)組中是否含有該整數(shù)。

2、解題思路:

通過分析可以很簡單的找出一個規(guī)律,二維數(shù)組的最左下角的的點,該點的所在列上邊的點都是減少的,該點所在行右邊的點都是增加的。因此,我們以該點作為切入點,如果目標數(shù)比左下角的數(shù)大,則往右邊移動;如果目標數(shù)比左下角的數(shù)小,則往上邊移動;之后以此類推,如果匹配到目標數(shù),則返回true;如果當移動到最右上角的點仍然沒有匹配到目標數(shù),則返回false。

3、代碼示例:

public boolean Find(int target, int[][] array) {int rowCount = array.length;int colCount = array[0].length;int x, y;for (y = rowCount - 1, x = 0; y >= 0 && x < colCount;) {if (target == array[y][x]) {return true;} else if (target > array[y][x]) {x++;continue;} else if (target < array[y][x]) {y--;continue;}}return false;}

?

二、從頭到尾打印鏈表:

1、題目:

輸入一個鏈表,按鏈表值從尾到頭的順序返回一個ArrayList。

2、代碼實現(xiàn):

public class Solution{//第二種方式:遞歸實現(xiàn):ArrayList<Integer> resultList = new ArrayList<Integer>();public ArrayList<Integer> printListFromTailToHead2(ListNode listNode) {if(listNode!=null){this.printListFromTailToHead2(listNode.next);resultList.add(listNode.val);}return resultList;}//第一種方式,使用堆棧結(jié)構(gòu)public ArrayList<Integer> printListFromTailToHead1(ListNode listNode) {Stack<Integer> stack = new Stack<Integer>();while(listNode != null){stack.push(listNode.val);listNode = listNode.next;}ArrayList<Integer> resultList = new ArrayList<Integer>();while(!stack.isEmpty()){resultList.add(stack.pop());}return resultList;} }

?

?

三、重建二叉樹:

1、題目:

輸入某二叉樹的前序遍歷和中序遍歷的結(jié)果,請重建出該二叉樹。假設(shè)輸入的前序遍歷和中序遍歷的結(jié)果中都不含重復(fù)的數(shù)字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹并返回。

2、思路:

通過分析前序遍歷和中序遍歷的規(guī)律,前序遍歷的第一個節(jié)點就是二叉樹的根節(jié)點,中序遍歷中,位于根節(jié)點前面的所有節(jié)點都位于左子樹上,位于根節(jié)點后面的所有節(jié)點都位于右子樹上面。通過這個規(guī)律,我們可以使用遞歸方法來重建二叉樹。

3、代碼實現(xiàn):

class TreeNode{int val;TreeNode left;TreeNode right;TreeNode(int x){val=x;} }public class Test1 {public TreeNode reConstructBinaryTree(int[] pre,int[] in){//前序的第一個數(shù)是根節(jié)點TreeNode root = new TreeNode(pre[0]);int len=pre.length;if(len==1){root.left=null;root.right=null;return root;}//找出中序中的根節(jié)點位置int rootVal=root.val;int i;for(i=0;i<len;i++){if(rootVal==in[i])break;}//構(gòu)建左子樹if(i>0){int[] pr = new int[i];int[] ino = new int[i];for(int j=0;j<i;j++){pr[j]=pre[j+1];ino[j]=in[j];}root.left=reConstructBinaryTree(pr,ino);}else{root.left=null;}//構(gòu)建右子樹if(len-i-1>0){int[] pr =new int[len-i-1];int[] ino = new int[len-i-1];for(int j=i+1;j<len;j++){pr[j-i-1]=pre[j];ino[j-i-1]=in[j];}root.right=reConstructBinaryTree(pr,ino);}else{root.right=null;}return root;}}

4、第二種寫法:

public class Solution {public TreeNode reConstructBinaryTree(int [] pre,int [] in) {TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);return root;}//前序遍歷{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6}private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {if(startPre>endPre||startIn>endIn)return null;TreeNode root=new TreeNode(pre[startPre]);for(int i=startIn;i<=endIn;i++)if(in[i]==pre[startPre]){root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);break;}return root;} }

?

四、旋轉(zhuǎn)數(shù)組的最小數(shù)字:

1、題目:

把一個數(shù)組最開始的若干個元素搬到數(shù)組的末尾,我們稱之為數(shù)組的旋轉(zhuǎn)。 輸入一個非減排序的數(shù)組的一個旋轉(zhuǎn),輸出旋轉(zhuǎn)數(shù)組的最小元素。 例如數(shù)組{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉(zhuǎn),該數(shù)組的最小值為1。 NOTE:給出的所有元素都大于0,若數(shù)組大小為0,請返回0。

2、思路:

采用二分查詢的方法,但是需要處理兩種特殊情況:

即{1 0 1 1 1} 以及{1 1 1 0 1}這兩種類型的排序。

3、代碼實現(xiàn):

public class Solution {public int minNumberInRotateArray(int [] array) {if(array.length==0){return 0;}int leftIndex=0;int rightIndex=array.length-1;int midIndex=0;while(array[leftIndex]>=array[rightIndex]){//當左右兩個指針相互接觸,則說明已經(jīng)找到最小值,即右邊的指針的元素if(rightIndex-leftIndex<=1){midIndex=rightIndex;break;}midIndex=(leftIndex+rightIndex)/2;//這里是處理特殊情況,即當左中右三個指針的值都是一樣的時候,我們不能判斷最小元素位于哪個位置,只能通過遍歷的方法找出最小元素//特殊情況:{1 0 1 1 1} 以及{1 1 1 0 1}這兩種類型的排序if(array[rightIndex]==array[leftIndex] && array[leftIndex]==array[midIndex]){return MinInOrder(array,leftIndex,rightIndex);}//如果中間元素大于末尾元素,那么表明最小元素在后半段數(shù)組中,修改leftIndex指針位置if(array[midIndex]>=array[leftIndex]){leftIndex=midIndex;}else if(array[midIndex]<=array[rightIndex]){//如果中間元素小于末尾元素,那么表明最小元素在前半段部分中,修改rightIndex指針位置rightIndex=midIndex;}}return array[midIndex];}public int MinInOrder(int[] array,int leftIndex,int rightIndex){int result=array[leftIndex];for(int i=leftIndex+1;i<rightIndex;i++){if(result>array[i]){result=array[i];}}return result;}}

4、代碼實現(xiàn)2:

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

注意這里有個坑:如果待查詢的范圍最后只剩兩個數(shù),那么mid 一定會指向下標靠前的數(shù)字

比如 array = [4,6]

array[low] = 4 ;array[mid] = 4 ; array[high] = 6 ;

如果high = mid - 1,就會產(chǎn)生錯誤, 因此high = mid

?

?

總結(jié)

以上是生活随笔為你收集整理的《剑指offer》--二维数组中的查找、从头到尾打印链表、重建二叉树、旋转数组的最小数字的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。