169竞赛

和为零的N个唯一整数

给你一个整数 n,请你返回 任意 一个由 n 个 各不相同 的整数组成的数组,并且这 n 个数相加和为 0 。

 

示例 1:

输入:n = 5
输出:[-7,-1,1,3,4]
解释:这些数组也是正确的 [-5,-1,1,2,3],[-3,-1,2,-2,4]。
示例 2:

输入:n = 3
输出:[-1,0,1]
示例 3:

输入:n = 1
输出:[0]
 

提示:

1 <= n <= 1000

 

/**
 * @param {number} n
 * @return {number[]}
 */
var sumZero = function(n) {
    let res = [];
    let start = 0;
    let p=0;
    while(n>1){
        start+=1;
        res.push(start, -start);
        n-=2;
    }
    if(n===1){
       res.push(0); 
    }
    return res;
};
/**
 * @param {number} n
 * @return {number[]}
 */
var sumZero = function(n) {
    const result = [];
    if (n % 2 === 1) result.push(0);
    for (let i = 1; result.length < n; i++) {
        result.push(i);
        result.push(-i);
    }
    return result;
};

这个写是写了,但是上面第一个是我写的,就是有点搞怪,明明循环一下就可以,我估计是当时并没有想到循环跳出的判断条件 result.length < n ,所以整了个while 循环,还行吧。

两棵二叉搜索树中的所有元素

给你 root1 和 root2 这两棵二叉搜索树。

请你返回一个列表,其中包含 两棵树 中的所有整数并按 升序 排序。.

 

示例 1:

 

输入:root1 = [2,1,4], root2 = [1,0,3]
输出:[0,1,1,2,3,4]
示例 2:

输入:root1 = [0,-10,10], root2 = [5,1,7,0,2]
输出:[-10,0,0,1,2,5,7,10]
示例 3:

输入:root1 = [], root2 = [5,1,7,0,2]
输出:[0,1,2,5,7]
示例 4:

输入:root1 = [0,-10,10], root2 = []
输出:[-10,0,10]
示例 5:

 

输入:root1 = [1,null,8], root2 = [8,1]
输出:[1,1,8,8]
 

提示:

每棵树最多有 5000 个节点。
每个节点的值在 [-10^5, 10^5] 之间。

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root1
 * @param {TreeNode} root2
 * @return {number[]}
 */
const dfs = (root, arr)=>{
    if(!root) return;
    arr.push(root.val)
    if(root.left){
        dfs(root.left, arr)
    }
    if(root.right){
        dfs(root.right, arr)
    }
}
const toList = (arr)=>{
    // let s = null;
    // let p = null;
    // s = p;
    // arr.forEach(a=>{
    //     let newObj = {
    //         val: a,
    //         next: null
    //     }
    //     p = newObj;
    //     p = p.next
    // })
    //  return s;
    let s = null;
    let p = null;
    arr.forEach((a, i)=>{
        let newObj = {
            val: a,
            next: null
        }
        // p = newObj;
        if(i===0){
            p = newObj;
            s=p
        }
        p.next = newObj;
        p = p.next
    })
     return s; 
    
}
var getAllElements = function(root1, root2) {
    let arr = [];
    dfs(root1, arr);
    dfs(root2, arr);
    // arr.sort() 默认排序有 0 还不对
    arr.sort((a, b)=> a-b)
   return arr;
};


解释: 这个题描述的有问题,说什么列表,我以为链表。转了层链表,开始还没转对,翻了了以前代码才转对。导致花费一些时间。还有这个sort函数,我用了默认sort(),这样是不行的,元素中出现2位以上数字是不行的,它会按照相同位的大小排序。

 

 

跳跃游戏 III

这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。

请你判断自己是否能够跳到对应元素值为 0 的 任意 下标处。

注意,不管是什么情况下,你都无法跳到数组之外。

 

示例 1:

输入:arr = [4,2,3,0,3,1,2], start = 5
输出:true
解释:
到达值为 0 的下标 3 有以下可能方案:
下标 5 -> 下标 4 -> 下标 1 -> 下标 3
下标 5 -> 下标 6 -> 下标 4 -> 下标 1 -> 下标 3
示例 2:

输入:arr = [4,2,3,0,3,1,2], start = 0
输出:true
解释:
到达值为 0 的下标 3 有以下可能方案:
下标 0 -> 下标 4 -> 下标 1 -> 下标 3
示例 3:

