当前位置: 首页 > news >正文

【算法与数据结构】198、213、337LeetCode打家劫舍I, II, III

文章目录

  • 一、198、打家劫舍
  • 二、213、打家劫舍 II
  • 三、337、打家劫舍III
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、198、打家劫舍

在这里插入图片描述
  思路分析:打家劫舍是动态规划的的经典题目。本题的难点在于递归公式和初始化。

  • 第一步, d p [ j ] dp[j] dp[j]的含义。 d p [ j ] dp[j] dp[j]代表到第 j j j家的时候,偷窃到的最高金额。
  • 第二步,递推公式。 d p [ j ] dp[j] dp[j]仅仅与 d p [ j − 1 ] dp[j-1] dp[j1] d p [ j − 2 ] dp[j-2] dp[j2]有关。如果不偷第 j j j家,则偷窃金额不变, d p [ j ] = d p [ j − 1 ] dp[j] = dp[j-1] dp[j]=dp[j1]。如果偷第 j j j家,那么偷窃金额在 d p [ j − 2 ] dp[j-2] dp[j2]基础上加上 n u m s [ i ] nums[i] nums[i],即 d p [ j ] = d p [ j − 2 ] + n u m s [ i ] dp[j] = dp[j-2] + nums[i] dp[j]=dp[j2]+nums[i]。综合二者, d p [ j ] = m a x ( d p [ j − 1 ] , d p [ j − 2 ] + n u m s [ i ] ) dp[j] = max(dp[j-1], dp[j-2] + nums[i]) dp[j]=max(dp[j1],dp[j2]+nums[i])
  • 第三部,元素初始化。 d p [ 0 ] dp[0] dp[0]初始化为0,代表还没开始偷窃; d p [ 1 ] dp[1] dp[1]初始化为 n u m [ 0 ] num[0] num[0]
  • 第四部,递归顺序。循环从 j = 2 j = 2 j=2开始。
  • 第五步,打印结果。
      程序如下
// 198、打家劫舍,动态规划
class Solution {
public:int rob(vector<int>& nums) {vector<int> dp(nums.size() + 1, 0);dp[1] = nums[0];for (int i = 2; i <= nums.size(); i++) {dp[i] = max(dp[i - 1], dp[i - 2] + nums[i-1]);}return dp[nums.size()];}
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

  因为只用到了dp数组的最后一个元素,实际上不需要保存所有的元素。因此对上述代码进行内存优化,将空间复杂度降低到 O ( 1 ) O(1) O(1),但是递归的过程不明显,找bug费劲。

// 198、打家劫舍,动态规划-内存优化
class Solution2 {
public:int rob(vector<int>& nums) {if (nums.size() == 0) return 0;if (nums.size() == 1) return nums[0];int first = nums[0], second = max(nums[0], nums[1]);for (int i = 2; i < nums.size(); i++) {int temp = second;second = max(second, first + nums[i]);first = temp;}return second;}
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

二、213、打家劫舍 II

在这里插入图片描述

  思路分析:本题是打家劫舍I的升级版,要求第一家和最后一家是连着的,不能同时偷。这是一个非此即彼的问题。要么偷第一家,不偷最后一家,这等于将最后一家排除在外。反之,不偷第一家,偷最后一家,等价于将第一家排除在外。假设第一家的下标为 0 0 0,最后一家的下标为 i − 1 i-1 i1,那么一共有两种情况:偷窃范围 [ 0 , i − 2 ] [0, i - 2] [0,i2],偷窃范围 [ 1 , i − 1 ] [1, i - 1] [1,i1]。然后应用打家劫舍I的思路来做即可。以下是动态规划的代码,内存优化版本就没给出了,思路都是一样的。

