(小)算法题(长期更新)

class Queue{
    container = []

    enter(element){
        this.container.push(element)
    }
    leave(){
        return this.container.shift()
    }

    size(){
        return this.container.length
    }
    value(){
        return this.container
    }
}

function game(n, m){
    let qe = new Queue
    // 把人放到队列
    for(var i=0; i<n; i++){
        qe.enter(i+1)
    }
    while(qe.size() > 1){
        for(var j=0;j<m-1; j++){
           qe.enter(qe.leave())
        }

        qe.leave()
    }

    return qe.value().toString()
    
    
}

console.log(game(5, 3))

 



把十进制数字转换为二进制

class Stack{
    container = []

    enter(element){
        this.container.unshift(element)
    }
    leave(){
        this.container.shift()
    }

    size(){
        this.container.length
    }
    value(){
        return this.container
    }
}

Number.prototype.decimal2binary = function decimal2binary(){
    let sk = new Stack  
 
    let decimalNum = this.valueOf()

    if(decimalNum === 0) return '0'
    while(decimalNum > 0){
         sk.enter(decimalNum % 2)

        decimalNum = Math.floor(decimalNum / 2)
    }

    return sk.value().join('')
    
}
var num=59
console.log(num.decimal2binary())

 





1.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

var twoSum = function(nums, target){
    let res = new Map()
    for(var i=0,len=nums.length;i<len;i++){
        if(res.has(target - nums[i])) return [res.get(target-nums[i]), i]

        res.set(nums[i], i)
    }

    console.log(res)
}


twoSum([2,5,7,8,9], 15)
(2) [2, 3]

------------------------------------------------------------------------------------

// 类似给定数组,找出最大差值,最大的这个差值都是以右边 - 左边得出来的 如:var arr = [4,2,7,5,11,13,8,1] 当中最大差值是9 11-2 = 9
var arr = [4,2,7,5,11,13,8,1]
function maxDiff(arr){
  if(arr.length<=1) return NaN
  let min = Math.min(arr[0], arr[1])
  let maxDiff = arr[1]-arr[0]

   for(let i=0; i<arr.length; i++){
    if(arr[i] > min) {
      maxDiff = Math.max(maxDiff, arr[i]-min)
    } else min = arr[i]
   }

   return maxDiff

}
console.log(maxDiff(arr))

[4,2,7,5,11,13,9,1].reduce((result, item, index, data) => Math.max(result, ...[...data].slice(0, index).map(v => item -v)));

[4,2,7,5,11,13,9,1].reduce((result, item, index, data) => Math.max(result, item - Math.min(...[...data].slice(0,index))));

 

 

// 给定一个整数无序数组和变量sum,如果存在数组中任意两项和使等于sum 的值,则返回true。否则 false 

//例如数组 [3,5,1,4] 和sum=9

const findSum = (arr, sum) =>
arr.some((set => n => set.has(n) || !set.add(sum - n))(new Set));

 

var findSum = (arr, sum)=> arr.some((function(set){
  return function (n){
    return set.has(n) || !set.add(sum - n)
  }
})(new Set))


 第三大的数

var thirdMax = function(nums){
    nums.sort((a, b)=> b-a)

      let map = new Map
    for(let i = 0,len=nums.length; i<len; i++){
        let cur = nums[i]    
        if(!map.get(cur)){
            map.set(cur, 1)
            if(map.size === 3) return cur
        }
    }

    return nums[0]
}

console.log(thirdMax([2,3]))

 

2.递归案例:求一个数字,各个位数上的数字 和: 123  ---> 6

function getEverySum(x){
    if(x<10) return x
    return x % 10 + getEverySum(parseInt(x/10))
}
console.log(getEverySum(564564))

 

3. 数组  var arr = ['1-2', '2-8', '1-3', '2-4', '6-10', '2-5']

 转换成:[ {key: 1, values: [2 , 3]}, {key: 2, values: [8, 4, 5]}, {key: 6, values: [10]}]

var arr = ['1-2', '2-8', '1-3', '2-4', '6-10', '2-5']
var fn = arr => {
    var res = []
    var obj = arr.reduce((pre, cur)=> {
        var [k, v] = cur.split('-')
        pre[k] ? pre[k].push(v): pre[k] = [v]
        return pre
    }, {})

    for(const [key, values] of Object.entries(obj)){
        res.push({key, values})
    }
// arr.map(v => v.split('-')).reduce((pre, [k, v])=> {
      (pre[k] = pre[k] || []).push(v)
return pre
     }, {})

// return Object.entries(obj).map(([key, values])=> ({key, values}))
return res } console.log(fn(arr))

 

4.实现一个sum方法使其有以下表现

sum(2,3).valueOf()           //5
    
sum(2,3,4).valueOf()         //9
    
sum(2,3)(4).valueOf()        //9
    
