日期: 2021 年 5 月 28 日

郭同欣: 统筹疫情防控和经济社会发展的新答卷

统筹疫情防控和经济社会发展的新答卷
——《2021中国统计摘要》评读 郭同欣   《2021中国统计摘要》已经如期出版,它全面反映了过去一年我国经济社会发展取得的新成就新进展。2020年是新中国历史上*不平凡的一年。面对突如其来的新冠肺炎疫情、世界经济深度衰退等多重严重冲击,在以*同志为核心的党中央坚强领导下,全国各族人民团结一心、攻坚克难,疫情防控取得重大战略成果,经济运行稳定恢复,社会大局和谐稳定,创新动能积聚壮大,改革开放迈出新步伐,决胜全面建成小康社会取得决定性成就,交出一份人民满意、世界瞩目、可以载入史册的答卷。   一、统筹防疫和发展取得重大成果,经济恢复走在世界前列   2020年初,突如其来的新冠肺炎疫情对我国经济社会发展带来前所未有的冲击,主要经济指标明显下滑。面对严峻形势,各地区各部门按照党中央、国务院部署,统筹推进疫情防控和经济社会发展,率先控制住疫情、率先复工复产、率先实现经济正增长,我国经济强大韧性和巨大潜能充分彰显。一是我国经济实现正增长。2020年一季度,国内生产总值同比下降6.8%,随着疫情得到有效防控和复工复产加快推进,二、三、四季度分别增长3.2%、4.9%和6.5%,经济增速在全球范围率先由负转正。2020年,世界经济比上年下降3.3%,而我国国内生产总值比上年增长2.3%。在全球国内生产总值1万亿美元以上的主要经济体中,我国是唯一实现经济正增长的主要经济体。二是经济总量突破百万亿元大关。2020年,我国国内生产总值101.6万亿元,按年平均汇率折算达14.7万亿美元;占世界经济的比重预计超过17%,稳居世界第二位。2020年,人均国内生产总值72000元,按年平均汇率折算达10438美元,连续两年超过1万美元,稳居中等偏上收入国家行列。三是发展基础日益巩固。2020年末,我国高速铁路营业里程3.79万公里,“四纵四横”高铁主骨架全面建成;高速公路里程达16.1万公里,稳居世界*。2020年末,全国移动通信基站总数达931万个,互联网宽带接入端口近9.5亿个。   二、“六稳”“六保”落地显效,经济社会发展大局稳定   扎实做好“六稳”工作,全面落实“六保”任务,着力畅通经济循环,积*稳岗扩就业,大力助企纾困,筑牢民生保障基础,稳住了经济基本盘,保持了社会大局稳定。一是居民就业总体稳定。2020年末,全国就业人员75064万人,其中城镇就业人员46271万人,比上年末增加1022万人。年末全国城镇调查失业率为5.2%,城镇登记失业率为4.2%,均低于预期目标。二是基本民生保障有力。保供稳价政策有力有效,2020年居民消费价格比上年上涨2.5%,低于3.5%左右的预期目标。社会兜底保障力度加大,2020年全国居民人均转移净收入比上年名义增长8.7%。三是市场主体活力增强。营商环境持续优化,减税降费效应显现,新的市场主体快速涌现。2020年,新登记市场主体2502万户,日均新登记企业2.2万户,年末市场主体总数达1.4亿户。四是粮食和能源供给增加。2020年,粮食总产量13390亿斤,再创历史新高,连续6年保持在1.3万亿斤以上;一次能源生产总量40.8亿吨标准煤,比上年增长2.7%。五是产业链供应链得到加强。着力打通产业链供应链卡点堵点,重点行业对上下游带动作用较强。2020年,规模以上装备制造业增加值比上年增长6.6%,其中汽车、电子行业分别增长6.6%、7.7%;工业产能利用率回升至74.5%。六是基层运转较好维护。为应对疫情冲击,2020年财政赤字规模比上年增加1万亿元,发行1万亿元抗疫特别国债,通过创新建立中央财政资金直达机制,确保资金及时到位,有效缓解了市县基层财政压力。   三、三大攻坚战取得决定性成就,固根基补短板强弱项成效显著   着力抓重点、补短板、强弱项,坚决打好三大攻坚战,脱贫攻坚取得全面胜利,绿色发展底色更加靓丽,风险防控“精准拆弹”取得成效。一是新时代脱贫攻坚目标任务胜利完成。现行标准下农村贫困人口全部脱贫,832个贫困县全部摘帽,区域性整体贫困得到解决,*对贫困现象历史性消除,创造了人类减贫史上的奇迹。2020年贫困地区农村居民人均可支配收入比上年实际增长5.6%,高于全国农村居民1.8个百分点。二是污染防治成效显著。2020年,在监测的337个地级及以上城市中,空气质量达标的城市占59.9%,比上年提高13.3个百分点。细颗粒物(PM2.5)未达标城市年平均浓度37微克/立方米,比上年下降7.5%。全国地表水考核断面中,水质优良(Ⅰ~Ⅲ类)断面比例为83.4%,比上年提高8.5个百分点;劣Ⅴ类断面比例为0.6%,下降2.8个百分点。三是防范化解重大风险扎实推进。2020年末,全国地方政府债务余额256615亿元,控制在全国人大批准的限额之内。多渠道补充银行资本金,着力提升银行资产质量。年末商业银行资本充足率为14.7%,比上年提高0.1个百分点;商业银行不良贷款率1.92%,比年初下降0.06个百分点。   四、供给侧结构性改革深入推进,创新动能持续增强   坚持以深化改革激活力,以推动创新增动力,持续深化“放管服”改革,深入推进要素市场化配置改革,强化企业创新主体地位,科技创新支撑能力不断增强,市场创新活力有效激发。一是创新投入和产出快速增加。2020年,研究与试验发展(R&D)经费支出比上年增长10.3%,连续5年保持两位数增长;与国内生产总值之比为2.40%,比上年提高0.16个百分点。世界知识产权组织报告显示,2020年我国继续位列全球创新指数排名第14位,是前30名中唯一的中等收入经济体。重大科技成果持续涌现,探月工程、火星探测、卫星导航、海洋深潜、量子计算领域捷报频传。二是新产业新产品快速发展。2020年,规模以上高技术制造业增加值比上年增长7.1%,快于全部规模以上工业4.3个百分点;工业机器人、新能源汽车、集成电路产量分别增长20.7%、17.3%、29.6%。三是新业态新模式蓬勃兴起。依托互联网、云计算、大数据等技术发展的新经济模式快速成长,在应对疫情冲击中展现出巨大发展潜力。2020年,实物商品网上零售额比上年增长14.8%,占社会消费品零售总额比重为24.9%,比上年提高4.0个百分点。移动互联网应用场景不断丰富,移动终端规模快速提升,带动移动互联网流量持续扩大。2020年,移动互联网累计接入流量比上年增长35.7%。   五、全方位对外开放扎实推进,外贸外资逆势增长   面对外部环境变化带来的新挑战,坚定不移扩大对外开放,全力以赴稳外贸稳外资,着力稳定产业链供应链,主动加强抗疫国际合作,以开放促改革促发展,稳住了外贸外资基本盘,实现了对外开放新突破。一是货物贸易规模继续扩大。2020年,货物进出口总额32.2万亿元,创历史新高,比上年增长1.9%,是全球唯一实现货物贸易正增长的主要经济体,国际市场份额提升,货物贸易*大国地位更加巩固。服务贸易稳中提质。2020年知识密集型服务进出口占服务进出口总额的比重达44.5%,比上年提高9.9个百分点。二是利用外资居世界*。在全球跨国直接投资大幅下降的背景下,我国实际使用外资逆势增长,实现引资总量、增长幅度、全球占比“三提升”。2020年,实际使用外商直接投资近1万亿元,比上年增长6.2%,其中高技术产业实际使用外资增长11.4%;我国吸收外资在全球占比首次突破10%。三是共建“一带一路”走深走实。2020年,我国对“一带一路”沿线国家进出口总额93696亿元,比上年增长1.0%;对“一带一路”沿线国家非金融类直接投资额178亿美元,增长18.3%。中欧班列和西部陆海新通道班列“两翼齐飞”。2020年,中欧班列开行12406列,比上年增长50%,首次突破“万列”大关;西部陆海新通道铁海联运班列开行4596列,增长104.9%。   六、坚持以人民为中心促发展,民生福祉持续增进   坚决兜牢民生底线,多措并举增加居民收入,推进教育公平发展和质量提升,全面加强公共卫生体系建设,丰富群众精神文化生活,全力提高社会保障水平,发展成果更多更公平惠及全体人民。一是居民收入与经济同步增长。2020年,全国居民人均可支配收入32189元,比上年增长4.7%,扣除价格因素实际增长2.1%,快于人均国内生产总值增速。农村居民收入较快增长。2020年,农村居民人均可支配收入比上年实际增长3.8%,快于城镇2.6个百分点。二是教育文化医疗事业持续发展。教育水平实现新提升。2020年九年义务教育巩固率为95.2%,比上年提高0.4个百分点;我国每10万人中具有大学(大专及以上)文化程度的由2010年8930人上升至15467人;15岁及以上人口的平均受教育年限提高至9.91年。医疗卫生服务能力得到加强。年末全国共有医疗卫生机构102.3万个,比上年末增加1.5万个;卫生技术人员1067万人,增加52万人。公共文化服务体系更加健全。2020年末,全国公共图书馆3212个,比上年增加16个;博物馆5446个,增加314个。三是社会保障安全网织密织牢。2020年末,全国参加城镇职工基本养老保险、城乡居民基本养老保险、基本医疗保险、失业保险人数分别比上年末增加2150万人、978万人、693万人、1147万人。全国基本养老保险参保人数近10亿人,基本医疗保险参保率稳定在95%以上。   2020年,我国克服疫情不利影响实现经济稳定复苏,主要发展目标任务全面完成,为开启全面建设社会主义现代化国家新征程奠定了坚实基础。2021年是“十四五”开局之年,是第二个百年奋斗目标新征程的开启之年,也是我国现代化建设进程中具有特殊重要性的一年。今年以来,统筹疫情防控和经济社会发展成效持续显现,我国经济延续稳定恢复发展态势。但也要看到,全球经济复苏与疫情防控存在不确定因素,国内部分领域结构性矛盾依然突出,推动经济恢复向好仍面临不少挑战。我们要以*新时代中国特色社会主义思想为指导,深入贯彻落实十九届五中全会、中央经济工作会议和全国“两会”精神,用好稳增长压力较小的窗口期,凝神聚力深化供给侧结构性改革,打通国内大循环、国内国际双循环堵点,保持经济运行在合理区间,使经济在恢复中达到更高水平均衡,不断迈向高质量发展,以优异成绩向党的百年华诞献*。

