贪心算法:最长回文串和无重叠区域

499 阅读2分钟

这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战

最长回文串

题目地址:   leetcode-cn.com/problems/lo…

题目描述:

给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。

在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。

注意: 假设字符串的长度不会超过 1010。

示例

输入:
"abccccdd"

输出:
7

解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7

题目分析

本题是一道简单级别的leetcode题,其实思路也非常简单,构建回文串,除中间外左右两边都需要相等,所以中间字符可以单个,但是其他字符都需要成双成对。

搜先将字符串变成数组,并且进行排序。然后设定一个标准target,默认为数组第一个值.

然后从数组第二值开始遍历,如果当前值与target相同,则target赋空,并计数+1.

在最后的返回值时,要注意计数需要*2,并且如果字符串总长度大于结果,需要+1,因为还可以在中间放单个字符。

最长回文1.png

最长回文2.png

代码

var longestPalindrome = function(s) {
    let sArr = s.split('').sort(), len1 = s.length, target = sArr[0];
    let nums = 0;
    for(let i = 1; i < len1; i++) {
        if(sArr[i] == target) {
            nums++;
            target = '';
        } else {
            target = sArr[i];
        }
    }
    if (nums*2 < len1) {
        return nums*2 + 1;
    } else {
        return len1;
    }
};


无重叠区域

题目地址: leetcode-cn.com/problems/no…

题目描述:

给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。

注意:

可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。

示例

输入: [ [1,2], [2,3], [3,4], [1,3] ]

输出: 1

解释: 移除 [1,3] 后,剩下的区间没有重叠。
输入: [ [1,2], [1,2], [1,2] ]

输出: 2

解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。

题目分析

本题其实与一道射箭题目类似,贪心通过各个区间的边界极限值来计算得到需要减少的区间。

首先对数组按照各个区间的右边界进行排序,设置right变量为第一个右边界值。

对数组进行循环,如果right> 数组[1]的左边界值,说明重叠了,记录has+1。否则不重叠,并把right设置为数组[1]的右边界值

最终结果为has

无重叠区域.png

代码

let newArr = intervals.sort((a,b)=>{
    return a[1] - b[1];
});

let right = newArr[0][1], has = 0;
for(let i = 1; i < newArr.length; i++) {
    if (newArr[i][0] < right) {
        has++;
    } else {
        right = newArr[i][1];
    }
}
return has;