sum(2,3,4)(2)(3,4).valueOf() //18
// sum() 的结果可以继续使用 () 运算符,说明 sum() 返回的是一个函数(函数/函数表达式/箭头函数的统称);另外,这个返回值还有 valueOf() 方法,所以可以先搭个框
function sum() {
    const fn = () => {};
    fn.valueOf = () => {};
    return fn;
}

function sum(...args) {
    const r = args.reduce((a, b) => a + b);

    const fn = (...args) => {
        return sum(r, ...args);
    };

    fn.valueOf = () => r;
    return fn;
}
------------------------------------------------------------------------------
// 类似 fn(1).value = 1 fn(1)(2).value = 5 fn(1)(2)(3).value = 14

function fn(){
  const a = function(m){
   a.value = m*m
    return a
  }
  a.value = 1
  return a
}






 

5.递归修改json的key值

var dataObject = {
    "1": {
        "name": "第一级1",
        "type": "第一级2",
        "describe": "第一级3",
        "testNum": "第一级4",
        "1-1": {
            "name": "第二级5",
            "type": "第二级6",
            "describe": "第二级7",
            "testNum": "第二级8",
            "1-1-1": {
                "name": "第三级9",
                "type": "第三级q",
                "describe": "第三级w",
                "testNum": "第三级e"
            }
        }
    }
};
// 将里面的1-1,1-1-1,1-2之类的值修改成对应的name字段里面的值,需要替换成下面这种的:
var dataObject = {
        "第一级1": {
            "name": "第一级1",
            "type": "第一级2",
            "describe": "第一级3",
            "testNum": "第一级4",
            "第二级5": {
                "name": "第二级5",
                "type": "第二级6",
                "describe": "第二级7",
                "testNum": "第二级8",
                "第三级9": {
                    "name": "第三级9",
                    "type": "第三级q",
                    "describe": "第三级w",
                    "testNum": "第三级e"
                },
                "第三级r": {
                    "name": "第三级r",
                    "type": "第三级ty",
                    "describe": "第三级y",
                    "testNum": "第三级y"
                }
            }
        }
}
function generate(obj) {
  let _obj = {}
  Object.entries(obj).forEach(([key, value]) => {
    if (typeof value !== 'object') {
      _obj[key] = value
    } else {
      _obj[value.name] = generate(value)
    }
  })
  return _obj
}

var res = generate(dataObject)
console.log(res)

 

 6. 输入一个值获取最近的值,并返回

var arr = [
["IP-1", 0],
["IP-2", 13],
["IP-3", 68],
["IP-4", 138],
["IP-5", 149],
["IP-6", 834],
["IP-7", 1090],
["IP-8", 1247],
["IP-9", 1310],
["IP-10", 1956],
["IP-11", 2270],
["IP-12", 3337],
]
// 出入 200,返回 IP-7
var res = function (value) {
  // 设置一个 map
   const map = new Map() 
   // 设置每个 绝对值 和 name
   arr.forEach(x => {
        const number = Math.abs(value - x[1])
        map.set(number, x[0])
    })
    // 得到 map里面最小的 value,得到名字
    return map.get(Math.min.apply(null, Array.from(map.keys())))
}
console.log(res(2000)) // IP-10

 

 7. 2个多维数组查找交集 打标识

var A = [
    {id: 1},
    {
        id: 2,
        children: [
            {id: 3},
            {id: 4},
            {
                id: 5,
                children: [{
                    id: 6
                }]
            }
        ]
    }
];
var B = [
    {id: 1},
    {
        id: 2,
        children: [{
            id: 5,
            children: [{
                id: 6
            }]
        }]
    }];
let c = method(A, B)
//结果
c = [
    {id: 1, disabled: true},
    {
        id: 2,
        disabled: true,
        children: [
            {id: 3},
            {id: 4},
            {
                id: 5,
                disabled: true,
                children: [{
                    id: 6,
                    disabled: true
                }]
            }
        ]
    }
];
function method (treeA, treeB) {
  return dfs(treeA, new Set(flat(treeB)))
}

function dfs (root, dict) {
  for (node of root) {
    if (dict.has(node.id)) {
      node.disabled = true
    }
    if (node.children) {
      dfs(node.children, dict)
    }
  }
  return root
}

function flat (root, path = []) {
  for (node of root) {
    path.push(node.id)
    if (node.children) {
      flat(node.children, path)
    }
  }
  return path
}

 

8.查找对象的上一级

var arr = [
    {
        check: false,
        child: [
            {
                check: false,
                child: [
                    {
                        check: true,
                    },
                    {
                        check: true
                    }
                ]
            },
            {
                check: false,
                child: [
                    {
                        check: true,
                    },
                    {
                        check: false,
                    }
                ]
            }
        ]
    },
]

// 实现结果:
var res= [
    {
        check: false,
        child: [
            {
                check: true,
                child: [
                    {
                        check: true,
                    },
                    {
                        check: true
                    }
                ]
            },
            {
                check: false,
                child: [
                    {
                        check: true,
                    },
                    {
                        check: false,
                    }
                ]
            }
        ]
    },
]