289. 生命游戏(JS实现)

289. 生命游戏(JS实现)

1 题目
根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态:1 即为活细胞(live),或 0 即为死细胞(dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
根据当前状态,写一个函数来计算面板上所有细胞的下一个(一次更新后的)状态。下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。
示例:
输入:
[
[0,1,0],
[0,0,1],
[1,1,1],
[0,0,0]
]
输出:
[
[0,0,0],
[1,0,1],
[0,1,1],
[0,1,0]
]
进阶:
你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?

链接:https://leetcode-cn.com/problems/game-of-life

2 思路
首先我们遍历整个矩阵,如果某细胞是活的,那么给周围8个位置细胞都加上影响因子10,然后我们第二次遍历矩阵,根据每个细胞的影响因子数来更新细胞的状态

3代码
/**
* @param {number[][]} board
* @return {void} Do not return anything, modify board in-place instead.
*/
var gameOfLife = function(board) {
let m = board.length;
let n = board[0].length;

function affect(i,j) {
if (board[i][j] % 10 === 0) return;

for (let x=i-1; x<=i+1; x++) {
for (let y=j-1; y<=j+1; y++) {
if (x === i && y === j || x < 0 || y < 0 || x >= m || y >= n) continue;
board[x][y] += 10;
}
}
}

function caculte(i,j) {
let num = board[i][j];
let k = Math.floor(num / 10);
if (num % 10 === 0) {
if ( k === 3) {
board[i][j] = 1;
} else {
board[i][j] = 0;
}
} else {
if (k < 2 || k > 3) {
board[i][j] = 0;
} else {
board[i][j] = 1;
}
}
}

for (let i=0; i<m; i++) {
for (let j=0; j<n; j++) {
affect(i,j);
}
}

for (let i=0; i<m; i++) {
for (let j=0; j<n; j++) {
caculte(i,j);
}
}
};

*长上升子序列(JS实现)

*长上升子序列(JS实现)

\
1 题目
给定一个无序的整数数组,找到其中*长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: *长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
可能会有多种*长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

链接:https://leetcode-cn.com/problems/longest-increasing-subsequence

2 思路
这道题明显根据题意就知道应该用动态规划来做,注意题意,这里是子序列并不是要求连续的,设d[i]为0…i元素之间*大上升子序列长度,状态转移方程为 d[i+1] = max(d[0…i]) + 1

3代码
/**
* @param {number[]} nums
* @return {number}
*/
var lengthOfLIS = function(nums) {
if (nums.length < 2) return nums.length;
const d = [1];

let maxAns = 1;
for (let i=1; i<nums.length; i++) {
let len = 0;
for (let j=0;j<d.length;j++) {
if (nums[i] > nums[j]) {
len = Math.max(len, d[j]);
}
}
d[i] = len + 1;
maxAns = Math.max(maxAns, d[i])
}

return maxAns;
};

二维区域和检索 – 矩阵不可变(JS实现)

二维区域和检索 – 矩阵不可变(JS实现)

1 题目
给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2)。
上图子矩阵左上角 (row1, col1) = (2, 1) ,右下角(row2, col2) = (4, 3),该子矩形内元素的总和为 8。
示例:
给定 matrix = [
[3, 0, 1, 4, 2],
[5, 6, 3, 2, 1],
[1, 2, 0, 1, 5],
[4, 1, 0, 1, 7],
[1, 0, 3, 0, 5]
]
sumRegion(2, 1, 4, 3) -> 8
sumRegion(1, 1, 2, 2) -> 11
sumRegion(1, 2, 2, 4) -> 12
说明:
你可以假设矩阵不可变。
会多次调用 sumRegion 方法。
你可以假设 row1 ≤ row2 且 col1 ≤ col2。

