一、如下是一个tree树的实现,写出结果:
var s=[];
var arr=s;
for(var i=0;i<3;i++){
var pusher = {
value: "item"+i
},tmp;
if(i!==2){
tmp = []
pusher.children = tmp
}
arr.push(pusher);
arr = tmp; // arr做了一个对象指针的移动,等于上一个children
}
console.log(s[0]);
// {
value: "item0",
children:[
{
value: "item1",
children:[{
value: "item2"
}]
}
]
}
二、查找如下有序数组中31出现的位置,最快的查找方法是什么,JavaScript怎么实现?
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
对于一个已经排好序的数组,最快定位的方法是二分查找
function find (arr, item) {
var low = 0; //设定下标
var high = arr.length - 1; // 设定上标
while (high >= low) {
var mid = Math.floor((low + high) / 2); //二分查找的关键
if (arr[mid] === item) {
return mid;
}else if (arr[mid] > item) {
high = mid;
} else if (arr[mid] < item){
low = mid;
}
}
return -1;
}
三、 用JavaScript实现数组的快速排序:
快速排序过程只需要三步:
- 1、在数据集中,选择一个元素作为“基准”(pivot)。(基准值可以任意选择,但是选择中间的值比较容易理解)
- 2、所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
- 3、对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
使用js数组方法及递归
function quickSort(arr) {
if(arr.length <= 1) return arr;
var index = Math.floor(arr.length / 2);
var key = arr.splice(index, 1)[0];
var left = [],right = [];
arr.forEach(function(v){
v <= key ? left.push(v) : right.push(v);
});
return quickSort(left).concat([key], quickSort(right));
}
四、写出单向链表和双向链表的添加和删除操作的实现过程。
单向链表的添加:
function insert(newElement, item){
var newNode = new Node(newElement); // 新建一个节点
var current = this.find(item); //找到item的位置(current在js中是引用,类似于C语言指针)
newNode.next = current.next; //将新节点的后继指向item的后继
current.next = newNode; // 修改item节点的后继指向新节点
}
单向链表的删除:
// 首先要找到删除元素的上一个节点
function findPrevious (item) {
var currentNode = this.head;
while (!(currentNode.next === null) && (currentNode.element !== item)) {
return currentNode;
}
}
function remove (item) {
var prevNode = this.findPrevious(item);
var currentNode = this.find(item); // 查找到当前要删除的节点
if (!(prevNode.next === null)) {
prevNode.next = prevNode.next.next; //待删除节点的前驱的后继 指向 原本待删除节点的后继
currentNode.next = null; // 释放节点,防止内存泄漏
}
}
双向列表的添加:
// 插入节点,注意插入的链指向
function insert(newElement, item){
var newNode = new Node(newElement); // 新建一个节点
var current = this.find(item); //找到item的位置
newNode.next = current.next; //将新节点的后继指向item的后继
newNode.previous = current;
current.next = newNode;
if (newNode.next !== null) {
newNode.next.previous = newNode; // 将item原本的位置的前驱指向新节点
}
}
双向链表的删除:
function remove (item) {
var currentNode = this.find(item);
if (!(currentNode === null)) {
currentNode.previous.next = currentNode.next; // 删除节点的前驱的后继,指向删除节点的后继
currentNode.next.previous = currentNode.previous; //删除节点的后继的前驱,指向删除节点的前驱
currentNode.next = null; // 释放节点,防止内存泄漏
currentNode.previous = null;
} else {
currentNode.previous.next = null; // 尾节点的前驱的后继指向null
currentNode.previous = null; // 释放尾节点
}
}
五、用代码实现二叉搜索树,写出相关方法查找最小值。
//定义节点
function Node(data, left, right) {
this.data = data;
this.left = left;
this.right = right;
}
// 插入值
function insert (data) {
var n = new Node(data, null, null); // 定义一个新节点
if(this.root === null) {
this.root = n;
} else {
var current = this.root;
var parent;
while (true) {
parent = current;
if (data < current.data) {
current = current.left; // 比当前值小就放左边
if (current === null) {
parent.left = n;
break;
}
} else { // 比当前值大就放右边
current = current.right;
if(current === null){
parent.right = n;
break;
}
}
}
}
}
// 找最小值
function getSmallest (root) {
// 一直往左子树上去找,找到没有左节点即找到了最小值
var current = this.root || root;
while (!(current.left === null)) {
current = current.left;
}
return current;
}
六、编写一个方法,求一个字符串的字节长度:
(一个英文字符占1个字节,一个中文字符占2个字节)
function getBytes(str) {
var len = str.length;
var bytes = len;
for (var i = 0; i< len; i++) {
if (str.charCodeAt(i) >= 128) { // 如果判断是中文字符就+1
bytes++;
}
}
return bytes;
}
七、找出一个正数数组的最大差值:
function getDifference(arr) {
var minValue = arr[0];
var maxDifference = 0;
for (var i = 0; i < arr.length; i++) {
var current = arr[i];
minValue = Math.min(minValue, current); // 用一个临时变量存较小的值
var difference = current - minValue;
maxDifference = Math.max(maxDifferent, potential);
}
return maxDifference;
}
ES6扩展运算符
function getDifference(arr){
var max = Math.max(...arr); // 找出最大值
var min = Math.min(...arr); // 找出最小值
return max - min;
}
数组sort排序
function getDifference(arr){
var arr = arr.sort();
var min = arr[0];
var max = arr[arr.length-1];
return maxDifference = max - min;
}
八、判断一个单词是否是回文:
(如mamam)
function isPalindrome(str) {
var len = str.length;
var start = Math.ceil(len / 2);
while (start < len) {
if(str[start] !== str[len - start - 1]) {
return false;
};
start++;
}
return true;
}
九、数组去重:
function unique(arr) {
var result = [];
arr.forEach(function(v){
if(result.indexOf(v) < 0) {
result.push(v);
}
});
return result;
}
十、计算字符串中出现次数最多的字母及次数:
function findMaxDuplicate(str){
if (str.length === 1) return str;
var charObj = {};
for(var i=0; i= maxValue) {
maxChar = k;
maxValue = charObj[k];
}
}
return '出现次数最多的是:'+ maxChar +',一共'+charObj[maxChar]+'次'
}
十一、写一个isPrime()函数,当其为质数时返回为true,否则返回false。
(质数:大于1且只能被1和它本身整除的数)
function isPrime(number) {
if (typeof number !== 'number' || !Number.isInteger(number)) {
return false;
}
if (number < 2) {
return false;
} else if (number === 2) {
return true;
} else if (number % 2 === 0) {
return false;
}
var squareRoot = Math.sqrt(number); // 求平方根
for(var i = 3; i <= squareRoot; i += 2) {
if (number % i === 0) {
return false;
}
}
return true;
}
十二、对下列字符串进行排序,按照字符串中的数字排序:
"hell2o wor5ld Compa1y T4est 3abc"
1.首先对给定字符串根据空格进行分割,毕竟数组比字符串更容易操作。
2.接着制定排序规则,哪个单词中包含的数字更大,排名就靠后。
3.然后,用数组的sort方法,传入排序规则匿名函数,进行定制排序。
4.最后,将sort后的数组进行聚合,返回字符串。
function FindNumber(str){
for(var i=0;i
十三、写一个flat函数将如下一个多层嵌套数组输出成字符串。
输入:['a', ['b', 'c'], 1, 2, ['d', 'e'], 'f', 3, 4]
输出:a, b, c, 1, 2, d, e, f, 3, 4
方法一:递归方法
var arr = ['a', ['b', 'c', ['d']], 1, 2, ['e', 'f'], 'g', 3, 4];
function flat (arr) {
var result = [];
var each = function (arr) {
arr.forEach(item => {
if (item instanceof Array) {
each(item);
} else {
result.push(item);
}
});
}
each(arr);
return result.join(',');
}
flat(arr);
方法二:toString格式转换
var arr = ['a', ['b', 'c', ['d']], 1, 2, ['e', 'f'], 'g', 3, 4];
Array.prototype.toString = function () {
return this.join(','); // 这里this就是arr数组
}
var flat = function (arr) {
return arr + '';
}
flat(arr);
十四、将1234567 变成 1,234,567,即千分位标注
// 方法一:
function exchange(num) {
num = String(num); // 转成字符串
if (num.length <= 3) {
return num;
}
num = num.replace(/\d{1,3}(?=(\d{3})+$)/g, (v) => {
return v + ',';
});
return num;
}
exchange(1234567) // 1,234,567
// 方法二
function format(num){
num = String(num); // 数字转字符串
var str=""; // 字符串累加
for(var i = num.length - 1, j=1; i>=0; i--, j++){
if(j%3 == 0 && i !== 0){ // 每隔三位加逗号,过滤正好在第一个数字的情况
str+=num[i]+","; // 加千分位逗号
continue;
}
str+=num[i]; // 倒着累加数字
}
return str.split('').reverse().join(""); // 字符串=>数组=>反转=>字符串
}
十五 、有100格台阶,可以跨1步可以跨2步,一共有多少种走法:
(本质是斐波那契数列)
function step(){
this.n1 = 1;
this.n2 = 2;
this.total = 100;
this.getFunction = getFunction;
}
var Stairs = new step();
function getFunction(){
for(i=2; i
十六、多维数组问题
1、多维数组转一维数组:
let arr = ['a', ['b', 'c'], 1, 2, ['d', 'e'], 'f', 3, 4]
arr.concat.apply([], arr) // ["a", "b", "c", 1, 2, "d", "e", "f", 3, 4]