构造数组MaxTree、环形单链表的约瑟夫问题等总结
生活随笔
收集整理的這篇文章主要介紹了
构造数组MaxTree、环形单链表的约瑟夫问题等总结
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1.構(gòu)造數(shù)組的MaxTree
定義二叉樹(shù)節(jié)點(diǎn)如下:
public class Node{
public int value;
public Node left;
public Node right;
public Node (int data){
this.value = data;
}
}
一個(gè)數(shù)組的MaxTree定義如下:
數(shù)組必須沒(méi)有重復(fù)元素,MaxTree是一棵二叉樹(shù),數(shù)組的每一個(gè)值對(duì)應(yīng)一個(gè)二叉樹(shù)的節(jié)點(diǎn),包括MaxTree樹(shù)在內(nèi)且在其中的每一棵子樹(shù)上,值最大的節(jié)點(diǎn)都是樹(shù)的頭。給定一個(gè)沒(méi)有重復(fù)元素的數(shù)組arr,寫(xiě)出生成這個(gè)數(shù)組的MaxTree的函數(shù),要求如果數(shù)組長(zhǎng)度為N,則時(shí)間復(fù)雜度為O(N),額外空間復(fù)雜度為O(N)
思路:找一個(gè)數(shù)左邊離它最近的比它大的,還有右邊一個(gè)比他大的,即可實(shí)現(xiàn)MaxTree。建立一個(gè)大底棧,對(duì)于任何一個(gè)數(shù),當(dāng)它從棧中彈出時(shí),當(dāng)前將要入棧的數(shù)是彈出的數(shù)的右邊離他最近的比他大的數(shù),而它棧中下面的數(shù)是離他最近的左邊比他大的數(shù)
2.最大值減去最小值小于或等于num的子數(shù)組數(shù)量
給定數(shù)組arr和整數(shù)num,共返回有多少個(gè)子數(shù)組滿足以下情況:
max(arr[i...j]) - min(arr[i...j]) <= num
max(arr[i...j])表示子數(shù)組arr[i...j]中的最大值,min(arr[i...j])表示子數(shù)組arr[i...j]中的最小值
要求:如果數(shù)組長(zhǎng)度為N,求實(shí)現(xiàn)時(shí)間復(fù)雜度為O(N)的解法
建立一個(gè)雙端隊(duì)列,用于求出最大值和最小值,有兩個(gè)指針,都從數(shù)組頭開(kāi)始向右滑動(dòng),維持一個(gè)遞增的隊(duì)列,此隊(duì)列中存儲(chǔ)的是數(shù)組的下標(biāo)。如果隊(duì)列右邊比現(xiàn)在隊(duì)尾小的話,依次將隊(duì)列中的尾部從右彈出,直到可以將當(dāng)前值右側(cè)入隊(duì)。
3.環(huán)形單鏈表的約瑟夫問(wèn)題
41個(gè)人圍成一個(gè)環(huán),由第一人開(kāi)始報(bào)數(shù),報(bào)到3的人即自殺,然后再由下一任重新報(bào)1,報(bào)到3的人再自殺,依次類推,直到剩下最后一個(gè)人?,F(xiàn)用單向環(huán)形鏈表描述該結(jié)構(gòu)并呈現(xiàn)整個(gè)自殺過(guò)程
輸入:一個(gè)環(huán)形單向鏈表的頭節(jié)點(diǎn)head和報(bào)數(shù)的值m
返回:最后生存下來(lái)的節(jié)點(diǎn),且這個(gè)節(jié)點(diǎn)自己組成環(huán)形單向鏈表,其他節(jié)點(diǎn)都刪除
要求:如果鏈表節(jié)點(diǎn)數(shù)為N,實(shí)現(xiàn)時(shí)間復(fù)雜度為O(N)的解法
public static Node josephusKill(Node head, int m){if(head == null || head.next == head || m < 1){return head;}Node cur = head.next;int tmp = 1; //ListSizewhile(cur != head){tmp++;cur = cur.next;}tmp = getLive(tmp, m);while(--tmp != 0){head = head.next;}head.next = head;return head; } public static int getLive(int i, int m){if(i == 1){return 1;}return (getLive(i - 1, m) + m - 1) % i + 1; } public static void printCircularList(Node head){if(head == null){return;} }
定義二叉樹(shù)節(jié)點(diǎn)如下:
public class Node{
public int value;
public Node left;
public Node right;
public Node (int data){
this.value = data;
}
}
一個(gè)數(shù)組的MaxTree定義如下:
數(shù)組必須沒(méi)有重復(fù)元素,MaxTree是一棵二叉樹(shù),數(shù)組的每一個(gè)值對(duì)應(yīng)一個(gè)二叉樹(shù)的節(jié)點(diǎn),包括MaxTree樹(shù)在內(nèi)且在其中的每一棵子樹(shù)上,值最大的節(jié)點(diǎn)都是樹(shù)的頭。給定一個(gè)沒(méi)有重復(fù)元素的數(shù)組arr,寫(xiě)出生成這個(gè)數(shù)組的MaxTree的函數(shù),要求如果數(shù)組長(zhǎng)度為N,則時(shí)間復(fù)雜度為O(N),額外空間復(fù)雜度為O(N)
思路:找一個(gè)數(shù)左邊離它最近的比它大的,還有右邊一個(gè)比他大的,即可實(shí)現(xiàn)MaxTree。建立一個(gè)大底棧,對(duì)于任何一個(gè)數(shù),當(dāng)它從棧中彈出時(shí),當(dāng)前將要入棧的數(shù)是彈出的數(shù)的右邊離他最近的比他大的數(shù),而它棧中下面的數(shù)是離他最近的左邊比他大的數(shù)
2.最大值減去最小值小于或等于num的子數(shù)組數(shù)量
給定數(shù)組arr和整數(shù)num,共返回有多少個(gè)子數(shù)組滿足以下情況:
max(arr[i...j]) - min(arr[i...j]) <= num
max(arr[i...j])表示子數(shù)組arr[i...j]中的最大值,min(arr[i...j])表示子數(shù)組arr[i...j]中的最小值
要求:如果數(shù)組長(zhǎng)度為N,求實(shí)現(xiàn)時(shí)間復(fù)雜度為O(N)的解法
建立一個(gè)雙端隊(duì)列,用于求出最大值和最小值,有兩個(gè)指針,都從數(shù)組頭開(kāi)始向右滑動(dòng),維持一個(gè)遞增的隊(duì)列,此隊(duì)列中存儲(chǔ)的是數(shù)組的下標(biāo)。如果隊(duì)列右邊比現(xiàn)在隊(duì)尾小的話,依次將隊(duì)列中的尾部從右彈出,直到可以將當(dāng)前值右側(cè)入隊(duì)。
當(dāng)隊(duì)列右邊界在向右移動(dòng)時(shí),隊(duì)列中的最大值只可能越來(lái)越小,左邊界在向右移動(dòng)時(shí),隊(duì)列中的最小值越來(lái)越大。
public static int getNum(int[] arr, int num){if(arr == null || arr.length == 0){return 0;}LinkedList<Integer> qmin = new LinkedList<Integer>();LinkedList<Integer> qmax = new LinkedList<Integer>();int i = 0;int j = 0;int res = 0;while(i < arr.length){while(j < arr.length){while(!qmin.isEmpty() && arr[qmin.peekLast()] >= arr[j]){qmin.pollLast();}qmin.adList(j);while(!qmax.isEmpty() && arr[qmax.peekLast()] <= arr[j]){qmax.polLast();}qmax.addLast(j);if(arr[qmax.getFirst()] - arr[qmin.getFirst()] > num){break;}j++;}if(qmin.peekFirst() == i){qmin.pollFirst();}res += j - i;i++;}return res; }3.環(huán)形單鏈表的約瑟夫問(wèn)題
41個(gè)人圍成一個(gè)環(huán),由第一人開(kāi)始報(bào)數(shù),報(bào)到3的人即自殺,然后再由下一任重新報(bào)1,報(bào)到3的人再自殺,依次類推,直到剩下最后一個(gè)人?,F(xiàn)用單向環(huán)形鏈表描述該結(jié)構(gòu)并呈現(xiàn)整個(gè)自殺過(guò)程
輸入:一個(gè)環(huán)形單向鏈表的頭節(jié)點(diǎn)head和報(bào)數(shù)的值m
返回:最后生存下來(lái)的節(jié)點(diǎn),且這個(gè)節(jié)點(diǎn)自己組成環(huán)形單向鏈表,其他節(jié)點(diǎn)都刪除
要求:如果鏈表節(jié)點(diǎn)數(shù)為N,實(shí)現(xiàn)時(shí)間復(fù)雜度為O(N)的解法
public static Node josephusKill(Node head, int m){if(head == null || head.next == head || m < 1){return head;}Node cur = head.next;int tmp = 1; //ListSizewhile(cur != head){tmp++;cur = cur.next;}tmp = getLive(tmp, m);while(--tmp != 0){head = head.next;}head.next = head;return head; } public static int getLive(int i, int m){if(i == 1){return 1;}return (getLive(i - 1, m) + m - 1) % i + 1; } public static void printCircularList(Node head){if(head == null){return;} }
總結(jié)
以上是生活随笔為你收集整理的构造数组MaxTree、环形单链表的约瑟夫问题等总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 汉诺塔的改编题(用栈求解,分别递归和非递
- 下一篇: 如何复制一个含有随机指针节点的链表