【2020.5.9今日编程】LeetCode 300.最长上升子序列 +LeetCode 114.二叉树展开为链表 +LeetCode 105.从前序与中序遍历序列构造二叉树

LeetCode 300.最长上升子序列

中等

  • 题目:给定一个无序的整数数组,找到其中最长上升子序列的长度。

  • 示例

输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。

★ 请大家注意,题目要求的是最长上升子序列,而不是子串!!!子序列可以是不连续的,但是子串一定是连续的。(我当时一看示例真的很懵,以为题目错了,奈何读书太少加上没注意审题,哭)

  • 方法:动态规划(我觉得状态规划真的是一个很重要的方法,一定要学会!!!这道题最常见做法的时间复杂度是O(n^2),但是可以优化到O(nlgn),明天尝试学习一下—)。
  • cpp代码实现
class Solution
{
     
	public:
		int lengthOfLIS(vector<int>& nums) 
		{
     
			if(nums.empty())
				return 0;
			vector<int>dp(nums.size(), 0);
			dp[0] = 1;
			for(int i = 1; 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);
				}
			}
			sort(dp.begin(), dp.end());
			return dp[dp.size() - 1];
		}
};
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n)

LeetCode 114.二叉树展开为链表

中等

  • 题目:给定一个二叉树,原地将它展开为链表。

  • 示例

例如,给定二叉树:
【2020.5.9今日编程】LeetCode 300.最长上升子序列 +LeetCode 114.二叉树展开为链表 +LeetCode 105.从前序与中序遍历序列构造二叉树_第1张图片
将其展开为:
【2020.5.9今日编程】LeetCode 300.最长上升子序列 +LeetCode 114.二叉树展开为链表 +LeetCode 105.从前序与中序遍历序列构造二叉树_第2张图片

  • 方法:其实就是把左子树的节点都移到右边,然后相互连接起来即可。
  • cpp代码实现
class Solution
{
     
	public:
		void flatten(TreeNode* root)
		{
     
			if(root == NULL)
				return ;
			flatten(root->right);
			flatten(root->left);
			TreeNode* cur = root->left;
			if(cur == NULL)
				return ;
			while(cur->right != NULL)
				cur = cur->right;
			cur->right = root->right;
			root->right = root->left;
			root->left = NULL;
		}	
};

LeetCode 105.从前序与中序遍历序列构造二叉树

中等

  • 题目:根据一棵树的前序遍历与中序遍历构造二叉树。
    注意:
    你可以假设树中没有重复的元素。

  • 示例

例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

  • 方法:根据先序遍历 + 中序遍历 或者 中序遍历 + 后序遍历可以重构二叉树,关键是找到根节点的位置,之后找到左右子树,最后核心就是要递归喽。

  • cpp代码实现

class Solution
{
     
	public:
		TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
		{
     
			return bulid(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1);
		}
		TreeNode* build(vector<int>& preorder, int lo1, int hhi1, vector<int>& inorder, int lo2, int hi2)
		{
     
			if(lo1 > hi1 || lo2 > hi2)
				return NULL;
			TreeNode* root = new TreeNode(preorder[lo1]);
			int mid = lo2;
			for(int i = lo2; i <= hi2; i++)
			{
     
				if(inorder[i] == root->val)
				{
     
					mid = i;
					break;
				}
			}
			root->left = build(preorder, lo1 + 1, lo1 + mid - lo2, inorder, lo2, mid - 1);
			root->right = build(lo1 + mid - lo2 + 1, hi1, inorder, mid + 1, hi2);
			return root;
		}
};

写在最后
又是一个雨天,伴随着一天的身体不舒服,和朋友聊了聊天,我好像能慢慢想开并努力走出来。学习之余睡睡觉、吃吃零食、帮妈妈干点活儿、思考思考人生感觉也不错,生活看似很糟,却又没有那么糟,我好像把自己绷得太紧了,有时候越逼自己好像越适得其反,以后就 努力+顺其自然吧~~~

你可能感兴趣的:(二叉树,leetcode)