剑指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;
    }
    
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值