leetcode剑指 Offer 专项突击版(051、008、016)

简介: leetcode剑指 Offer 专项突击版(051、008、016)

剑指 Offer II 051. 节点之和最大的路径


题目描述:

路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。


路径和 是路径中各节点值的总和。


给定一个二叉树的根节点 root ,返回其 最大路径和,即所有路径上节点值之和的最大值。

示例:

02f0ee547d504e7097360a031e8e2996.png

思路:

这个路径,可以是左子结点 根结点 右子结点。可以不包括root结点!!

不是简单的走完所有的路,求和!

要判断左右子树结点和是否有利于和最大,所以比较这是不是一个比0大的,起正向作用的。

注意,返回值是什么,走到空指针的时候,返回值应该是0,而不是max_num。以及走完一条路,返回的是根节点加左右子树中大的路径和。


代码:

一开始思路错误,求的所有的和,想改前缀和也不对。

/**
 * 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:
    int dfs(TreeNode* root,int& max_num){
        if(root == nullptr)
            return 0;
        int left = max(0,dfs(root->left,max_num));
        int right = max(0,dfs(root->right,max_num));
        max_num = max(root->val + left + right,max_num);
        return root->val + max(left,right);
    }
    int maxPathSum(TreeNode* root) {
        int max_num = INT_MIN;
        dfs(root,max_num);
        return max_num;
    }
    // int dfs(TreeNode* root,int sums,int max_num)
    // {
    //     i++;
    //     if(root == nullptr)
    //     {
    //         // printf("%d ",sum);
    //         return sum;
    //     }
    //     sum = dfs(root->left,sum,max_num);
    //     sum = dfs(root->right,sum,max_num);
    //     // if(root->left == nullptr && root->right == nullptr)
    //     // {
    //     sum[i] += root->val;
    //     // if()
    //     max_num = max(max_num,sum);
    //     // }
    //     printf("%d",max_num);
    //     return sum;
    // }
    // int maxPathSum(TreeNode* root) {
    //     // int vector<int> sums;
    //     int sum = 0;
    //     int max_num = 0;
    //     // sums[0] = 0;
    //     return dfs(root,sum,max_num);
    // }
};


剑指 Offer II 008. 和大于等于 target 的最短子数组


题目描述:

给定一个含有 n 个正整数的数组和一个正整数 target 。


找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。


示例:

08db012fb37a4af6997a82389a8b14ea.png


思路:

直接滑动窗口,o(n)复杂度。

应该优化用前缀和加二分查找。


代码:

滑动窗口:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int min_size = 99999999;
        int len = nums.size();
        int right = 0;
        int left = 0;
        long long sum = 0;
        while(right < len)
        {
            sum += nums[right];
            while(sum >= target)
            {
                min_size = min(min_size,right-left+1);
                // sum += nums[right];
                sum -= nums[left];
                left++;
            }
            right++;
        }
        return min_size < 99999999 ? min_size : 0;
    }
};

前缀和+二分

class Solution {
public:
    int bin_search(vector<int>& nums, int s, int e, int tar) {
        int l = s, r = e;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (nums[mid] >= tar) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        if (nums[r] < tar) return -1;
        return r;
    }
    int minSubArrayLen(int target, vector<int>& nums) {
        for (int i = 1; i < nums.size(); ++i) {
            nums[i] += nums[i - 1];
        }
        int sd = 0;
        int ans = INT_MAX;
        for (int i = 0; i < nums.size(); ++i) {
            // 需要在后续前缀和数组中搜索的值
            if (i == 0) {
                sd = target;
            } else {
                sd = nums[i - 1] + target;
            }
            // 寻找第一个大于等于 sd 的值的位置
            int idx = bin_search(nums, i, nums.size() - 1, sd);
            if (idx < 0) {
                break;
            } else {
                ans = min(ans, idx - i + 1);
            }
        }
        return ans == INT_MAX ? 0 : ans;
    }
};


剑指 Offer II 016. 不含重复字符的最长子字符串


题目描述:

给定一个字符串 s ,请你找出其中不含有重复字符的 最长连续子字符串 的长度。

思路:

直接滑动窗口+set

代码:

// #include <algorithm>
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n = s.length();
        if(n == 1) return 1;
        if(n == 0) return 0;
        set<char> window;
        int max_size = 1;
        //这是一个窗口
        int right = 0,left = 0;
        while(right < n)
        {
            if(window.count(s[right]))
            {
                window.erase(s[left]);
                left++;
            }
            else
            {
                window.insert(s[right]);
                max_size = max(int(window.size()),max_size);
                right++;
            }
        }
        return max_size;
    }
};
相关文章
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
76 6
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
73 4
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 49. 丑数
解决剑指 Offer 49题"丑数"的Python实现,通过动态规划的方法计算出第n个丑数。
59 2
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 04. 二维数组中的查找
剑指Offer题目 "二维数组中的查找" 的Python解决方案,包括非递归迭代、递归以及使用内置函数的二分查找方法,以判断一个有序的二维数组中是否含有给定整数。
48 1
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 03. 数组中重复的数字
解决剑指Offer题目 "数组中重复的数字" 的Python实现方法,通过使用字典来记录数组中每个数字的出现次数,快速找出重复的数字。
53 1
|
6月前
|
iOS开发 MacOS
【Mac系统】解决Vscode中LeetCode插件不能刷剑指offer题库
文章讨论了解决Mac系统中Vscode里LeetCode插件无法刷剑指Offer题库的问题,并提供了一些相关的使用技巧和资源链接。
339 1
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
68 5
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
45 4
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
Leetcode题目"剑指 Offer 21. 调整数组顺序使奇数位于偶数前面"的两种Python解决方案,一种是使用双端队列调整数组顺序,另一种是使用双指针法将奇数移到数组前半部分,偶数移到后半部分。
37 4
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
56 4