leetcode剑指 Offer 专项突击版(23、047、028、036)

简介: leetcode剑指 Offer 专项突击版(23、047、028、036)

23.合并K个升序链表


题目描述:

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例:

7.png

思路:

对于k个升序链表合并,先想到两个升序链表合并。然后加入归并排序的思想,划分到两两排序,在逐级合并。

通过代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        int len = lists.size();
        return merge(lists,0,len-1);
    }
    ListNode* merge(vector<ListNode*>& lists,int l,int r)
    {
        if(l == r) return lists[l];
        if(l > r) return nullptr;
        int mid = (l + r)/2;
        return mergeTwoLists(merge(lists,l,mid),merge(lists,mid+1,r)); //熟悉又不熟悉的归并
    }
    ListNode* mergeTwoLists(ListNode* l1,ListNode* l2)
    {
        if(l1 == nullptr || l2 ==nullptr)
        {
            return l1 ? l1 : l2;
        }
        ListNode *a,*b;
        a = l1;
        b = l2;
        ListNode head;
        ListNode* c = &head; //这里 忘记malloc咋用了 要死
        while(a != nullptr && b != nullptr)
        {
            if(a->val < b->val)
            {
                c->next = a;
                a = a->next;
            }
            else
            {
                c->next = b;
                b = b->next;
            }
            c = c->next;
        }
        if(a != nullptr)
        {
            c->next = a;
        }
        if(b != nullptr)
        {
            c->next = b; 
        }
        return head.next;
    }
};


剑指 Offer II 047. 二叉树剪枝


题目描述:

给定一个二叉树 根节点 root ,树的每个节点的值要么是 0,要么是 1。请剪除该二叉树中所有节点的值为 0 的子树。

节点 node 的子树为 node 本身,以及所有 node 的后代。

示例:

8.png

思路:

  后序遍历的思想,看左子树,再看右子树。
  对于叶子结点来判断是否为0,进行剪枝操作。这里注意root是一个临时变量,不能在if语句里面令root等于nullptr,再返回root。这里与下一题,链表结点里面的res那里使用一致,当进入dfs函数后,res保存的东西就会丢失。

通过代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* pruneTree(TreeNode* root) {
        if(root == nullptr)
            return nullptr;
        TreeNode* left = pruneTree(root->left);
        TreeNode* right = pruneTree(root->right);
        if(root->val == 0 && left == nullptr && right == nullptr)
        {         
            return nullptr;
        }
        root->left = left;
        root->right = right;
        return root;
    }
};


剑指 Offer II 028. 展平多级双向链表


题目描述:

多级双向链表中,除了指向下一个节点和前一个节点指针之外,它还有一个子链表指针,可能指向单独的双向链表。这些子列表也可能会有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。


给定位于列表第一级的头节点,请扁平化列表,即将这样的多级双向链表展平成普通的双向链表,使所有结点出现在单级双链表中。

示例:

4031c3161e104a11902a370f3655370b.png

acef64a76bc843ac8e648429ea211b7f.png

思路:

深度优先搜索,对于dfs到最深处返回的是当前的最后一个结点,而不是有孩子结点的下一个结点。有孩子结点就要进行一次深度优先搜索,然后找到的child_结点指向,孩子结点的next结点。

通过代码:

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* prev;
    Node* next;
    Node* child;
};
*/
class Solution {
public:
    Node* res;
    Node* dfs(Node* head){
        if(head == nullptr)
        {
            return nullptr;
        }
        Node* pre = head;
        Node* last = nullptr;
        while(pre != nullptr)
        {
            // res = pre->next;
            if(pre->child == nullptr)
            {
                last = pre;
                pre = pre->next;
            }
            else{
                Node *child_ = dfs(pre->child);
                // printf("%d",res->val);
                res = pre->next;
                pre->next = pre->child;
                pre->child->prev = pre;
                pre->child = nullptr;
                // child_->prev = pre;
                if(res != nullptr)
                {
                    child_->next = res;
                    res->prev = child_;
                }
                last = child_;
                pre = res;
            }
            // pre = res;
        }
        return last;
    }
    Node* flatten(Node* head) {
        if(head == nullptr)
        {
            return nullptr;
        }
        dfs(head);
        return head;
    }
};


剑指 Offer II 036. 后缀表达式


题目描述:

根据 逆波兰表示法,求该后缀表达式的计算结果。

有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。

给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

3af3601d9d1646738bdc36f94a845064.png

思路:

栈的应用+小细节c++里的switch参数要求

通过代码:

//注意:c++只能字符或者整型,java的switch就能不用整数类型了
class Solution {
public:
    vector<string> s {"+","-","*","/"};
    stack<int> mystack;
    int evalRPN(vector<string>& tokens) {
        int len = tokens.size();
        int a,b,c;
        for(string i:tokens)
        {
            // cout<<tokens[i]<<endl;
            if(count(s.begin(), s.end(), i))
            {
                // char c = char(i);
                b = mystack.top();
                mystack.pop();
                a = mystack.top();
                mystack.pop();
                // switch(int(i)){
                if (i == "+")
                    c = a + b;
                    // break;
                else if (i =="-")
                    c = a - b;
                    // break;
                else if (i == "*")
                    c = a * b;
                    // break;
                else if (i == "/")
                    c = a / b;
                    // break;
                // }
                mystack.push(c);
            }
            else
            {
                mystack.push(stoi(i));
            }
        }
        return mystack.top();
    }
};
相关文章
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
63 6
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
55 4
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 49. 丑数
解决剑指 Offer 49题"丑数"的Python实现,通过动态规划的方法计算出第n个丑数。
46 2
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 04. 二维数组中的查找
剑指Offer题目 "二维数组中的查找" 的Python解决方案,包括非递归迭代、递归以及使用内置函数的二分查找方法,以判断一个有序的二维数组中是否含有给定整数。
39 1
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 03. 数组中重复的数字
解决剑指Offer题目 "数组中重复的数字" 的Python实现方法,通过使用字典来记录数组中每个数字的出现次数,快速找出重复的数字。
41 1
|
4月前
|
iOS开发 MacOS
【Mac系统】解决Vscode中LeetCode插件不能刷剑指offer题库
文章讨论了解决Mac系统中Vscode里LeetCode插件无法刷剑指Offer题库的问题,并提供了一些相关的使用技巧和资源链接。
257 1
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
55 5
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
33 4
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
Leetcode题目"剑指 Offer 21. 调整数组顺序使奇数位于偶数前面"的两种Python解决方案,一种是使用双端队列调整数组顺序,另一种是使用双指针法将奇数移到数组前半部分,偶数移到后半部分。
29 4
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
46 4