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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

《剑指offer》-- 序列化二叉树、二叉搜索树的第k个节点、数据流中的中位数、滑动窗口的最大值

發布時間:2024/9/30 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《剑指offer》-- 序列化二叉树、二叉搜索树的第k个节点、数据流中的中位数、滑动窗口的最大值 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、序列化二叉樹:

1、題目:

請實現兩個函數,分別用來序列化和反序列化二叉樹。

2、解題思路:

(1)根據前序遍歷規則完成序列化與反序列化。所謂序列化指的是遍歷二叉樹為字符串;所謂反序列化指的是依據字符串重新構造成二叉樹。

(2)依據前序遍歷序列來序列化二叉樹,因為前序遍歷序列是從根結點開始的。當在遍歷二叉樹時碰到Null指針時,這些Null指針被序列化為一個特殊的字符“#”。另外,結點之間的數值用逗號隔開。

3、代碼實現:

public class Test20 {//序列化String Serialize(TreeNode root) {StringBuffer sb = new StringBuffer();if(root == null){sb.append("#,");return sb.toString();}sb.append(root.val+",");sb.append(Serialize(root.left));sb.append(Serialize(root.right));return sb.toString();}public int index = -1;int len =0;//反序列化TreeNode Deserialize(String str) {String[] strArray = str.split(",");len = str.length();return Deserialize2(strArray,str);}TreeNode Deserialize2(String[] strArray,String str){index++;TreeNode node = null;if(!strArray[index].equals("#")){node = new TreeNode(Integer.valueOf(strArray[index]));node.left = Deserialize2(strArray,str);node.right = Deserialize2(strArray,str);}return node;} }class TreeNode {int val = 0;TreeNode left = null;TreeNode right = null;public TreeNode(int val) {this.val = val;} }

?

二、二叉搜索樹的第k個節點:

1、題目:

給定一棵二叉搜索樹,請找出其中的第k小的結點。例如, (5,3,7,2,4,6,8)? ? 中,按結點數值大小順序第三小結點的值為4。

2、解題思路:

使用中序遍歷找到第k個節點。

3、代碼實現:

public class Test21 {/*如果沒有if(node != null)這句話 那么那個root就是返回給上一級的父結點的,而不是遞歸結束的條件了,有了這句話過后,一旦返回了root,那么node就不會為空了,就一直一層層的遞歸出去到結束了。舉第一個例子{8,6,5,7},1 答案應該是5,如果不加的時候,開始,root=8,node=kth(6,1),繼續root=6,node=kth(5,1)root =5 返回null,這時向下執行index=k=1了,返回 5給root=6遞歸的時候的node,這時回到root=8了,往后面調右孩子的時候為空而把5給覆蓋了。現在就為空了,有了這句話后雖然為空,但不把null返回,而是繼續返回5,*/int index = 0;TreeNode KthNode(TreeNode pRoot, int k){if(pRoot != null){//中序遍歷尋找第k個TreeNode node = KthNode(pRoot.left,k);if(node != null){return node;}index++;if(index == k){return pRoot;}node = KthNode(pRoot.right,k);if(node != null){return node;}}return null;} }class TreeNode {int val = 0;TreeNode left = null;TreeNode right = null;public TreeNode(int val) {this.val = val;} }

?

三、數據流中的中位數:

1、題目:

如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那么中位數就是所有數值排序之后位于中間的數值。如果從數據流中讀出偶數個數值,那么中位數就是所有數值排序之后中間兩個數的平均值。我們使用Insert()方法讀取數據流,使用GetMedian()方法獲取當前讀取數據的中位數。

2、解題思路:

使用一個大頂堆和一個小頂堆,維持大頂堆的數都小于等于小頂堆的數,且兩者的個數相等或差1。平均數就在兩個堆頂的數之中。

3、代碼實現:

public class Test23 {private int count = 0;//默認最小堆private PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(11,new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}});public void Insert(Integer num) {if(count %2 == 0){//當數據總數為偶數是,新加入的元素,應當進入小根堆,//(主意不是直接進入小跟堆,而是經過大根堆篩選后去大根堆中最大元素進入小根堆)//1、新加入的元素先入到大根堆,由大根堆篩選出堆中最大的元素maxHeap.offer(num);int filteredMaxNum = maxHeap.poll();//2.篩選后的 大根堆中的最大元素 進入小跟堆minHeap.offer(filteredMaxNum);}else{//當數據總數為奇數時,新加入的元素,應當進入大根堆//(注意不是直接進入大根堆,而是經小根堆篩選后取小根堆中最大元素進入大根堆)//1.新加入的元素先入到小根堆,由小根堆篩選出堆中最小的元素minHeap.offer(num);int filteredMinNum = minHeap.poll();//2.篩選后的【小根堆中的最小元素】進入大根堆maxHeap.offer(filteredMinNum);}count++;}public Double GetMedian() {if(count % 2 == 0 ){return new Double((minHeap.peek()+maxHeap.peek()))/2;}else{return new Double(minHeap.peek());}} }

?

四、滑動窗口的最大值:

1、題目:

給定一個數組和滑動窗口的大小,找出所有滑動窗口里數值的最大值。例如,如果輸入數組{2,3,4,2,6,2,5,1}及滑動窗口的大小3,那么一共存在6個滑動窗口,他們的最大值分別為{4,4,6,6,6,5}; 針對數組{2,3,4,2,6,2,5,1}的滑動窗口有以下6個: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

2、解題思路:

用一個雙端隊列,隊列第一個位置保存當前窗口的最大值,當窗口滑動一次,進行下面的兩個判斷:
(1)判斷當前最大值是否過期;
(2)新增加的值從隊尾開始比較,把所有比他小的值丟掉。

3、代碼實現:

public class Test22 {public ArrayList<Integer> maxInWindows(int [] num, int size){ArrayList<Integer> result = new ArrayList<Integer>();if(size == 0){return result;}int begin;//建立一個雙端隊列,注意:隊列中存放的是下標ArrayDeque<Integer> queue = new ArrayDeque<Integer>();for(int i =0;i<num.length;i++){begin = i-size+1;//滑動窗口的起始位置。if(queue.isEmpty()){queue.add(i);}else if(begin>queue.peekFirst()){queue.pollFirst();}while( !queue.isEmpty() && num[queue.peekLast()]<=num[i]){queue.pollLast();}queue.add(i);if(begin>=0){result.add(num[queue.peekFirst()]);}}return result;} }

?

總結

以上是生活随笔為你收集整理的《剑指offer》-- 序列化二叉树、二叉搜索树的第k个节点、数据流中的中位数、滑动窗口的最大值的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。