链接:https://leetcode-cn.com/problems/range-sum-query-2d-immutable

2 思路
这道题可以用动态规划来做,首先sumRegion(2, 1, 4, 3)可以分割为sumRegion(0, 0, 4, 3) – sumRegion(0, 0, 4, 1) – sumRegion(0, 0, 2, 3) + sumRegion(0, 0, 2, 1),因此我只需计算d[i][j],d[i][j]为左上角为num[0][0],右下角为num[i][j]子矩阵的和。状态转移方程为d[i+1][j] = d[i][j] + sumRow(i+1, j), 其中 sumRow(i,j)为第i行0…j的和

3代码
/**
* @param {number[][]} matrix
*/
var NumMatrix = function(matrix) {
this.d = [];
let rows = matrix.length;
if (rows === 0) return;
let cols = matrix[0].length;

for (let i=0; i<rows; i++) {
this.d[i] = [];
let sumRow = 0;
for (let j=0; j<cols; j++) {
sumRow += matrix[i][j];
this.d[i][j] = i > 0 ? this.d[i-1][j] + sumRow : sumRow;
}
}
};

/**
* @param {number} row1
* @param {number} col1
* @param {number} row2
* @param {number} col2
* @return {number}
*/
NumMatrix.prototype.sumRegion = function(row1, col1, row2, col2) {
let area = 0;
if (this.d.length === 0) return area;
if (col1 > 0) {
area -= this.d[row2][col1-1];
}

if (row1 > 0) {
area -= this.d[row1-1][col2];
}

if ( col1 > 0 && row1 > 0) {
area += this.d[row1-1][col1-1];
}

return this.d[row2][col2] + area;
};

