持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
编程世界总是离不了算法
最近在看框架源码时,会有很多算法的实现逻辑,有时候会感到吃力
于是决定蹭着假期,加强算法和数据结构相关的知识
那怎么提升呢?
其实我知道算法这东西没有捷径,多写多练才能提升,于是我开启我的LeetCode刷题之旅
第一阶段目标是:200道,每天1到2篇
为了不乱,本系列文章目录分为三部分:
- 今日题目:xxx
- 我的思路
- 代码实现
今日题目:587. 安装栅栏
在一个二维的花园中,有一些用 (x, y) 坐标表示的树。由于安装费用十分昂贵,你的任务是先用最短的绳子围起所有的树。只有当所有的树都被绳子包围时,花园才能围好栅栏。你需要找到正好位于栅栏边界上的树的坐标。
示例 1:
输入: [[1,1],[2,2],[2,0],[2,4],[3,3],[4,2]] 输出: [[1,1],[2,0],[4,2],[3,3],[2,4]]
示例 2:
输入: [[1,2],[2,2],[4,2]]
输出: [[1,2],[2,2],[4,2]]
注意:
- 所有的树应当被围在一起。你不能剪断绳子来包围树或者把树分成一组以上。
- 输入的整数在 0 到 100 之间。
- 花园至少有一棵树。
- 所有树的坐标都是不同的。
- 输入的点没有顺序。输出顺序也没有要求。
来源:力扣(LeetCode) 链接:leetcode.cn/problems/er… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的思路
1。先排序所有的点,按坐标x值排序,如果x值一样按y值排。
2。先正序遍历,计算下半部分的凸包。
3。再倒序遍历,计算上半部分的凸包
代码实现
/**
* @param {number[][]} trees
* @return {number[][]}
*/
var outerTrees = function(trees) {
const n = trees.length;
const map = {};
for (let i = 0; i < n; i++) {
const items = map[trees[i][0]] || [];
items.push(trees[i][1]);
map[trees[i][0]] = items;
}
const sortArray = [];
for (const key in map) {
const items = map[key];
items.sort((a, b) => {
return b - a;
});
sortArray.push([key, items]);
}
sortArray.sort((a, b) => {
return a[0] - b[0];
});
const m = sortArray.length;
let topX = sortArray[0][0]; let topY = sortArray[0][1][0]; let bottomX = topX; let bottomY = sortArray[0][1][sortArray[0][1].length-1];
const res = [];
const topSelector = (topPoint, i, x) => {
const k1 = (topPoint - topY) / (x - topX);
let selected = true;
for (let a = i+1; a < m; a++) {
const k2 = (sortArray[a][1][0] - topY) / (sortArray[a][0] - topX);
if (k1 < k2) {
selected = false;
break;
}
}
if (selected) {
res.push([x, topPoint]);
topX = x;
topY = topPoint;
}
return selected;
};
const bottomSelector = (bottomPoint, i, x) => {
const k1 = (bottomPoint - bottomY) / (x - bottomX);
let selected = true;
for (let a = i+1; a < m; a++) {
const k2 = (sortArray[a][1][sortArray[a][1].length-1] - bottomY) / (sortArray[a][0] - bottomX);
if (k1 > k2) {
selected = false;
break;
}
}
if (selected) {
res.push([x, bottomPoint]);
bottomX = x;
bottomY = bottomPoint;
}
return selected;
};
for (let i = 0; i < m; i++) {
const x = sortArray[i][0];
const yArray = sortArray[i][1];
if (i === 0 || i === m-1) {
for (let j = 0; j < yArray.length; j++) res.push([x, yArray[j]]);
} else {
let topPoint;
let bottomPoint;
if (yArray.length === 1) {
if (Math.abs(yArray[0] - topY) <= Math.abs(yArray[0] - bottomY) && bottomY < yArray[0]) topPoint = yArray[0];
else bottomPoint = yArray[0];
} else {
topPoint = yArray[0];
bottomPoint = yArray[yArray.length-1];
}
if (topPoint !== undefined) {
topSelector(topPoint, i , x);
}
if (bottomPoint !== undefined) {
const flag = bottomSelector(bottomPoint, i , x);
if (topPoint === undefined && !flag) topSelector(bottomPoint, i , x);
}
}
}
return res;
};
总结
实现方式其实有很多,这里仅供参考~
由于刚开始刷题,也不知道从哪里刷好,如果前辈们有好的建议,希望不吝赐教,感谢🌹