---------------------------------------

function check (root) {
  const _checkNode = x => x.check = x.child ? x.child.every(_checkNode) : x.check
  root.forEach(_checkNode)
  return root
}

var mapper = item => 
    [item.child
        && (item.check = (item.child = item.child.map(mapper))
            .filter(c => c.check).length === item.child.length)
    , item][1]
    
console.dir(arr.map(mapper));


 9

function Stack() {
  let items = [] // 存储数据
  
  // 从栈顶添加元素,也叫压栈
  this.push = function (item) {
    items.push(item)
  }
  
  // 弹出栈顶元素
  this.pop = function () {
    return items.pop()
  }
  
  // 返回栈顶元素
  this.top = function () {
    return items[items.length - 1]
  }
  
  // 判断是否为空
  this.isEmpty = function () {
    return items.length == 0
  }
  
  // 返回栈的大小
  this.size = function () {
    return items.length
  }
}

/*
* 思路:
* 遇到左括号,就把左括号压入栈中
* 遇到右括号,判断栈是否为空,为空说明没有左括号与之对应,缺少左括号,字符串括号不合法
* 如果不为空,则把栈顶元素移除,这对括号抵消了
*
* 当for循环结束后,如果栈是空,就说明所有的括号都抵消掉了
* 如果栈里还有元素,说明缺少右括号,字符串括号不合法
*
* */

-------------------------------
// 判断字符串里的括号是否合法
function is_leagl_brackets(string) {
  let stack = new Stack()
  for (var i=0; i< string.length; i++) {
    var cur = string[i]
    if (cur == '(') {
      stack.push(cur)
    } else if(cur == ')') {
      if (stack.isEmpty()) {
        return false
      } else {
        stack.pop()
      }
    }
  }
  
  return stack.isEmpty()
}

console.log('111------', is_leagl_brackets('fasdfadsf()(fdsa()fsa('))
console.log('222------', is_leagl_brackets('fasdfadsf()'))

--------------------------------------

// 逆波兰表达式,也叫后缀表达式,他将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式
// 例如(a+b)*(c+d) 转换为ab+cd+*
//示例 ['4', '13', '5', '/', '+' ]等价于 (4 + (13/5)) = 6
// 4 入栈
// 13 入栈
// 5 入栈
// 遇到了 / 连续两次弹出栈顶元素 a b   b / a = c  c入栈
// 遇到 +   连续两次弹出栈顶元素 e f   e + f = 6  6入栈

function calc_exp(exp) {
  let stack = new Stack()
  
  for (let i = 0; i <exp.length; i++) {
    let cur = exp[i]
    if (['+', '-', '*', '/'].includes(cur)){
      let val1 = stack.pop(), val2 = stack.pop()
      let exp_str = val1 + cur + val2
      // 计算并取整
      var res = parseInt(eval(exp_str))
      // 计算结果压入栈中
      stack.push(res)
    } else stack.push(cur)
  }
  
  return stack.pop()
}
console.log('calc_exp(exp)------', calc_exp(['4', '13', '5', '/', '+' ]))

 10.

var entry = {
  a: {
    b: {
      c: {
        dd: "abcdd"
      }
    },
    d: {
      xx: "adxx"
    },
    e: "ae"
  }
};

// // 要求转换成如下对象
// var output = {
// "a.b.c.dd": "abcdd",
// "a.d.xx": "adxx",
// "a.e": "ae"
// }

// 这道题是典型的DFS。这里有个技巧,就是将res作为参数传过去,
// 从而子函数(helper)可以对其进行修改。 这样我们可以不必依赖返回值,
// 也就避免了很多判断。

function helper(entry, prefix, res) {
  for (const key in entry) {
    if (entry[key] instanceof Object) {
      helper(entry[key], `${prefix}.${key}`, res);
    } else {
      res[`${prefix.slice(1)}.${key}`] = entry[key];
    }
  }
}

function format(entry) {
  const res = {};
  helper(entry, "", res);
  return res;
}

console.log(format(entry));

 11.

 list = [
     {
      id: 1,
      label: 'a',
      children: [{
        id: 4,
        label: 'b',
        children: [{
          id: 9,
          label: 'c'
        }, {
          id: 10,
          label: 'd'
        }]
      }]
    }
 ]
 
 // 怎么根据label = c的条件 拿到 id为9的这条属性

varfind = (list, label) => {
  let result;
  for (let i = 0; i < list.length; i++) {
    const item = list[i];
    if (item.label === label) {
      return result = item;
    } else {
      if (item.children) {
        result = find(item.children, label);
      }
    }
  }
  return result;
};

var result = find(list, "c");
console.log(result);

 

12 求众数

给定一个大小为n的数组,找到其中的众数。众数是指在数组中出现次数大于 n / 2 的元素 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

网络释义
Maxdiff: 最大偏差

 

posted @ 2019-04-08 09:31  慕斯undefined  阅读(160)  评论(0编辑  收藏  举报