/**
* Your NumMatrix object will be instantiated and called as such:
* var obj = new NumMatrix(matrix)
* var param_1 = obj.sumRegion(row1,col1,row2,col2)
*/

累加数(JS实现)

累加数(JS实现)

1 题目
累加数是一个字符串,组成它的数字可以形成累加序列。
一个有效的累加序列必须至少包含 3 个数。除了*开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和。
给定一个只包含数字 ‘0’-‘9’ 的字符串,编写一个算法来判断给定输入是否是累加数。
说明: 累加序列里的数不会以 0 开头,所以不会出现 1, 2, 03 或者 1, 02, 3 的情况。
示例 1:
输入: “112358”
输出: true
解释: 累加序列为: 1, 1, 2, 3, 5, 8 。1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8
示例 2:
输入: “199100199”
输出: true
解释: 累加序列为: 1, 99, 100, 199。1 + 99 = 100, 99 + 100 = 199

链接:https://leetcode-cn.com/problems/additive-number

2 思路
这道题用递归的方法,依次回溯累加即可,比较讨厌的是,要注意处理0的情况,递归函数d(i,j,k,s),其中i为指向当前*个数的开头字符,j指向第二个数的开头字符,k为第三个数的开头字符

3代码
/**
* @param {string} num
* @return {boolean}
*/
var isAdditiveNumber = function(num) {
if (num.length < 3) return false;

let i=0;
for (let j=i+1; j<num.length-1;j++) {
for (let k=j+1; k<num.length; k++) {
if (d(i,j,k,num)) return true;
}
}

return false;

function d(i,j,k,s) {
if (k === s.length) return true;
if (s[i] === ‘0’ && j > i + 1) return false; //*个数字不是0,但以0开头
if (s[j] === ‘0’ && k > j + 1) return false; //第二个数字不是0,但以0开头
let num1 = parseInt(s.slice(i,j));
let num2 = parseInt(s.slice(j,k));

for (let m=k+1; m<=s.length; m++) {
if (s[k] === ‘0’ && m > k+1) return false; //第三个数字不是0,但以0开头
let num3 = parseInt(s.slice(k,m));
if (num1 + num2 === num3) {
return d(j,k,m,s);
} else if (num1 + num2 < num3) { //若前两个数已经小于第三个数,则提前结束
return false;
}
}

return false;
}
};

