数据结构转换题

286 阅读2分钟

求多叉树的最大深度

let tree = [
    {
        id: 1,
        children: [
            {
                id: 2,
                children: [
                    {
                        id: 3,
                        children: [
                            {
                                id: 4,
                            }
                        ]
                    }
                ]
            },
            {
                id: 5
            }
        ]
    },
    {
        id:6
    },
    {
        id: 7
    }
]
console.log(getNodeMaxDepth(tree, 1)) // 3
console.log(getNodeMaxDepth(tree, 2)) // 2
console.log(getNodeMaxDepth(tree, 5)) // 0
console.log(getNodeMaxDepth(tree, 6)) // 0
let const = new Map()
const getNodeMaxDepth = (tree, id) => {
  const getTreeMap = tree => {
    for (const node of tree) {
      map.set(node.id, node)
      node.children && getTreeMap(node.children)
    }
  }
  if (map.size === 0) {
    getTreeMap(tree)
  }
  const getMaxDepth = node => {
    if (!node || !node.children) return 0
    let max = 0

    for (const cnode of node.children) {
      max = Math.max(max, getMaxDepth(cnode))
    }
    return max + 1
  }

  return getMaxDepth(map.get(id))
}

1.对象转换


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

    function transform(entry) {
      var ret = {};
      Object.keys(entry).forEach(key => {
        const keys = key.split('.');
        keys.reduce((prev, curr, i) => {
            prev[curr] = i === keys.length - 1 ? entry[key] : (prev[curr] || {});
            return prev[curr];
        }, ret);
      });
      return ret;
  }
  
  
  // 从output转为entry
function convert(o) {
  var ret = {};
  (function inner(o, chain = '') {
    for (const key in o) {
      if (o.hasOwnProperty(key)) {
        var temp = chain;
        chain += `${key}.`;
        const element = o[key];
        if (Object.prototype.toString.call(element) !== '[object Object]' || !Object.keys(element).length) {
          ret[chain.substr(0, chain.length - 1)] = element;
        }  else {
          inner(element, chain);
          // 返回父节点的链
          chain = temp;
        }
      }
    }
  })(o)
  return ret;
}
  

2.大数相加

两个字符串整数
var a = '100000012314140000000000000003'
var b = '456789345678945678945678';

function add(a, b) {
    let l1 = [...a];
    let l2 = [...b];
    let max = Math.max(l1.length, l2.length);
    while (l2.length !== max) {
        l2.unshift(0);
    }
    while (l1.length !== max) {
        l1.unshift(0);
    }
    l1.reverse();
    l2.reverse();
    let m = 0;
    const ret =  l1.reduce((sum, c, i) => {
        let t = c + l2[i] + m;
        if (t >= 10) {
            m = 1;
            t -= 10
        } else {
            m = 0;
        }
            if (m > 0 && i === l1.length - 1) {
                return [...sum, t, m]
            }
            return [...sum, t,]
    }, [])
    return ret;
};
}

3.实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject

Promise.retry = async (promFn, max = 3) =>{
    const taskpool = [];
    while(max--) {
        taskpool.push(promFn);
    }
    const next = async () => {
        try {

            let task = taskpool.pop();
            console.log('剩余次数', taskpool.length)
            const ret = task && await task();
            taskpool.length = 0;
            return ret;
        } catch (error) {
            next();
        }
    }
    return next();
}

function promiseGenerator() {
    const n = Math.random();
    return new Promise((resolve, reject) => {
        console.log(n)
        setTimeout(() =>  n > 0.8 ? resolve(n) : reject(n));
    }, 1000);
}
Promise.retry(promiseGenerator);

4.不用加减乘除运算符,求整数的7倍

var n = 10
Array.from({length: 7}).fill(n).reduce((a, b) => a + b, 0)

5.求两数之和

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例:

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

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

function calc(arr, target) {
    var n = 0;
    var map = new Map();
    map.set(arr[0], n);
    while(n++ <= arr.length) {
        var rest =  target - arr[n];
        if (map.has(rest)) {
            return [map.get(rest), n]
        } else {
            map.set(rest, n);
        }
    }
}

6.数组分类

var arr = [1,2,3,5,6, 8, 9, 10, 13, 15, 17];

转换成=> [[1,2,3], [5, 6], [8,9,10], [13], [15], [17]]; 递增为1的放在一起

function sort(randomArr) {
    return [...new Set(randomArr.sort((a, b) => a - b))].reduce((prev, curr) => {
        var last = prev[prev.length -1];
        if (Array.isArray(last)) {
            var lastele = last[last.length -1];
            if (lastele - curr === -1) {
                prev.pop();
                return [...prev, [...last, curr]]
            }
        }
        return [...prev, [curr]]
    }, []);
}

LazyMan

微信图片_20220113101926.jpg

Scheduler

class Scheduler {
    taskpool = [];
    limit = 2;
    add(promise) {
        return new Promise((resolve) => {
            this.taskpool.push(async() => {
                await promise();
                resolve();
            })
        })
    }

    start() {
        while(this.limit--) {
            this.next();
        }
    }

    async next() {
        if(this.taskpool.length) {
            await this.taskpool.shift()();
            this.next();
        }
    }
}

const timeout = time => new Promise(rs => setTimeout(rs, time))

const scheduler = new Scheduler();

const addTask = async (time, order)=> {
    await scheduler.add(() => timeout(time));
    console.log(order);
}


addTask(1000, 1);
addTask(2000, 2);
addTask(1000, 3);
addTask(1000, 4);
// 1s后输出1 
// 2s后输出2, 3
// 3s后输出4
scheduler.start();

scheduler失败重试

<script>
  class Scheduler {
    constructor(max = 6) {
      this.max = max;
      this.taskPool = [];
    }

    pushTask(promiseFn) {
      return new Promise((resolve, reject) => {
        this.taskPool.push({
          request: promiseFn,
          exector: { resolve, reject },
        });
      });
    }

    async next() {
      if (!this.taskPool.length) return;
      const task = this.taskPool.shift();
      const { request, exector } = task;

      try {
        const res = await request();
        exector.resolve(res);
        this.next();
      } catch (error) {
        exector.reject(error);
        this.next();
      }
    }

    run() {
      let max = this.max;
      while (max-- > 0) {
        this.next();
      }
    }
  }

  // 假装是一个耗时请求
  const req = () => {
    return new Promise((rs, rj) => {
      setTimeout(() => {
        const n = Math.random() * 100;
        if (n > 20) {
          rs(n);
        } else {
          rj(n);
        }
      }, 500);
    });
  };

  var scheduler = new Scheduler();

  // 假装并发
  for (let i = 0; i < 20; i++) {
    scheduler.pushTask(req).then(console.log);
  }

  scheduler.run();

  setTimeout(() => {
    scheduler.pushTask(req).then(console.log);
    scheduler.run();
  }, 3000);
</script>

carbon.png