  程序如下

// 213、打家劫舍II,动态规划
class Solution3 {
public:int rob(vector<int>& nums) {if (nums.size() == 0) return 0;if (nums.size() == 1) return nums[0];int result1 = robRange(nums, 0, nums.size() - 2);int result2 = robRange(nums, 1, nums.size() - 1);return max(result1, result2);}int robRange(vector<int>& nums, int start, int end) {if (end == start) return nums[start];vector<int> dp(nums.size(), 0);dp[start] = nums[start];dp[start + 1] = max(nums[start], nums[start + 1]);for (int i = start + 2; i <= end; i++) {dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1]);}return dp[end];}
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

三、337、打家劫舍III

在这里插入图片描述
在这里插入图片描述

  思路分析:本题是打家劫舍I的变体,原题目中的数组变成了二叉树。本题涉及到树形递归和动态规划,我们就结合递归三部曲和动态规划五步骤:

  • 1、返回值和递归参数。我们需要判断一个节点要不要偷,而偷不偷取决于动作带来的收益。因此,我们需要返回一个节点偷与不偷的两个状态所得的金额。这就是一个长度为2的数组。这里我们假设这个二维数组第一个元素代表不偷的收益,第二个元素代表偷的收益,{ 0 , 1 = 不偷的收益,偷的收益 {0, 1} = {不偷的收益,偷的收益} 0,1=不偷的收益,偷的收益}。输入参数是当前节点。
  • 2、确定终止条件。当遇到空节点就返回,空节点不会带来收益。因此返{ 0 , 0 {0,0} 0,0}。
	if (cur == NULL) return vector<int>{0, 0};
  • 3、确定遍历顺序。因为当前节点偷不偷需要根据左右孩子的返回值来进行判断,所以 我们需要先得到左右孩子的返回值,即先遍历左右孩子。在所有的遍历顺序中,只有后序遍历(左右中遍历顺序)满足。
	vector<int> left = robTree(cur->left); // 左vector<int> right = robTree(cur->right); // 右
  • 4、确定单层递归逻辑。对于当前节点来说,只有两个情况。如果偷当前节点,那么左右孩子节点就不能偷,偷的收益=左孩子不偷的收益+右孩子不偷的收益。如果不偷当前节点,那么左右孩子节点可偷可不偷,至于究竟偷不偷就看那个收益大(注意偷的收益未必更大,偷了小的金额,旁边大的金额就偷不了)。不偷的收益 = max(左孩子不偷的收益,左孩子偷的收益)+max(右孩子不偷的收益,右孩子偷的收益)。将文字抽象成公式:
 	int val1 = cur->val + left[0] + right[0];   // 偷当前节点,那么左右孩子节点不能偷int val2 = max(left[0], left[1]) + max(right[0], right[1]); // 不偷当前节点,那么左右孩子节点可以偷也可以不偷,取决于偷或者是不偷的金额。
  • 5、具体示例推导dp数组,验证。
      程序如下
// 337、打家劫舍III动态规划
class Solution {
public:int rob(TreeNode* root) {vector<int> result = robTree(root);return max(result[0], result[1]);}vector<int> robTree(TreeNode* cur) {    // 返回一个二维数组, {0, 1} = {不偷的金额,偷的金额}if (cur == NULL) return vector<int>{0, 0};vector<int> left = robTree(cur->left);vector<int> right = robTree(cur->right);int val1 = cur->val + left[0] + right[0];   // 偷当前节点,那么左右孩子节点不能偷int val2 = max(left[0], left[1]) + max(right[0], right[1]); // 不偷当前节点,那么左右孩子节点可以偷也可以不偷,取决于偷或者是不偷的金额。return { val2, val1 };}
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n),每个节点只遍历了一次。
  • 空间复杂度: O ( l o g n ) O(log n) O(logn),算上递推系统栈的空间。

三、完整代码

// 打家劫舍I, II
# include <iostream>
# include <vector>
# include <algorithm>
using namespace std;// 198、打家劫舍,动态规划
class Solution {
public:int rob(vector<int>& nums) {vector<int> dp(nums.size() + 1, 0);dp[1] = nums[0];for (int i = 2; i <= nums.size(); i++) {dp[i] = max(dp[i - 1], dp[i - 2] + nums[i-1]);}return dp[nums.size()];}
};// 198、打家劫舍,动态规划-内存优化
class Solution2 {
public:int rob(vector<int>& nums) {if (nums.size() == 0) return 0;if (nums.size() == 1) return nums[0];int first = nums[0], second = max(nums[0], nums[1]);for (int i = 2; i < nums.size(); i++) {int temp = second;second = max(second, first + nums[i]);first = temp;}return second;}
};// 213、打家劫舍II,动态规划
class Solution3 {
public:int rob(vector<int>& nums) {if (nums.size() == 0) return 0;if (nums.size() == 1) return nums[0];int result1 = robRange(nums, 0, nums.size() - 2);int result2 = robRange(nums, 1, nums.size() - 1);return max(result1, result2);}int robRange(vector<int>& nums, int start, int end) {if (end == start) return nums[start];vector<int> dp(nums.size(), 0);dp[start] = nums[start];dp[start + 1] = max(nums[start], nums[start + 1]);for (int i = start + 2; i <= end; i++) {dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1]);}return dp[end];}
};int main() {vector<int> nums = { 1,2,3,1 };Solution3 s1;int result = s1.rob(nums);cout << result << endl;system("pause");return 0;
}
// 337、打家劫舍III
# include <iostream>
# include <vector>
# include <string>
# include <queue>
using namespace std;// 树节点定义
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) {}
};template<typename T>
void my_print(T& v, const string msg)
{cout << msg << endl;for (class T::iterator it = v.begin(); it != v.end(); it++) {cout << *it << ' ';}cout << endl;
}template<class T1, class T2>
void my_print2(T1& v, const string str) {cout << str << endl;for (class T1::iterator vit = v.begin(); vit < v.end(); ++vit) {for (class T2::iterator it = (*vit).begin(); it < (*vit).end(); ++it) {cout << *it << ' ';}cout << endl;}
}// 前序遍历迭代法创建二叉树,每次迭代将容器首元素弹出(弹出代码还可以再优化)
void Tree_Generator(vector<string>& t, TreeNode*& node) {if (!t.size() || t[0] == "NULL") return;    // 退出条件else {node = new TreeNode(stoi(t[0].c_str()));    // 中if (t.size()) {t.assign(t.begin() + 1, t.end());Tree_Generator(t, node->left);              // 左}if (t.size()) {t.assign(t.begin() + 1, t.end());Tree_Generator(t, node->right);             // 右}}
}// 层序遍历
vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> que;if (root != NULL) que.push(root);vector<vector<int>> result;while (!que.empty()) {int size = que.size();  // size必须固定, que.size()是不断变化的vector<int> vec;for (int i = 0; i < size; ++i) {TreeNode* node = que.front();que.pop();vec.push_back(node->val);if (node->left) que.push(node->left);if (node->right) que.push(node->right);}result.push_back(vec);}return result;
}// 337、打家劫舍III动态规划
class Solution {
public:int rob(TreeNode* root) {vector<int> result = robTree(root);return max(result[0], result[1]);}vector<int> robTree(TreeNode* cur) {    // 返回一个二维数组, {0, 1} = {不偷的金额,偷的金额}if (cur == NULL) return vector<int>{0, 0};vector<int> left = robTree(cur->left);vector<int> right = robTree(cur->right);int val1 = cur->val + left[0] + right[0];   // 偷当前节点,那么左右孩子节点不能偷int val2 = max(left[0], left[1]) + max(right[0], right[1]); // 不偷当前节点,那么左右孩子节点可以偷也可以不偷,取决于偷或者是不偷的金额。return { val2, val1 };}
};int main() {vector<string> t = { "3", "2", "NULL", "3", "NULL", "NULL", "3", "NULL", "1", "NULL", "NULL"};   // 前序遍历TreeNode* root = new TreeNode();    // 生成根节点Tree_Generator(t, root);            // 生成树vector<vector<int>> tree = levelOrder(root);    // 层序遍历my_print2<vector<vector<int>>, vector<int>>(tree, "目标树:");  // 打印层序遍历Solution s1;int result = s1.rob(root);cout << "最大金额为:" << result << endl;system("pause");return 0;
}

end

相关文章:

【算法与数据结构】198、213、337LeetCode打家劫舍I, II, III

文章目录 一、198、打家劫舍二、213、打家劫舍 II三、337、打家劫舍III三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、198、打家劫舍 思路分析&#xff1a;打家劫舍是动态规划的的经典题目。本题的难点在于递归公式…...

React、React Router、JSX 简单入门快速上手

React、React Router、JSX 简单入门快速上手 介绍特点 JSX使用js表达式渲染列表样式控制注意事项 入门脚手架创建react项目安装目录介绍入口文件解析 组件解析介绍函数式组件类组件 事件绑定注意点定义使用事件对象事件处理函数接收额外参数 组件状态状态的定义使用 组件通信父…...

从 0 开始搭建 React 框架

webpack 配置 不再赘述&#xff0c;可参考前三个文章&#xff08;wenpack5 基本使用 1 - 3&#xff09; 使用 react 安装 react、react-dom、babel/preset-react yarn add react react-dom babel/preset-react<!DOCTYPE html> <html lang"en"> <h…...

网站地址怎么改成HTTPS?

现在&#xff0c;所有类型的网站都需要通过 HTTPS 协议进行安全连接&#xff0c;而实现这一目标的唯一方法是使用 SSL 证书。如果您不将 HTTP 转换为 HTTPS&#xff0c;浏览器和应用程序会将您网站的连接标记为不安全。 但用户询问如何将我的网站从 HTTP 更改为 HTTPS。在此页…...

Blender教程(基础)-面的细分与删除、挤出选区-07

一、Blender之面的细分 新建一个立方体&#xff0c;在编辑模式下、选中一个面。 在选中的面上单击右键弹出细分选项&#xff0c;选择细分。 在选中细分后、会默认细分1次。修改细分次数在左下角 二、Blender之面的删除 选择中需要操作的面&#xff0c;在英文状态下按X键弹…...

QT自制软键盘 最完美、最简单、支持中文输入(二)

目录 一、前言 二、本自制虚拟键盘特点 三、中文输入原理 四、组合键输入 五、键盘事件模拟 六、界面 七、代码 7.1 frmKeyBoard 头文件代码 7.2 frmKeyBoard 源文件代码 八、使用示例 九、效果 十、结语 一、前言 由于系统自带虚拟键盘不一定好用&#xff0c;也不一…...

SpringCloud_学习笔记_1

SpringCloud01 1.认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 1.0.学习目标 了解微服务架构的优缺点 1.1.单体架构 单体架构&#xff…...

容器算法迭代器初识

#include<iostream> using namespace std; #include<vector> //vetor容器存放内置数据类型 void test01() {//创建了一个vector容器&#xff0c;数组 vector<int> v;//向容器中插入数据v.push_back (10);//尾插 v.push_back (20);v.push_back (30);v.push_ba…...

瑞_力扣LeetCode_二叉搜索树相关题

文章目录 说明题目 450. 删除二叉搜索树中的节点题解递归实现 题目 701. 二叉搜索树中的插入操作题解递归实现 题目 700. 二叉搜索树中的搜索题解递归实现 题目 98. 验证二叉搜索树题解中序遍历非递归实现中序遍历递归实现上下限递归 题目 938. 二叉搜索树的范围和题解中序遍历…...

python爬虫爬取网站

流程&#xff1a; 1.指定url(获取网页的内容) 爬虫会向指定的URL发送HTTP请求&#xff0c;获取网页的HTML代码&#xff0c;然后解析HTML代码&#xff0c;提取出需要的信息&#xff0c;如文本、图片、链接等。爬虫请求URL的过程中&#xff0c;还可以设置请求头、请求参数、请求…...

c# Get方式调用WebAPI,WebService等接口

/// <summary> /// 利用WebRequest/WebResponse进行WebService调用的类 /// </summary> public class WebServiceHelper {//<webServices>// <protocols>// <add name"HttpGet"/>// <add name"HttpPost"/>// …...

银行数据仓库体系实践(11)--数据仓库开发管理系统及开发流程

数据仓库管理着整个银行或公司的数据&#xff0c;数据结构复杂&#xff0c;数据量庞大&#xff0c;任何一个数据字段的变化或错误都会引起数据错误&#xff0c;影响数据应用&#xff0c;同时业务的发展也带来系统不断升级&#xff0c;数据需求的不断增加&#xff0c;数据仓库需…...

微信小程序引导用户打开定位授权通用模版

在需要使用位置信息的页面&#xff08;例如 onLoad 或 onShow 生命周期函数&#xff09;中调用 wx.getSetting 方法检查用户是否已经授权地理位置权限&#xff1a; Page({onLoad: function() {wx.getSetting({success: res > {if (res.authSetting[scope.userLocation]) {/…...

JVM篇----第十篇

系列文章目录 文章目录 系列文章目录前言一、JAVA 强引用二、JAVA软引用三、JAVA弱引用四、JAVA虚引用五、分代收集算法前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧…...

DevSecOps 参考模型介绍

目录 一、参考模型概述 1.1 概述 二、参考模型分类 2.1 DevOps 组织型模型 2.1.1 DevOps 关键特性 2.1.1.1 模型特性图 2.1.1.2 特性讲解 2.1.1.2.1 自动化 2.1.1.2.2 多边协作 2.1.1.2.3 持续集成 2.1.1.2.4 配置管理 2.1.2 DevOps 生命周期 2.1.2.1 研发过程划分…...

什么是okhttp?

OkHttp简介&#xff1a; OkHttp 是一个开源的、高效的 HTTP 客户端库&#xff0c;由 Square 公司开发和维护。它为 Android 和 Java 应用程序提供了简单、强大、灵活的 HTTP 请求和响应的处理方式。OkHttp 的设计目标是使网络请求变得更加简单、快速、高效&#xff0c;并且支持…...

R语言基础学习-02 (此语言用途小众 用于数学 生物领域 基因分析)

变量 R 语言的有效的变量名称由字母&#xff0c;数字以及点号 . 或下划线 _ 组成。 变量名称以字母或点开头。 变量名是否正确原因var_name2.正确字符开头&#xff0c;并由字母、数字、下划线和点号组成var_name%错误% 是非法字符2var_name错误不能数字开头 .var_name, var.…...

CTF-WEB的入门真题讲解

EzLogin 第一眼看到这个题目我想着用SQL注入 但是我们先看看具体的情况 我们随便输入admin和密码发现他提升密码不正确 我们查看源代码 发现有二个不一样的第一个是base64 意思I hava no sql 第二个可以看出来是16进制转化为weak通过发现是个弱口令 canyouaccess 如果…...

【C项目】顺序表

简介&#xff1a;本系列博客为C项目系列内容&#xff0c;通过代码来具体实现某个经典简单项目 适宜人群&#xff1a;已大体了解C语法同学 作者留言&#xff1a;本博客相关内容如需转载请注明出处&#xff0c;本人学疏才浅&#xff0c;难免存在些许错误&#xff0c;望留言指正 作…...

【Docker】在Windows下使用Docker Desktop创建nginx容器并访问默认网站

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Docker容器》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对…...

快速原型:用快马一键生成win11右键菜单传统样式恢复工具

快速原型&#xff1a;用快马一键生成win11右键菜单传统样式恢复工具 最近升级到Windows 11后&#xff0c;最让我不习惯的就是那个右键菜单了。新版的设计把所有选项都折叠起来&#xff0c;每次想找个功能还得点"显示更多选项"&#xff0c;效率大打折扣。作为一个习惯…...

别再死记硬背了!用这个动画+仿真,5分钟搞懂CMOS反相器到底怎么‘反’的

别再死记硬背了&#xff01;用动画仿真5分钟搞懂CMOS反相器的翻转奥秘 第一次翻开数字电路教材时&#xff0c;那个由PMOS和NMOS组成的对称结构总让我困惑——为什么PMOS必须在上方&#xff1f;为什么输入高电平反而输出低电平&#xff1f;直到我在实验室里用仿真软件亲眼看到电…...

效率倍增器:利用快马AI自动生成网络设备批量巡检与健康报告脚本

最近在深圳做网络运维的朋友跟我吐槽&#xff0c;每天要手动巡检几十台网络设备&#xff0c;检查CPU、内存、接口状态这些指标&#xff0c;不仅耗时还容易出错。于是我尝试用InsCode(快马)平台帮他解决这个问题&#xff0c;效果出奇的好。今天就把这个自动化巡检脚本的实现过程…...

Reloadium与Django集成:实现视图热重载和页面自动刷新

Reloadium与Django集成&#xff1a;实现视图热重载和页面自动刷新 【免费下载链接】reloadium Hot Reloading, Profiling and AI debugging for Python 项目地址: https://gitcode.com/gh_mirrors/re/reloadium Reloadium是一个强大的Python开发工具&#xff0c;为你的I…...

Python原生AOT编译实战指南(2026 LTS版正式启用倒计时)

第一章&#xff1a;Python原生AOT编译的演进脉络与2026 LTS战略意义Python长期以来以解释执行和字节码&#xff08;.pyc&#xff09;为核心运行范式&#xff0c;而原生AOT&#xff08;Ahead-of-Time&#xff09;编译的探索始于2010年代中期的Nuitka、Cython等工具&#xff0c;但…...

MegSpot专业视觉分析工具:从基础操作到高级应用全指南

MegSpot专业视觉分析工具&#xff1a;从基础操作到高级应用全指南 【免费下载链接】MegSpot MegSpot是一款高效、专业、跨平台的图片&视频对比应用 项目地址: https://gitcode.com/gh_mirrors/me/MegSpot 在数字媒体创作与分析领域&#xff0c;如何高效对比图片细节…...

保姆级教程:用Python+Socket实现西门子CNC产量数据自动采集(附避坑指南)

PythonSocket实现西门子CNC产量数据自动化采集实战指南 在工业4.0时代&#xff0c;生产数据的实时采集与分析已成为智能制造的核心环节。对于使用西门子数控系统&#xff08;如828D、840DSL等&#xff09;的制造企业而言&#xff0c;如何绕过复杂的授权流程&#xff0c;通过编程…...

云顶之弈策略优化工具:TFT Overlay如何提升游戏决策效率

云顶之弈策略优化工具&#xff1a;TFT Overlay如何提升游戏决策效率 【免费下载链接】TFT-Overlay Overlay for Teamfight Tactics 项目地址: https://gitcode.com/gh_mirrors/tf/TFT-Overlay 在云顶之弈激烈的对战中&#xff0c;玩家常常面临装备合成路径混乱、羁绊触发…...

Alpamayo-R1-10B商业应用探索:车企研发提效与算法验证加速方案

Alpamayo-R1-10B商业应用探索&#xff1a;车企研发提效与算法验证加速方案 1. 项目概述 Alpamayo-R1-10B是NVIDIA推出的自动驾驶专用开源视觉-语言-动作(VLA)模型&#xff0c;作为新一代自动驾驶研发工具链的核心组件&#xff0c;正在改变车企的研发流程。这个100亿参数规模的…...

Windows HEIC缩略图插件:系统级集成架构深度解析

Windows HEIC缩略图插件&#xff1a;系统级集成架构深度解析 【免费下载链接】windows-heic-thumbnails Enable Windows Explorer to display thumbnails for HEIC files 项目地址: https://gitcode.com/gh_mirrors/wi/windows-heic-thumbnails 在跨平台数字内容管理日益…...