区域和检索 – 数组可修改(JS实现)

区域和检索 – 数组可修改(JS实现)

1 题目
给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。
update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。
示例:
Given nums = [1, 3, 5]
sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8
说明:
数组仅可以在 update 函数下进行修改。
你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。

链接:https://leetcode-cn.com/problems/range-sum-query-mutable

2 思路
这道题用动态规划的方法来做即可,在更新数组元素值时,也要更新dp数组

3代码
/**
* @param {number[]} nums
*/
var NumArray = function(nums) {
this.d = [];
this.nums = nums;
let sum = 0;

for (let i=0; i<nums.length; i++) {
sum += nums[i];
this.d[i] = sum;
}
};

/**
* @param {number} i
* @param {number} val
* @return {void}
*/
NumArray.prototype.update = function(i, val) {
let diff = val – this.nums[i];
for (let j=i; j<this.d.length; j++) {
this.d[j] += diff;
}
this.nums[i] = val;
};

/**
* @param {number} i
* @param {number} j
* @return {number}
*/
NumArray.prototype.sumRange = function(i, j) {
return this.d[j] – (i > 0 ? this.d[i-1] : 0);
};

/**
* Your NumArray object will be instantiated and called as such:
* var obj = new NumArray(nums)
* obj.update(i,val)
* var param_2 = obj.sumRange(i,j)
*/

*小高度树(JS实现)

*小高度树(JS实现)

1 题目
对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有*小高度的树被称为*小高度树。给出这样的一个图,写出一个函数找到所有的*小高度树并返回他们的根节点。
格式
该图包含 n 个节点,标记为 0 到 n – 1。给定数字 n 和一个无向边 edges 列表(每一个边都是一对标签)。
你可以假设没有重复的边会出现在 edges 中。由于所有的边都是无向边, [0, 1]和 [1, 0] 是相同的,因此不会同时出现在 edges 里。
示例 1:
输入: n = 4, edges = [[1, 0], [1, 2], [1, 3]]
0
|
1
/
2 3
输出: [1]
示例 2:
输入: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2
\ | /
3
|
4
|
5
输出: [3, 4]
说明:
根据树的定义,树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。
树的高度是指根节点和叶子节点之间*长向下路径上边的数量。

链接:https://leetcode-cn.com/problems/minimum-height-trees

2 思路
这道题考察图的遍历,每次从图的*外层节点开始,删除图外层节点(入度为1的节点),直到图中没有节点,*后一次删除的节点就是*内层的根节点

