nowcoder

二叉樹重建(給定前序司倚、中序遍歷的結(jié)果)

#include <iostream>
#include <vector>
using namespace std;
struct TreeNode{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x):val(x),left(NULL),right(NULL){};
};
TreeNode* rebuild(vector<int> preOrder, vector<int> inOrder){
    if(preOrder.empty()||inOrder.empty()){
        return NULL;
    }
    // vector<int>::iterator it;
    // // cout<<"pre"<<endl;
    // for(it=preOrder.begin();it!=preOrder.end();it++){
    //     cout<<*it<<" ";
    // }
    // cout<<endl<<"in"<<endl;
    // for(it=inOrder.begin();it!=inOrder.end();it++){
    //     cout<<*it<<" ";
    // }
    // cout<<endl;
    int idx_find = 0;
    for(idx_find=0;idx_find<inOrder.size();idx_find++){
        if(inOrder[idx_find]==preOrder[0]) break;
    }
    // cout<<"idx:"<<idx_find<<endl;
    // cout<<"val:"<<inOrder[idx_find]<<endl;
    TreeNode* root = new TreeNode(preOrder[0]);

    vector<int> preLeft(preOrder.begin()+1,preOrder.begin()+idx_find+1);//(begin,end) end is not in vector
    vector<int> preRight(preOrder.begin()+idx_find+1,preOrder.end());
    vector<int> inLeft(inOrder.begin(),inOrder.begin()+idx_find);
    vector<int> inRight(inOrder.begin()+idx_find+1,inOrder.end());
    root->left = rebuild(preLeft,inLeft);
    root->right = rebuild(preRight,inRight);
    return root;
}
int main(){
    int pre[] = {1,2,4,7,3,5,6,8};
    int in[] = {4,7,2,1,5,3,8,6};
    vector<int> preOrder(pre,pre+sizeof(pre)/sizeof(int));
    vector<int> inOrder(in,in+sizeof(in)/sizeof(int));
    TreeNode* reBiTree=rebuild(preOrder,inOrder);
}

要對比兩個序列,找到根篓像,劃分為左右子樹动知,再遞歸建立左右子樹
注意用iterator生成vector時第二個參數(shù)的指向的元素不進入vector
注意無左右子樹時返回NULL

2 stacks mock queue

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
        while(!stack1.empty()){
            stack2.push(stack1.top());
            stack1.pop();
        }
        int ret = stack2.top();
        stack2.pop();
        while(!stack2.empty()){
            stack1.push(stack2.top());
            stack2.pop();
        }
        return ret;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

push沒啥特別,隊列的pop在頭上员辩,把stack的元素倒到另一個棧盒粮,然后pop然后倒回。相當于彈出棧底元素

旋轉(zhuǎn)數(shù)組找最小值

把一個數(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

暴力法不考慮。使用改進二分法

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int first=0,last=rotateArray.size()-1,mid;
        
        while(first<last){
            mid = (first+last)/2;
            if(rotateArray[mid]>rotateArray[last]){
                first = mid+1;
                //mid = (first+last)/2;
            }
            else if(rotateArray[mid]<rotateArray[last]){
                last = mid;
            }
            else{
                last--;
            }
        }
        return rotateArray[last];
    }
};

旋轉(zhuǎn)前數(shù)組可以是0淆攻,0阔墩,1,1瓶珊,1啸箫,2,4
比較難理解mid 和target處數(shù)字相等的情況

青蛙跳臺階問題


519966841.jpg

二進制問題
正數(shù)右移最終為0
負數(shù)右移伞芹,保持負數(shù)(首位為1)最終為-1
正數(shù)左移不保持正數(shù)(1左移31變最小負數(shù))
負數(shù)左移不保持負數(shù)忘苛,有正有負

求double base 的整數(shù)次方
注意指數(shù)為負數(shù)的時候

c++ STL copy()
copy(iterator start, iterator end, container.begin())

求鏈表倒數(shù)第k個元素
普通解法:遍歷求長度蝉娜,再減k再循環(huán)定位到目標位置
優(yōu)化:使用快慢指針方法,讓快指針先走k步扎唾,然後快慢指針同時走直到快指針到達尾部

ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        if(!pListHead)    return NULL;
        ListNode* p=pListHead, *q=pListHead;
        while(k--){
            if(p){
                p = p->next;
            }
            else return NULL;
        }
        //if(p!=NULL||k!=0)    return NULL;
        while(p){
            p = p->next;
            q = q->next;
        }
        return q;
}