输入:arr = [3,0,2,1,2], start = 2
输出:false
解释:无法到达值为 0 的下标 1 处。
 

提示:

1 <= arr.length <= 5 * 10^4
0 <= arr[i] < arr.length
0 <= start < arr.length

/**
 * @param {number[]} arr
 * @param {number} start
 * @return {boolean}
 */
var canReach = function(arr, start) {
   let flag = false;
    let getZero = (arr, start, map=new Map())=>{
        if(arr[start] === 0){
            flag = true;
            return;
        }
        if(map.has(start)) return;
        map.set(start, 1);
        let plus = start+arr[start];
        let minus = start-arr[start];
        let len = arr.length;
        if(plus>=0 && plus <len ){
            // map.set(plus, 1);
            getZero(arr, plus, map)
            // map.set(plus, 1);
        }
        if( minus >= 0 && minus < len) {
             // map.set(minus, 1)
            getZero(arr, minus, map);
            // map.set(minus, 1)
        }
    }
    getZero(arr, start);
    return flag
};

这个在判断出现重复索引start 时,整错几个地方,就上面注释的地方,要么就是 栈溢出,要么就是 只递归一次就退出了。最后灵机一动放到了正确位置。

/**
 * @param {number[]} arr
 * @param {number} start
 * @return {boolean}
 */
var canReach = function(arr, start) {
    let l = 0;
    const r = [ start ];
    const a = new Array(arr.length).fill(0);
    a[start] = 1;
    while (l < r.length) {
        if (!arr[r[l]]) return true;
        if (r[l] - arr[r[l]] >= 0 && !a[r[l] - arr[r[l]]]) {
            r.push(r[l] - arr[r[l]]);
            a[r[l] - arr[r[l]]] = 1;
        }
        
        if (r[l] + arr[r[l]] < arr.length && !a[r[l] + arr[r[l]]]) {
            r.push(r[l] + arr[r[l]]);
            a[r[l] + arr[r[l]]] = 1;
        }
        l++;
    }
    return false;
};
/**
 * @param {number[]} arr
 * @param {number} start
 * @return {boolean}
 */
var canReach = function(arr, start) {
    if (arr[start] === 0) {
        return true
    }
    const n = arr.length
    let a = [start]
    let s = new Set()
    let i = 0
    while (i < a.length) {
        const x = a[i++]
        const w = x - arr[x]
        if (w >= 0 && !s.has(w)) {
            if (arr[w] === 0) {
                return true
            }
            s.add(w)
            a.push(w)
        }
        const y = x + arr[x]
        if (y < n && !s.has(y)) {
            if (arr[y] === 0) {
                return true
            }
            s.add(y)
            a.push(y)
        }
    }
    return false
};

 

口算难题

 

给你一个方程,左边用 words 表示,右边用 result 表示。

你需要根据以下规则检查方程是否可解:

  • 每个字符都会被解码成一位数字(0 - 9)。
  • 每对不同的字符必须映射到不同的数字。
  • 每个 words[i] 和 result 都会被解码成一个没有前导零的数字。
  • 左侧数字之和(words)等于右侧数字(result)。 

如果方程可解,返回 True,否则返回 False

 

示例 1:

输入:words = ["SEND","MORE"], result = "MONEY"
输出:true
解释:映射 'S'-> 9, 'E'->5, 'N'->6, 'D'->7, 'M'->1, 'O'->0, 'R'->8, 'Y'->'2'
所以 "SEND" + "MORE" = "MONEY" ,  9567 + 1085 = 10652

示例 2:

输入:words = ["SIX","SEVEN","SEVEN"], result = "TWENTY"
输出:true
解释:映射 'S'-> 6, 'I'->5, 'X'->0, 'E'->8, 'V'->7, 'N'->2, 'T'->1, 'W'->'3', 'Y'->4
所以 "SIX" + "SEVEN" + "SEVEN" = "TWENTY" ,  650 + 68782 + 68782 = 138214

示例 3:

输入:words = ["THIS","IS","TOO"], result = "FUNNY"
输出:true

示例 4:

输入:words = ["LEET","CODE"], result = "POINT"
输出:false

 

提示:

  • 2 <= words.length <= 5
  • 1 <= words[i].length, results.length <= 7
  • words[i], result 只含有大写英文字母
  • 表达式中使用的不同字符数最大为 10
/**
 * @param {string[]} words
 * @param {string} result
 * @return {boolean}
 */