3代码
/**
* @param {number} n
* @param {number[][]} edges
* @return {number[]}
*/
var findMinHeightTrees = function(n, edges) {
if (edges.length === 0) { //对于没有边的情况,每个节点都是根节点
let res = [];
for (let i=0; i<n; i++) {
res.push(i);
}
return res;
}
const map = {};

for (let edge of edges) { //建立图结构
if (!map[edge[0]]) {
map[edge[0]] = [];
map[edge[0]].len = 0;
}
if (!map[edge[1]]) {
map[edge[1]] = [];
map[edge[1]].len = 0;
}
map[edge[0]].push(edge[1]);
map[edge[1]].push(edge[0]);
map[edge[0]].len++;
map[edge[1]].len++;
}

let arr = Object.keys(map).filter(key => map[key].len === 1);

let temp = [];
let visited = {};
let res = arr.slice();
while(arr.length > 0 || temp.length > 0) {
if (arr.length === 0) {
arr = temp;
temp = [];
res = arr.slice();
}
let p = arr.shift();
if (visited[p]) continue;
visited[p] = true;
for (let edge of map[p]) { //将下一次外层节点推入
if (–map[edge].len === 1) temp.push(edge);
}
}

return res;
};

*佳买卖股票时机含冷冻期(JS实现)

*佳买卖股票时机含冷冻期(JS实现)

1 题目
给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。​
设计一个算法计算出*大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
示例:
输入: [1,2,3,0,2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]

链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown

2 思路
这道题是股票系列的变种, 动态规划d[i][j],代表第i天持有状态为j的*大利润,状态转移方程d[i][0] = Math.max(d[i-1][0], d[i-1][1] + prices[i])、d[i][1] = Math.max(d[i-1][1], d[i-2][0] – prices[i]),注意由于股票有冷冻期,因此只能买入第i-2天的股票

3代码
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
if (prices.length === 0) return 0;
const d = [];
const min = Number.MIN_SAFE_INTEGER;

for (let i=0; i<prices.length; i++) {
if (!d[i]) d[i] = [];
d[i][0] = 0;
d[i][1] = 0;
}

for (let i=0; i<prices.length; i++) {
if (i === 0) { //*天特殊处理
d[0][0] = 0;
d[0][1] = -prices[i];
continue;
}
if (i === 1) { //第二天情况特殊处理
d[i][0] = Math.max(d[i-1][0], d[i-1][1] + prices[i]);
d[i][1] = Math.max(d[i-1][1], -prices[i]);
continue;
}
d[i][0] = Math.max(d[i-1][0], d[i-1][1] + prices[i]);
d[i][1] = Math.max(d[i-1][1], d[i-2][0] – prices[i]);
}

return d[prices.length-1][0];

};

*大单词长度乘积(JS实现)

*大单词长度乘积(JS实现)

1 题目
给定一个字符串数组 words,找到 length(word[i]) * length(word[j]) 的*大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0。
示例 1:
输入: [“abcw”,“baz”,“foo”,“bar”,“xtfn”,“abcdef”]
输出: 16
解释: 这两个单词为 “abcw”, “xtfn”。
示例 2:
输入: [“a”,“ab”,“abc”,“d”,“cd”,“bcd”,“abcd”]
输出: 4
解释: 这两个单词为 “ab”, “cd”。
示例 3:
输入: [“a”,“aa”,“aaa”,“aaaa”]
输出: 0
解释: 不存在这样的两个单词。

链接:https://leetcode-cn.com/problems/maximum-product-of-word-lengths

2 思路
这道题的关键点在于如何快速判断两个单词是否有公共字符,因此就想到了利用位运算,我们可以将一个单词转换为数字,a代表1,b代表2,c代表4依次类推,注意相同的字符只加一次,判断两个单词是否有公共字符时只需将两个数字作&运算看结果是否为0即可,当然可能有多个单词转换后的数字相同,但我们只需要*长单词的长度即可

