[路飞]_力扣算法题练习三:二叉树的深度、平衡二叉树、搜索插入位置、罗马数字转整数、反转字符串

268 阅读4分钟

二叉树的深度

力扣链接

输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。

例如:

给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3 。


var maxDepth = function(root) {
    var deep = 0
    if(!root) return 0
    var maxValue = 0;
    const stack = []
    function treeDeep(root, deep) {
        var node = root
        if (node.left) {
            treeDeep(node.left, deep + 1)
        }
        if (node.right) {
            treeDeep(node.right, deep + 1)
        }
        if (!node.left && !node.right) {
            if ((deep + 1) > maxValue) {
                maxValue = deep + 1
            }
        }
    }
    treeDeep(root, deep)
    return maxValue
};

平衡二叉树

力扣链接

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

balance_1.jpg

输入: root = [3,9,20,null,null,15,7]
输出: true
  • 获取左右字数深度对比,递归每个节点
var isBalanced = function(root) {
    if (!root) return true
    function maxDeep(root, deep) {
        if(!root) return 0
        var maxValue = 0;
        const stack = []
        function treeDeep(root, deep) {
            var node = root
            if (node.left) {
                treeDeep(node.left, deep + 1)
            }
            if (node.right) {
                treeDeep(node.right, deep + 1)
            }
            if (!node.left && !node.right) {
                if ((deep + 1) > maxValue) {
                    maxValue = deep + 1
                }
            }
        }
        treeDeep(root, deep)
        return maxValue
    }
    function NodeIsBalaced(root){
        const left = maxDeep(root.left0)
        const right = maxDeep(root.right0)
        if (Math.abs(left - right) > 1) {
            return false
        }
        return true
    }
    var balanced = true;
    function checkAllNode(root){
        if(NodeIsBalaced(root)&&balanced){
            root.left&&checkAllNode(root.left)
            root.right&&checkAllNode(root.right)
        }else{
            balanced = false;
        }
    }
    checkAllNode(root)
    return balanced
};

搜索插入位置

力扣链接

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

示例 1:

输入: nums = [1,3,5,6], target = 5
输出: 2
var searchInsert = function(nums, target) {
    var len = nums.length
    if (len === 0) {
        return 0
    }
    if (target <= nums[0]) {
        return 0
    }
    if (target > nums[len - 1]) {
        return len
    }
    if (target === nums[len - 1]) {
        return len-1
    }
    if (len === 2) {
        return 1
    }
    var start = 0;
    var end = len - 1;
    var flag = true;
    while (flag) {
        var middle = (end + start) >> 1
        var pre = nums[middle - 1]
        var next = nums[middle + 1]
        if(nums[middle] === target){
            return middle
        }
        if (nums[middle] < target) {
            if (target === next) {
               return middle+1
            }else if(target < next){
                return middle+1
            }
        }
        if (target < nums[middle]) {
            if (pre < target) {
                return middle
            }else if(pre === target){
                return middle-1
            }
        }
        if (nums[middle] < target) {
            start = middle
        }
        if (nums[middle] > target) {
            end = middle
        }
    }
};

罗马数字转整数

力扣链接

罗马数字包含以下七种字符: I, V, X, LCD 和 M。

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000
例如, 罗马数字 2 写做 II ,即为两个并列的 112 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 49X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

 

示例 1:

输入: "III"
输出: 3

解:

var romanToInt = function (s) {
    var map = {
        'I'1,
        'V'5,
        'X'10,
        'L'50,
        'C'100,
        'D'500,
        'M'1000,
    }
    var doubleMap = {
        'IV'4,
        'IX'9,
        'XL'40,
        'XC'90,
        'CD'400,
        'CM'900,
    }
    if (s.length === 1) {
        return map[s]
    }
    if (s.length === 2) {
        if (doubleMap[s]) return doubleMap[s]
    }
    var total = 0
    s = s.replace('IV'function (item) {
        total += 4
        return ''
    })
    s = s.replace('IX'function (item) {
        total += 9
        return ''
    })
    s = s.replace('XL'function (item) {
        total += 40
        return ''
    })
    s = s.replace('XC'function (item) {
        total += 90
        return ''
    })
    s = s.replace('CD'function (item) {
        total += 400
        return ''
    })
    s = s.replace('CM'function (item) {
        total += 900
        return ''
    })
    var i = 0
    while(i < s.length){
        total+=map[s[i]]
        i++
    }
    return total
};

反转字符串

力扣链接

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例 2:

输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
  • 双指针
var reverseString = function(s) {
    if(s.length===1return s
    var startIndex = 0
    var endIndex = s.length-1
    while(startIndex<endIndex){
        var temp = s[startIndex]
        s[startIndex] = s[endIndex]
        s[endIndex] = temp
        startIndex++
        endIndex--
    }
    return s 
};