劍指offer:DAY4

***題目描述:二叉搜索樹與雙向鏈表

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。

class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        //bst的排序
        //左結點《根結點《右結點 
        //左葉子結點指向父結點,再指向右葉子結點
        //遞歸左-》子樹根-》遞歸右
        if(pRootOfTree==NULL)
            return NULL;
        
        TreeNode* pointer=NULL;
        digui(pRootOfTree,pointer);
        while(pointer->left!=NULL)
            pointer=pointer->left;
        
        return pointer;
    }
    //遞歸最左邊,建立雙向連接,再遞歸右邊
    void digui(TreeNode* pRoot,TreeNode *&pointer)
    {
        if(pRoot==NULL)
            return ;
        if(pRoot->left!=NULL)
        {
            digui(pRoot->left,pointer);//遞歸左
        }
        pRoot->left = pointer;//建立連接
        if(pointer!=NULL)
        {
            pointer->right=pRoot;//建立連接
        }
        pointer=pRoot;//子樹根
        if(pRoot->right!=NULL)
        {
            digui(pRoot->right,pointer);//遞歸右
        }
    }
};

***

題目描述:類字典序

輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。

class Solution {
public:
    vector<string> result;
    vector<string> Permutation(string str) {
        if(str.length()==0)
            return result;
        zidian(str,0);
        sort(result.begin(),result.end());
        return result;
        
    }
    void zidian(string str,int begin)
    {
        if(begin==(str.length()-1))
        {
            result.push_back(str);
            return;
        }
        for(int i=begin;str[i]!='\0';i++)
        {
            if(i!=begin&&str[begin]==str[i])
                continue;
            swap(str[begin],str[i]);
            zidian(str,begin+1);
            swap(str[begin],str[i]);

        }
    }
    
};

題目描述:連續子數組的最大和

HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全爲正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和爲8(從第0個開始,到第3個爲止)。給一個數組,返回它的最大連續子序列的和,你會不會被他忽悠住?(子向量的長度至少是1)

解答思路:不難,但得找到思路:如果前面的數加起來小於現在要加的數,那麼拋棄前面的數,從現在的數開始加

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
    //如果前面的數加起來小於現在要加的數,那麼拋棄前面的數,從現在的數開始加
        int record=array[0];
        int max=array[0];
        for(int i=1;i<array.size();i++)
        {
            record+=array[i];
            if(record<array[i])
                record=array[i];
            if(record>max)
                max=record;
        }
        return max;
    }
};

題目描述:把數組排成最小的數

輸入一個正整數數組,把數組裏所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字爲321323。

解題思路:比較後的相對位置不變

class Solution {
public:
    string PrintMinNumber(vector<int> numbers) {
        
        string str;
        int len=numbers.size();
        if(len==0)
            return str;
        sort(numbers.begin(),numbers.end(),cmp);
        for(int i=0;i<len;i++)
            str=str+to_string(numbers[i]);
        return str;
    }
    
    static bool cmp(int a,int b)
    {
        string A=to_string(a)+to_string(b);
        string B=to_string(b)+to_string(a);
        return A<B;
    }
    
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章