上题目
题目介绍:
给你一个整数 n
,请你每隔三位添加点(即 "." 符号)作为千位分隔符,并将结果以字符串格式返回。
示例 1:
输入: n = 987 输出: "987"
示例 2:
输入: n = 123456789 输出: "123.456.789"
方案一:将数字转为字符串、分割转为数组,反转拼接
Up Code ~ 一起都在码里面~
/** * @method thousandSeparator1 * @description 千位分割数 - split、reverse、reduce * @param n number * @returns string */ function thousandSeparator1(n: number): string { // 1. 将数值n转为字符串 const s = n.toString(); // 2. 使用split分割字符串,转为数组;使用reverse反转数组 const arr = s.split('').reverse(); // 3. 使用reduce,依次拼接每个数组单元 return arr.reduce((prev, val, index) => { // 千分位,每隔三位拼接一个符号 // 同时要注意index为0时,第一个符号不 if (index % 3 === 0 && index !== 0) { return val + '.' + prev; } else { return val + prev; } }, ''); }
算法复杂度:
- 空间复杂度:产生的数组
arr
是随着n的长度增大而增大的,复杂度为O(n)O(n)O(n)
- 时间复杂度:在函数内部使用
split
、reverse
、reduce
方法,其复杂度肯定是 > O(n)O(n)O(n)的
方案二:倒序遍历,使用额外变量记录已拼接字符长度
将数字转为字符串后,从字符串尾部开始遍历,使用额外变量tmpLength
记录已经拼接的字符串长度,tmpLength % 3
的值作为是否拼接分隔符的条件
/** * @method thousandSeparator2 * @description 千位分割数 - 倒序遍历,额外遍历记录已拼接字符长度 * @param n number * @returns string */ function thousandSeparator2(n: number): string { // 数值转为字符串,分割,反转数组,重新拼接 const s = n.toString(); let newS = ''; // 记录已拼接字符长度 - 这里是刨除千位分隔符. let tmpLength = 0; // 索引从s.length - 1开始,倒序 for (let i = s.length - 1; i >= 0; i--) { // 千位分割数的拼接条件:已拼接字符 % 3 === 0 // 同时排除第一个字符 tmpLength === 0时的情况 if (tmpLength % 3 === 0 && tmpLength !== 0) { // 拼接千位分割数 newS = s[i] + '.' + newS; } else { // 直接拼接 newS = s[i] + newS; } // 注意这里的长度累加,表示已经拼接的字符数量 tmpLength++; } return newS; }
算法复杂度:
- 空间复杂度:O(1)O(1)O(1),并没有什么特别的;
- 时间复杂度:一层循环,O(n)O(n)O(n)没啥好说的;
性能对比
将千位分隔执行200W次,看下性能对比
console.time('thousandSeparator1'); for (let i = 0; i < 200 * 10000; i++) { thousandSeparator1(1000000000); } console.timeEnd('thousandSeparator1'); console.time('thousandSeparator2'); for (let i = 0; i < 200 * 10000; i++) { thousandSeparator2(1000000000); } console.timeEnd('thousandSeparator2'); 复制代码
网络异常,图片无法展示
|
从事实说话,方案二:倒序遍历,使用额外遍历记录已拼接字符长度这种方式肯定是更优的了!