構造數組的MaxTree

題目

一個數組的MaxTree定義:java

  • 數組必須沒有重複元素
  • MaxTree是一棵二叉樹,數組的每個值對應一個二叉樹節點
  • 包括MaxTree樹在內且在其中的每一棵子樹上,值最大的節點都是樹的頭

給定一個沒有重複元素的數組arr,寫出生成這個數組的MaxTree的函數,要求若是數組長度爲N,則時間負責度爲O(N)、額外空間負責度爲O(N)。git

實現思路

  對每個元素,從左邊和右邊各選擇第一個比這個元素大的值,選擇值較小的元素做爲父節點。
  在【生成窗口最大數組】裏面,已經掌握了,在O(N)時間複雜度裏面,找到每一個元素位置最近的比元素大的元素,同個這個套路,就能夠構造一棵MaxTree了。github

證實

1 構造的不是森林
2 是一棵二叉樹數組

證實:1  
  對於每個樹節點,都能往上找到一個節點,直到找到最大節點爲止,這樣全部樹節點都有共同的父節點,這樣構造出來的就是一棵樹。函數

證實:2
  使用反證法解決,若是是一棵二叉樹,那麼對於每一個做爲父節點的元素,可以在元素的一邊找到兩個或兩個以上的元素。存在如:[p, b1, x, b2]這樣的結構,p是父節點、b一、b2爲子節點, x爲其餘節點。code

  • 按照題目,能夠設定:
      p > b1, p > b2
  • 當b1 > b2:
      b2不會選擇p做爲父節點,可能選擇b1做爲父節點.
  • 當b1 < b2:
      當x < b2時,b1不會選擇p做爲父節點,選擇b2做爲父節點.
      當x > b2時,b2不會選擇p做爲父節點,選擇x做爲父節點.

代碼

使用套路獲取從左到右或從右到左第一個比這個元素大的值:get

private List<Integer> getMaxList(List<Integer> valList, boolean reverse){
        //套路
        List<Integer> tMaxItemDeque = new LinkedList<>();
        Stack<Integer> tStackHelper = new Stack<>();

        Integer maxItem;

        Iterator<Integer> iter;
        if(reverse)
            iter = new ReverseListIterator(valList);
        else
            iter = valList.iterator();

        while (iter.hasNext()) {
            Integer item = iter.next();

            maxItem = null;

            while(false == tStackHelper.isEmpty()){
                Integer peekItem = tStackHelper.peek();
                if(peekItem > item)
                {
                    maxItem = peekItem;
                    tStackHelper.push(item);
                    break;
                }

                tStackHelper.pop();
            }

            if(tStackHelper.isEmpty()){
                tStackHelper.push(item);
            }

            tMaxItemDeque.add(maxItem);
        }

        return tMaxItemDeque;
    }

其餘

在github中查看it

相關文章
相關標籤/搜索