文章目录
题目来源于牛客网前端专题:
https://www.nowcoder.com/ta/front-end?page=1
https://www.nowcoder.com/ta/js-assessment
一、创建对象
遍历对象+判断对象类型+指针引用嵌套的对象空间
1.根据包名,在指定空间中创建对象
题目描述
根据包名,在指定空间中创建对象
输入描述:
namespace({a: {test: 1, b: 2}}, ‘a.b.c.d’)
输出描述:
{a: {test: 1, b: {c: {d: {}}}}}
原题:https://www.nowcoder.com/practice/a82e035501504cedbe881d08c824a381?tpId=2&tqId=10854&tPage=1&rp=1&ru=/ta/front-end&qru=/ta/front-end/question-ranking
function namespace(oNamespace, sPackage) {
var arr = sPackage.split(".");//按顺序储存属性值
var obj = oNamespace;//新建指针指向对象
for (var i = 0; i < arr.length; i++) {//遍历属性值
//对象中没有该属性,或者对象中该属性是一个基础数据结构
if (!obj.hasOwnProperty(arr[i]) || !(obj[arr[i]] instanceof Object)) {
obj[arr[i]] = {};//给该属性赋值空对象
}
//将指针指向这个内部对象
obj = obj[arr[i]];
}
return oNamespace;//因为obj只是对原对象的引用,原对象已被修改,最后返回原对象的值
}
namespace({ a: { test: 1, b: 2 } }, "a.b.c.d");
二、借助对象/Map对象
新建对象+遍历输入值,将key和频率插入对象+遍历对象获取需要的key进行操作
1.字符串中的第一个唯一字符(leetcode 387. First Unique Character in a String)
题目描述,点击查看原题
Given a string, find the first non-repeating character in it and return it’s index. If it doesn’t exist, return -1.
方法一:indexOf
和lastIndexOf
比较(性能较差)
思路:
- 遍历字符串
- 条件一:如果字符串
indexOf
和lastIndexOf
相等代表字符唯一, - 条件二:不为-1代表字符存在,
&&
连接两个条件。满足条件返回索引值:
var firstUniqChar = function(s) {
for(let i in s){
//index和lastIndex
if(s.indexOf(s[i]) === s.lastIndexOf(s[i])&&s.indexOf(s[i])!== -1){
return i;
}
}
return -1;
};
方法二:借助对象比较(性能较好)
思路:
- 新建对象map,
- 遍历输入值,将key和频率插入对象。
- 遍历对象获取需要的value进行操作
注意:
- 要寻找非重复字符串,就是要寻找
频率为1的key
,必须要先遍历数组/字符串,把所有的元素和频率都插入对象了以后,再遍历对象取value=1的key; - 但是寻找重复字符串,就是要寻找
对象里已经插入的key
,可以一边遍历数组/字符串,一遍查询对象中是否有对应的key,obj[key]不为空
,则代表该元素重复。
var firstUniqChar = function(s) {
//存放频率
map = {};
//遍历字符串,向map插入频率
for (let char of s) {
if (map[char]) {
map[char]++;
} else {
map[char] = 1;
}
}
//遍历对象
for (var key of Object.keys(map)) {
if (map[key] === 1) {
return s.indexOf(key);
}
}
return "-1";
};
2.字符流中第一个不重复的字符(牛客网:剑指 offer字符串专题)
[题目描述,点击查看原题](https://www.nowcoder.com/practice/00de97733b8e4f97a3fb5c680ee10720?tpId=13&tqId=11207&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。如果当前字符流没有存在出现一次的字符,返回#字符。
思路: 同上,按照要求拆分成三个方法:
//Init module if you need
var map = {};
function Init()
{
map = {};
// write code here
}
//Insert one char from stringstream
function Insert(ch)
{
if(map[ch]){
map[ch]++;
}else{
map[ch]=1;
}
// write code here
}
//return the first appearence once char in current stringstream
function FirstAppearingOnce()
{
// write code here
for (var char of ch) {
if (map[char] === 1) {
return char;
}
}
return "#";
}
3.两数之和(leetcode:1. Two Sum)
题目描述,点击查看原题
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
思路:
- 特殊情况: 数组长度小于1直接返回
- 先新建 map对象,Map是一组键值对的结构,具有极快的查找速度。
- 然后
forEach
遍历数组,向map插入元素和索引
。 - 最后遍历数组,查找map对象是否有
key===差值
,获取对应value(索引)j
- 如果
j && j !== i
,j存在,且j不能为自身索引i(自己+自己不允许),返回[i, j]
Object和Map:
- 一个Object的key只能是
字符串
或者Symbols
,但一个 Map 的键可以是任意值,包括函数、对象、基本类型。- Object中的key的顺序是
无序
的,Map 中的键值是有序
的,而。因此,当对它进行遍历时,Map 对象是按插入的顺序返回键值。- Object 的键值对个数只能
手动计算
,Map 可以通过size
属性直接获取键值对个数。- Map 可直接进行
for of
迭代,而 Object 的迭代需要先Object.keys(obj)
获取它的键数组,然后再进行for of
迭代。MDN文档 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map
var twoSum = function(nums, target) {
//新建map对象存放数组元素和索引
let map = new Map();
//数组长度小于1直接返回
if(nums.lenght<=1){
return [];
}
//遍历数组,向map插入元素和索引
nums.forEach((e, i) => map.set(e, i));
//遍历数组,查找map对象是否有key===差值
for (let i = 0; i < nums.length; i++) {
let j = map.get(target - nums[i]);
//j存在,且j不能为自身索引i(自己+自己不允许)
if (j && j !== i) {
return [i, j];
}
}
return [];
};
性能很好:
3.数组中第一个重复的数字(牛客网:剑指 offer数组专题)
题目描述,点击查看原题
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
思路:
- 特殊情况: 数组长度小于等于1直接返回
- 先新建 map对象,Map是一组键值对的结构,具有极快的查找速度。
- 然后一边
for of
遍历数组,一边查询map中是否有item的键值
。 - 如果有,代表item是重复元素,return
- 如果没有,代表第一次遍历item,
map.set(item, 1)
向map插入元素和频率1 - 遍历结束也没有查找到重复元素,return
function duplicate(numbers, duplication) {
// write code here
//这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
//函数返回True/False
if (numbers.lenght <= 1) {
return false;
}
var map = new Map();
for (let item of numbers) {
if (map.has(item)) {
duplication[0] = item;
return true;
}
map.set(item, 1);
}
return false;
}