反轉(zhuǎn)鏈表
普通解法:通過開辟新vector
優(yōu)化:不開辟新空間召川。用一個指針正向遍歷鏈表,將每個元素拉出來加入到反轉(zhuǎn)鏈表的頭部胸遇。ret指針指向反轉(zhuǎn)鏈表(tmp)頭部荧呐,一個指針指向正向遍歷指針的下一個元素,因為否則取走之后找不到頭了纸镊。

ListNode* ReverseList(ListNode* pHead) {
        ListNode *ret, *node, *nextNode;
        ret = NULL;
        node = pHead;
        nextNode = pHead->next;
        while(node){          
            node->next = ret;
            ret = node;
            node = nextNode;
            nextNode = nextNode->next;
        }
        return ret;
    }

合并兩個有序鏈表

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
//        if(!pHead1){
//            return pHead2;
//        }
//        if(!pHead2){
//            return pHead1;
//        }
//        ListNode* ret, *p;
//        bool flag = true;
//       while(pHead1&&pHead2){
//            int less;
//            if((pHead1->val) <= (pHead2->val)){
//                less = pHead1->val;
//                pHead1 = pHead1->next;
//            }
//            else{
//                less = pHead2->val;
//                pHead2 = pHead2->next;
//            }
            //int less = pHead1->val <= pHead2->val ? pHead1->val : pHead2->val;
//            ListNode* t = new ListNode(less);
//            if(flag){
//                ret = t;
//                p = ret;
//                flag = false;
//            }
//            else{
//                p->next = t;
//                p = p->next;
//            }
        
 //       }
//        if(pHead1){
//            p->next = pHead1;
//        }else if(pHead2){
//            p->next = pHead2;
//        }
//        return ret;    
    }
};

很自然的解法倍阐。
還有遞歸方法,我沒寫逗威,先貼著

class Solution {
public:
 ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
 {
     if (!pHead1) return pHead2;
     if (!pHead2) return pHead1;
     if (pHead1->val <= pHead2->val) {
         pHead1->next = Merge(pHead1->next, pHead2);
         return pHead1;
     }
     else {
         pHead2->next = Merge(pHead1, pHead2->next);
         return pHead2;
     }
 }
};

很簡潔收捣,我什么時候才能如此簡潔..

24 Sep
判斷樹b是否為樹a的子樹

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    bool dfs(TreeNode* r1, TreeNode* r2){
        if(!r2)    return true;
        if(!r1)    return false;
        return r1->val==r2->val && dfs(r1->left,r2->left) && dfs(r1->right,r2->right);
    }
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        
        if(pRoot1==NULL||pRoot2==NULL)    return false;
        if (HasSubtree(pRoot1->left, pRoot2))    return true;
        if (HasSubtree(pRoot1->right, pRoot2)) return true;
      
        return dfs(pRoot1,pRoot2);
    }
};

官方解釋,在hasSubtree中庵楷,返回深度遍歷的結(jié)果||左子樹判斷||右子樹判斷,heuristic楣颠。我的if-if-return其實是靠dfs在return 吧

return dfs(pRoot1, pRoot2) || HasSubtree(pRoot1->left, pRoot2) ||
    HasSubtree(pRoot1->right, pRoot2);

25 Sep
順時針打印矩陣
做了半天尽纽,原來還能打印矩形的矩陣。童漩。寫不動了弄贿,看看答案吧

class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        int r = matrix.size(), c = matrix[0].size();//行和列
        vector<int> result;
        if (r == 0 || c == 0)
            return result;
        int left = 0, right = c - 1;
        int top = 0, bottom = r - 1;
        while (left <= right && top <= bottom)
        {
            //從左到右輸出第一行
            for (int i = left; i <= right; i++)
            {
                //將一個新的元素添加到最后面
                result.push_back(matrix[top][i]);
            }
            //從上到下,不包括第一行最后一個數(shù)矫膨,即top+1
            for (int i = top + 1; i <= bottom; i++)
            {
                result.push_back(matrix[i][right]);
            }
            //從右到左差凹,不包括最后一行最后一個數(shù),即right-1
            if (top != bottom)
                for (int i = right - 1; i >= left; i--)
                {
                    result.push_back(matrix[bottom][i]);
                }
            //從下到上侧馅,不包括最后一行最后一個數(shù)和第一行第一個數(shù)
            if (left != right)
                for (int i = bottom - 1; i >= top + 1; i--)
                {
                    result.push_back(matrix[i][left]);
                }
                left++, top++, right--, bottom--;
        }
        return result;
    }
};

尋找棧中最小元素危尿,且時間復雜度為1
看解答才知道怎么回事,用一個輔助棧存normal棧更新時最小元素馁痴,查詢min時彈出輔助棧的棧頂即可谊娇。