var isSolvable = function(words, result) {
    let map = new Map();
    let arr = [0,1,2,3,4,5,6,7,8,9];
    let arr1 = [1,2,3,4,5,6,7,8,9];
    words.forEach((a)=>{
        let arr = a.split('');
        arr.forEach((b, i)=>{
            if(i===0){
               if(!map.has(b)){
                map.set(b, arr1)
                } 
            } else {
                if(!map.has(b)){
                map.set(b, arr)
                } 
            }
            
        })
    })
    result.split('').forEach((b, i)=>{
        if(i===0){
               if(!map.has(b)){
                map.set(b, arr1)
                } 
            } else {
                if(!map.has(b)){
                map.set(b, arr)
                } 
            }
    })
    
    words.forEach((a)=>{
        let arr = a.split('');
        arr.forEach((b, i)=>{
            map.get(b).forEach(c=>{
                  // 下面只能就是不定嵌套层级的循环,无解,要么拼字符串  
            })
            
        })
    })
    
    
};
/**
 * @param {string[]} words
 * @param {string} result
 * @return {boolean}
 */
var isSolvable = function(words, result) {
    const a = {};
    const l = [];
    const min = [];
    for (let i = 0; i < words.length; i++) {
        for (let j = 0; j < words[i].length; j++) {
            if (!a[words[i][j]]) {
                l.push(words[i][j]);
                min.push(0);
                a[words[i][j]] = l.length;
            }
            if (!j) min[a[words[i][j]] - 1] = 1;
        }
    }
    for (let i = 0; i < result.length; i++) {
        if (!a[result[i]]) {
            l.push(result[i]);
            min.push(0);
            a[result[i]] = l.length;
        }
        if (!i) min[a[result[i]] - 1] = 1;
    }
    const getL = new Array(10).fill(0);
    const v = new Array(l.length).fill(0);
    var dfs = function(d) {
        if (d === l.length) {
            let sum1 = 0;
            for (let i = 0; i < words.length; i++) {
                let sum = 0;
                for (let j = 0; j < words[i].length; j++) {
                    const ttt = v[a[words[i][j]] - 1];
                    if (!j && !ttt) return false;
                    sum = sum * 10 + ttt;
                }
                sum1 += sum;
            }
            let sum2 = 0;
            for (let i = 0; i < result.length; i++) {
                const ttt = v[a[result[i]] - 1];
                if (!i && !ttt) return false;
                sum2 = sum2 * 10 + ttt;
            }
            if (sum1 === sum2) return true;
        }
        for (let i = min[d]; i < 10; i++) {
            if (!getL[i]) {
                getL[i] = true;
                v[d] = i;
                if (dfs(d + 1)) return true;
                getL[i] = false;
            }
        }
        return false;
    }
    return dfs(0);
};
/**
 * @param {string[]} words
 * @param {string} result
 * @return {boolean}
 */
var isSolvable = function (words, result) {
    let letters = new Set()
    let leading = new Set()
    let left = {}
    let right = {}
    let p = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]
    for (let word of words) {
        let n = word.length
        for (let i = 0; i < n; i++) {
            const c = word[n - 1 - i]
            letters.add(c)
            if (c in left) {
                left[c] += p[i]
            } else {
                left[c] = p[i]
            }
        }
        leading.add(word[0])
    }
    let n = result.length
    for (let i = 0; i < n; i++) {
        const c = result[n - 1 - i]
        letters.add(c)
        if (c in right) {
            right[c] += p[i]
        } else {
            right[c] = p[i]
        }
    }
    leading.add(result[0])
    let a = Array.from(letters)
    let b = new Array(10)
    let d = {}
    b.fill(true)
    return dfs(a, a.length - 1, d, b, leading, left, right)
};

const dfs = (a, i, d, b, leading, left, right) => {
    if (i >= 0) {
        for (let x = leading.has(a[i]) ? 1 : 0; x < 10; x++) {
            if (b[x]) {
                b[x] = false
                d[a[i]] = x
                if (dfs(a, i - 1, d, b, leading, left, right)) {
                    return true
                }
                b[x] = true
            }
        }
        return false
    } else {
        let diff = 0
        for (c in left) {
            diff += d[c] * left[c]
        }
        for (c in right) {
            diff -= d[c] * right[c]
        }
        return diff === 0
    }
}

 

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/all-elements-in-two-binary-search-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

posted @ 2019-12-29 12:34  土豆zhang  阅读(161)  评论(0编辑  收藏  举报