3代码
/**
* @param {string[]} words
* @return {number}
*/
var maxProduct = function(words) {
let map = {};

for (let word of words) {
let bit = count(word);
if (map[bit]) { //只保留*大长度
map[bit] = Math.max(map[bit], word.length);
} else {
map[bit] = word.length;
}
}

let wordBits = Object.keys(map);

let max = 0;
for (let i=0; i<wordBits.length; i++) {
for (let j=i+1; j<wordBits.length; j++) {
if ((parseInt(wordBits[i]) & parseInt(wordBits[j])) === 0) {
max = Math.max(max, map[wordBits[i]] * map[wordBits[j]]);
}
}
}

return max;

function count(word) { //计算单词的对应的数字
let sum = 0;
let startIndex = ‘a’.charCodeAt(0);
let map1 = {};

for (let alpha of word) {
if (map1[alpha]) continue;
map1[alpha] = true;
sum += 1 << (alpha.charCodeAt() – startIndex);
}

return sum;
}
};

ios BLE通讯遇到的问题

错误log:
As: Error Domain=CBATTErrorDomain Code=3 “Writing is not permitted.” UserInfo={NSLocalizedDescription=Writing is not permitted.}

// 这里的type类型有两种 CBCharacteristicWriteWithResponse CBCharacteristicWriteWithoutResponse,它的属性枚举可以组合
[self.selectedPeripheral writeValue:sendData forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
iOS API:
typedef NS_ENUM(NSInteger, CBCharacteristicWriteType) {
CBCharacteristicWriteWithResponse = 0,
CBCharacteristicWriteWithoutResponse,
};
如果设置为WithResponse,则可以写成功一次,如果为WithoutResponse,则一次也不能写成功。
Ios上BLE开发总结:

蓝牙传输所用的框架是<CoreBluetooth/CoreBluetooth.h>

蓝牙连接需要中心管理者和外部设备,我们所做的开发基本是围绕中心管理来的;
蓝牙设备发过来的每个数据包,为了保证数据在传输的时候没有丢失,一般需要包头,包尾,校验和
有很多蓝牙协议很复杂,需要把数据转化成二进制进行转化解析,对于高字节,低字节,小端模式,大端模式,符号位,位运算这些基本概念需要了解清楚

1.关于Mac地址的获取

自iOS7之后,苹果不支持获取Mac地址,只能用UUID来标识设备,要注意的是同一个设备在不同手机上显示的UUID不相同,但有的设备可以通过 “180A”这个服务来发现特征,再来读取 “2A23”这个特征值,可以获得Mac地址。如果你的蓝牙设备不支持这样获取,你可以跟硬件工程师沟通,来获得Mac地址,添加一个获取地址命令或者增加一个含地址的特征值都可以很容易的获取。上面获取地址的前提都是需要先建立连接,如果一定要在扫描的时候获得Mac地址,让硬件工程师把数据写入广播包里,看是否可行;

2.蓝牙连接流程
建立中心设备管理者
扫描外设
连接外设
扫描外设中的服务
扫描外设中的特征
订阅或读取特征值
获取外设中的数据

建立中心设备管理者

// 创建之后会马上检查蓝牙的状态,nil默认为主线程
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]

蓝牙线程没必要去开异步线程,在主线程消耗不了什么性能

扫描外设

// 蓝牙状态发生改变,这个方法一定要实现
– (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
// 蓝牙状态可用
if (central.state == CBCentralManagerStatePoweredOn) {

// 如果蓝牙支持后台模式,一定要指定服务,否则在后台断开连接不上,如果不支持,可设为nil, option里的CBCentralManagerScanOptionAllowDuplicatesKey默认为NO, 如果设置为YES,允许搜索到重名,会很耗电
[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]] options:nil];
}
}
连接外设

/**
* 发现设备
* @param peripheral 设备
* @param advertisementData 广播内容
* @param RSSI 信号强度
*/
– (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
{
// 判断是否是你需要连接的设备
if ([peripheral.name isEqualToString:kPeripheralName]) {
peripheral.delegate = self;
// 一定要记得把外设保存起来
self.selectedPeripheral = peripheral;
// 开始连接设备
[self.centralManager connectPeripheral:self.selectedPeripheral options:nil];
}
}
扫描外设中的服务

/**
* 已经连接上设备
*/
– (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
// 停止扫描
[self.centralManager stopScan];
// 发现服务
[self.selectedPeripheral discoverServices:nil];
}
扫描外设中的特征

/**
* 已经发现服务
*/
– (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
for (CBService *service in peripheral.services) {
if ([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID]]) {
// 根据你要的那个服务去发现特性
[self.selectedPeripheral discoverCharacteristics:nil forService:service];
}

// 这里我是根据 180A 用来获取Mac地址,没什么实际作用,可删掉
if ([service.UUID isEqual:[CBUUID UUIDWithString:@”180A”]]) {
[self.selectedPeripheral discoverCharacteristics:nil forService:service];
}
}
}
订阅或读取特征值