class Solution {
public:
    stack<int> normal,minval;
    void push(int value) {
        normal.push(value);
        if(minval.empty())  minval.push(value);
        else if(value<minval.top()){
            minval.push(value);
        }
    }
    void pop() {
        if(normal.top()==minval.top()){
            minval.pop();
        }
        normal.pop();
    }
    int top() {
        return normal.top();
    }
    int min() {
        return minval.top();
    }
};

輔助棧真是

判斷出棧順序是否正確

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        
        vector<int>::iterator it,pre;
        stack<int> normal;
        it = find(pushV.begin(),pushV.end(),popV[0]);
        if(it==pushV.end()){
            return false;
        }
        pushV.erase(it);
        pre = it-1;
        for(int i=1;i<popV.size();i++){
        // if(popV[i]!=(*pre)&&popV[i]!=(*it)) return false;
        if(popV[i]!=(*pre)){
            bool hasAfter = false;
            while(it!=pushV.end()){
                if(*it == popV[i])  {
                    hasAfter = true;
                    break;
                }
                it++;
            }
            if(!hasAfter)return false;
            pushV.erase(it);    
            pre = it-1;
        }
        else {
            it = find(pushV.begin(),pushV.end(),popV[i]);
            pushV.erase(it);
            if(it-pushV.begin()==0){
                pre = it+1;
                continue;
            }
            pre = it-1;
        }
    }
    return true;
    }
};

按層從左到右打印二叉樹節(jié)點

vector<int> PrintFromTopToBottom(TreeNode* root) {    
        deque<TreeNode *> q;
        vector<int> ret;
        if(!root)    return ret;
        q.push_back(root);
        while(!q.empty()){
            TreeNode* tmp=q.front();
            ret.push_back(tmp->val);
            if(tmp->left)    q.push_back(tmp->left);
            if(tmp->right)    q.push_back(tmp->right);
            q.pop_front();
        }
        return ret;
    }

將根節(jié)點加入到隊列q中,取隊列頭罗晕,將其左右子樹加入隊列济欢,隊列頭加入返回向量中

判斷一個序列是不是二叉搜索樹后序遍歷結(jié)果

bool VerifySquenceOfBST(vector<int> sequence) {
        int n=sequence.size();
        if(n==0) return false;
        int j=0;
        for(int i=n-1;i>0;i--)
        {
            while(sequence[j]<sequence[i]) j++;
            while(sequence[j]>sequence[i]) j++;
            if(j<i) return  false;
            j=0;
        }
        return true;
    }

這是什么騷操作,看不懂

bool VerifySquenceOfBST(vector<int> sequence) {
        if(sequence.size()==1)  {
            return true;
        }
        int root = sequence.back();
        int idx=0;
        for(idx;idx<sequence.size();idx++){
            if(sequence[idx]>root)    break;
        }
        if(idx==0)  return true;
        for(int i=0;i<idx;i++){
            if(sequence[i]>root)    return false;
        }
        for(int i=idx;i<sequence.size();i++){
            if(sequence[i]<root)    return false;
        }
        vector<int> left(sequence.begin(),sequence.begin()+idx);
        vector<int> right(sequence.begin()+idx,sequence.end());
        if(VerifySquenceOfBST(left)&&VerifySquenceOfBST(right))    return true;
        return false;
    }

我寫的小渊,平臺報內(nèi)存超了不通過

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末法褥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子酬屉,更是在濱河造成了極大的恐慌半等,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異酱鸭,居然都是意外死亡吗垮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門凹髓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烁登,“玉大人,你說我怎么就攤上這事蔚舀《祝” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵赌躺,是天一觀的道長狼牺。 經(jīng)常有香客問我,道長礼患,這世上最難降的妖魔是什么是钥? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮缅叠,結(jié)果婚禮上悄泥,老公的妹妹穿的比我還像新娘。我一直安慰自己肤粱,他們只是感情好弹囚,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著领曼,像睡著了一般鸥鹉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上庶骄,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天毁渗,我揣著相機與錄音,去河邊找鬼单刁。 笑死祝蝠,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的幻碱。 我是一名探鬼主播绎狭,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼褥傍!你這毒婦竟也來了儡嘶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤恍风,失蹤者是張志新(化名)和其女友劉穎蹦狂,沒想到半個月后誓篱,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡凯楔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年窜骄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摆屯。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡邻遏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出虐骑,到底是詐尸還是另有隱情准验,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布廷没,位于F島的核電站糊饱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏颠黎。R本人自食惡果不足惜另锋,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望狭归。 院中可真熱鬧砰蠢,春花似錦、人聲如沸唉铜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潭流。三九已至,卻和暖如春柜去,著一層夾襖步出監(jiān)牢的瞬間灰嫉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工嗓奢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留讼撒,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓股耽,卻偏偏與公主長得像根盒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子物蝙,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354