剑指offer-字符的所有组合,复制复杂链表,二叉树中和为某一值的路径

Posted void-lambda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer-字符的所有组合,复制复杂链表,二叉树中和为某一值的路径相关的知识,希望对你有一定的参考价值。

字符的所有组合

描述:

输入一个字符串,求这个字符串中的字符的所有组合。如:“abc”,组合为"a" "b" c" "ab" "ac" "bc" "abc"

思路:

对于n个字符,求长度为m的组合,将字符分为两部分,对于当前的字符,要么取,然后再n-1个字符中取m-1个,要么不取,在n-1个字符中取m个。

代码:

void combination(string s, int num, vector<char>res);
void combination(string s)
{
    if (s.empty())
        return;
    vector<char> res;
    int number = s.size();
    for (int i = 1; i <= number; i++) //组合长度
    {
        combination(s,i, res);
    }
}
void combination(string s, int num, vector<char>res)
{
    if (num == 0)  //递归出口
    {
        static int n = 1;
        cout << "这是第" << n << "个组合" << endl;
        n++;
        vector<char>::iterator it;
        for (it = res.begin(); it != res.end(); it++)
        {
            cout << *it;
        }
        cout << endl;
        return;
    }
    if (s.size() == 0)
        return ;
    res.push_back(s[0]);
    s = s.assign(s,1, s.size() - 1);
    
    combination(s, num - 1, res); //要么加入这个字符,在接下来的字符串中找num-1个字符
    res.pop_back();
    combination(s, num , res); // 要么不加入这个字符,在接下来的字符串中找num个字符。
}

复制复杂链表

描述:

复制一个复杂的链表,链表节点除了next指针,还有随机的指针指向NULL或任意节点。

思路:

分解问题。第一步,在每个节点后复制一个原节点,并用next链接。第二步,链接随机指针,每个复制的节点的随即指针的指向都是前一个节点的随机指针指向的节点的后一个节点。
最后,分离链表。

代码:

struct CpxListNode
{
    int v;
    CpxListNode* next;
    CpxListNode* sibing;
};
void CloneNodes(CpxListNode* head)
{
    
    CpxListNode* p = head;
    while (p)
    {
        CpxListNode* cp = new CpxListNode;
        cp->v = p->v;
        cp->sibing = NULL;
        cp->next = p->next;
        p->next = cp;
        p = cp->next;
        
    }
}
void ConnectSibing(CpxListNode* head)
{
    CpxListNode* p = head;
    while(p)
    {
        CpxListNode* cp = p->next;
        if(p->sibing)
        cp->sibing = p->sibing->next;
        p = cp->next;
        

    }
}
CpxListNode* ReConnect(CpxListNode* head)
{
    CpxListNode* chead=NULL;
    CpxListNode* p=head;
    CpxListNode* cp = NULL;
    if (p)
    {
        chead = p->next;
        cp = chead;

    }
    while (p)
    {
        p->next = cp->next;
        p = p->next;
        cp->next = p->next;
        cp = cp->next;
    }
    return chead;
}
CpxListNode* CopyCL(CpxListNode* head)
{  
    CloneNodes(head);   //将复制后的节点插入原节点后面
    ConnectSibing(head);   //sibing指针的处理
    return ReConnect(head);   //分离链表


}

二叉树中和为某一值的路径

描述:

对于给定值k,要求在二叉树中找到一条路径,路径上的节点值和为k。

思路:

先序遍历整个树,用栈来记录路径,采用递归的思想,当走到一个节点,当前的和为num,若它是叶子节点,则找到一条路径。否则再从它的左右子树中找。

代码:

void Findpath(TreeNode* root, int num, vector<int> path, int currentsum)
{
    currentsum += root->v;
    path.push_back(root->v);
    if ((currentsum == num) && (root->left == NULL && root->right == NULL))
    {
        cout << "FIND" << endl;
        for (int i = 0; i < path.size(); i++)
        {
            cout << path[i];
        }
    }
    else
    {
        if (root->left != NULL)
        {
            Findpath(root->left, num, path, currentsum);
        }
        if (root->right)
        {
            Findpath(root->right, num, path, currentsum);
        }
        /*currentsum -= root->v;
        path.pop_back();*/
        //这边不用对currentsum和path操作,因为它们作为变量传入,返回时自动恢复,如果它们作为静态变量,则需要手动恢复。
    }
}
void FindInTree(TreeNode* root, int num)
{
    if (root == NULL)
    {
        return;
    }
    int currcentsum = 0;
    vector<int> path;
    Findpath(root, num, path, currcentsum);
}

以上是关于剑指offer-字符的所有组合,复制复杂链表,二叉树中和为某一值的路径的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer题目分类

《剑指offer》JZ21 ~ JZ30

《剑指offer》JZ21 ~ JZ30

《剑指offer》JZ21 ~ JZ30

《剑指offer》JZ21 ~ JZ30

剑指offer二十五之二叉搜索树与双向链表