/**
* 已经发现特性
*/
– (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
for (CBCharacteristic *characteristic in service.characteristics) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@”2A23″]]) {
// 这里是读取Mac地址, 可不要, 数据固定, 用readValueForCharacteristic, 不用setNotifyValue:setNotifyValue
[self.selectedPeripheral readValueForCharacteristic:characteristic];
}

if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicUUID]]) {
// 订阅特性,当数据频繁改变时,一般用它, 不用readValueForCharacteristic
[peripheral setNotifyValue:YES forCharacteristic:characteristic];

// 获取电池电量
unsigned char send[4] = {0x5d, 0x08, 0x01, 0x3b};
NSData *sendData = [NSData dataWithBytes:send length:4];

// 这里的type类型有两种 CBCharacteristicWriteWithResponse CBCharacteristicWriteWithoutResponse,它的属性枚举可以组合
[self.selectedPeripheral writeValue:sendData forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];

/*
characteristic 属性
typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {
CBCharacteristicPropertyBroadcast                                              = 0x01,
CBCharacteristicPropertyRead                                                   = 0x02,
CBCharacteristicPropertyWriteWithoutResponse                                   = 0x04,
CBCharacteristicPropertyWrite                                                  = 0x08,
CBCharacteristicPropertyNotify                                                 = 0x10,
CBCharacteristicPropertyIndicate                                               = 0x20,
CBCharacteristicPropertyAuthenticatedSignedWrites                              = 0x40,
CBCharacteristicPropertyExtendedProperties                                     = 0x80,
CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)        = 0x100,
CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)  = 0x200
};
*/

NSLog(@”%@”,characteristic);
// 打印结果为 <CBCharacteristic: 0x1702a2a00, UUID = FFF6, properties = 0x16, value = (null), notifying = NO>

//  我的结果 为 0x16  (0x08 & 0x16)结果不成立, (0x04 & 0x16)结果成立,那写入类型就是 CBCharacteristicPropertyWriteWithoutResponse
}
}
}
获取外设中的数据

/**
* 数据更新的回调
*/
– (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
// 这里收到的数据都是16进制,有两种转换,一种就直接转字符串,另一种是转byte数组,看用哪种方便

// 直接转字符串
NSString *orStr = characteristic.value.description;
NSString *str = [orStr substringWithRange:NSMakeRange(1, orStr.length – 2)];
NSString *dataStr = [str stringByReplacingOccurrencesOfString:@” ” withString:@””];
NSLog(@”dataStr = %@”,dataStr);

// 转Byte数组
Byte *byte = (Byte *)characteristic.value.bytes;

//_______________________________________________________________________________________________________________
// 解析你的协议,附几个解协议或许能用到的函数
}
设备连接断开

– (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
// 让它自动重连
[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]] options:nil];
}
这是系统代理方法,如果要主动断开需要调用  – (void)cancelPeripheralConnection:(CBPeripheral *)peripheral; 这个方法

写入数据成功的回调

– (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
// 读取数据
[self.selectedPeripheral readValueForCharacteristic:characteristic];
}
如果类型是CBCharacteristicWriteWithoutResponse,不会走这个方法;

需要注意的地方:
1、代理方法- (void)centralManagerDidUpdateState:(CBCentralManager *)central;一定要调用,否则会报错,这个方法只要设置中心设备的代理之后,就一定会走,我们*开始的扫描外设应放在这个方法里;
2、如果蓝牙支持要支持后台模式,只需要去把蓝牙后台模式打开

记住只要勾选Uses Bluetooth LE accessories就行了,别勾选Acts As a Bluetooth LE accessory,除非你把你的手机当做外部设备使用;

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速