LeetCode 热题 C++ 287. 寻找重复数 297. 二叉树的序列化与反序列化 300. 最长递增子序列 739. 每日温度

39 篇文章 0 订阅
20 篇文章 0 订阅

LeetCode287

给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,返回 这个重复的数

你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。

示例 1:

输入:nums = [1,3,4,2,2]
输出:2

示例 2:

输入:nums = [3,1,3,4,2]
输出:3

提示:

  • 1 <= n <= 105
  • nums.length == n + 1
  • 1 <= nums[i] <= n
  • nums只有一个整数 出现 两次或多次 ,其余整数均只出现 一次

进阶:

  • 如何证明 nums 中至少存在一个重复的数字?
  • 你可以设计一个线性级时间复杂度 O(n) 的解决方案吗? 

思路:

因为其数字都在 [1, n] 范围内,我们可以把它看成一个链表,有相同数字就说明有环,那么这道题就变成了找环的起点。

在之前讲过,可以看LeetCode 热题 C++ 141. 环形链表 142. 环形链表 II(详解!)_Zero_979的博客-CSDN博客

代码:

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int i=0,j=0;
        do{
            i=nums[i];
            j=nums[nums[j]];
        }while(i!=j);
        i=0;
        while(i!=j)
        {
            i=nums[i];
            j=nums[j];
        }
        return i;
    }
};

LeetCode297

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

示例 1:

输入:root = [1,2,3,null,null,4,5]
输出:[1,2,3,null,null,4,5]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

输入:root = [1,2]
输出:[1,2]

提示:

  • 树中结点数在范围 [0, 104]
  • -1000 <= Node.val <= 1000

思路:

DFS参考力扣

其中C++用到的一些知识点:

istringstream是一个比较有用的c++的输入输出控制类。

C++引入了ostringstream、istringstream、stringstream这三个类,要使用他们创建对象就必须包含<sstream>这个头文件。
istringstream类用于执行C++风格的串流的输入操作。
ostringstream类用于执行C风格的串流的输出操作。
strstream类同时可以支持C风格的串流的输入输出操作。

istringstream的构造函数原形如下:
istringstream::istringstream(string str);
它的作用是从string对象str中读取字符。

 atoi是C++的字符处理函数,把数字字符串转换成int输出

代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if(!root)return "null";
        string left=serialize(root->left);
        string right=serialize(root->right);
        return to_string(root->val)+" "+left+" "+right;
    }
    TreeNode* dfs(istringstream& is)
    {
        string s;
        is>>s;
        if(s=="null")return nullptr;
        TreeNode* root=new TreeNode(stoi(s));
        root->left = dfs(is);
        root->right = dfs(is);
        return root;
    }
    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        string s;
        istringstream is(data);
        return dfs(is);
    }
};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

LeetCode300

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例 1:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

示例 2:

输入:nums = [0,1,0,3,2,3]
输出:4

示例 3:

输入:nums = [7,7,7,7,7,7,7]
输出:1

提示:

  • 1 <= nums.length <= 2500
  • -104 <= nums[i] <= 104

进阶:

  • 你能将算法的时间复杂度降低到 O(n log(n)) 吗?

思路:

简单的dp

代码:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int dp[3000];
        memset(dp,0,sizeof(dp));
        int mmax=1;
        for(int i=0;i<nums.size();i++)
        {
            dp[i]=1;
            for(int j=0;j<i;j++)
            {
                if(nums[i]>nums[j])dp[i]=max(dp[i],dp[j]+1);
            }
            mmax=max(mmax,dp[i]);
        }
        return mmax;
    }
};

LeetCode739

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

示例 2:

输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]

示例 3:

输入: temperatures = [30,60,90]
输出: [1,1,0]

提示:

  • 1 <= temperatures.length <= 105
  • 30 <= temperatures[i] <= 100

思路:

暴力优化)

代码:

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        int len=temperatures.size();
        vector<int> v(len);
        v[len-1]=0;
        for(int i=len-2;i>=0;i--)
        {
            v[i]=0;
            for(int j=i+1;j<len;)
            {
                if(temperatures[j]>temperatures[i]){
                    v[i]=j-i;
                    break;
                }
                else if(temperatures[j]==temperatures[i]){
                    if(v[j]!=0)v[i]=v[j]+j-i;
                    break;
                }
                else if(v[j]==0)break;
                else j=j+v[j];
            }
        }
        return v;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值