表示一个折线图的最少线段数

简介: 🎈每天进行一道算法题目练习,今天的题目是“表示一个折线图的最少线段数”。

说在前面

🎈每天进行一道算法题目练习,今天的题目是“表示一个折线图的最少线段数”。

问题描述

给你一个二维整数数组 stockPrices ,其中 stockPrices[i] = [dayi, pricei] 表示股票在 dayi 的价格为 pricei 。折线图 是一个二维平面上的若干个点组成的图,横坐标表示日期,纵坐标表示价格,折线图由相邻的点连接而成。比方说下图是一个例子:\

image.png
请你返回要表示一个折线图所需要的 最少线段数 。\
示例 1:

image.png

输入:stockPrices = [[1,7],[2,6],[3,5],[4,4],[5,4],[6,3],[7,2],[8,1]]
输出:3

解释:

上图为输入对应的图,横坐标表示日期,纵坐标表示价格。
以下 3 个线段可以表示折线图:
- 线段 1 (红色)从 (1,7) 到 (4,4) ,经过 (1,7) ,(2,6) ,(3,5) 和 (4,4) 。
- 线段 2 (蓝色)从 (4,4) 到 (5,4) 。
- 线段 3 (绿色)从 (5,4) 到 (8,1) ,经过 (5,4) ,(6,3) ,(7,2) 和 (8,1) 。
可以证明,无法用少于 3 条线段表示这个折线图。

示例 2:

image.png

输入:stockPrices = [[3,4],[1,2],[7,8],[2,3]]
输出:1

解释:

如上图所示,折线图可以用一条线段表示。

提示:

1 <= stockPrices.length <= 10^5
stockPrices[i].length == 2
1 <= dayi, pricei <= 10^9
所有 dayi 互不相同 。

思路分析

读完题目之后,我们可以知道题目是要我们计算给出的一个折线图最少需要使用多少条线段来组成。\
输入参数stockPrices = [[3,4],[1,2],[7,8],[2,3]]表示折线图的4个端点坐标。\
我们需要计算出这四个端点形成的折线图由多少条线段组成。
首先我们需要思考一个问题:什么情况下的点集合可以使用一条线段来表示?转换一下问题描述,我们可以这样说,什么情况下n点会共线?这个问题可以简化为:什么情况下3点会共线?\
这个问题是不是就变得相对简单了?我们可以通过斜率来判断3点是否共线,两点可以确定一条直线,且直线的斜率为(y2-y1) / (x2-x1)。所以我们可以比较(y3-y2) / (x3-x2) 是否会与(y2-y1) / (x2-x1)即可。但是我们都知道除法往往会有精度缺失的问题出现,所以我们可以不进行除法运算,直接将两个斜率化简,比较两个斜率是否相等即可。\
分数化简我们可以通过最大公约数来化简,求两数的最大公约数如下:

function gcd (a, b) {
    if(b === 0) return 1;
    return a % b === 0 ?  b : gcd(b, a % b);
}

分数化简即将分子分母同时除于最大公约数即可

function simple(x,y){
    const g = gcd(x,y);
    return x / g + '/' + y / g;
}

这里还有一点需要我们注意,就是入参所给的点集合并不是按照日期排好序的,我们需要先对其进行排序后再进行计算

stockPrices = stockPrices.sort((a, b) => {
    return a[0] - b[0];
});

完整代码如下:

AC代码

/**
 * @param {number[][]} stockPrices
 * @return {number}
 */
var minimumLines = function (stockPrices) {
  if (stockPrices.length <= 1) return 0;
  function gcd (a, b) {
      if(b === 0) return 1;
    return a % b === 0 ?  b : gcd(b, a % b);
  }
  function simple(x,y){
      const g = gcd(x,y);
      return x / g + '/' + y / g;
  }
  let res = 1;
  stockPrices = stockPrices.sort((a, b) => {
    return a[0] - b[0];
  });
  let y = stockPrices[1][1] - stockPrices[0][1];
  let x = stockPrices[1][0] - stockPrices[0][0];
  for (let i = 2; i < stockPrices.length; i++) {
    let ty = stockPrices[i][1] - stockPrices[i - 1][1];
    let tx = stockPrices[i][0] - stockPrices[i - 1][0];
    if (simple(x,y) != simple(tx,ty)) {
      y = ty;
      x = tx;
      res++;
    }
  }
  return res;
};

说在后面

🎉这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,平时也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。
目录
相关文章
|
安全 UED
再次上演“空间魔法”,方太重新定义水槽洗碗机的能力边界
9月25日,方太在北京品牌超级体验店发布了全新一代水槽洗碗机Y系列,引发广泛关注。这款产品集水槽、洗碗机、果蔬净化机于一体,解决了传统洗碗机安装复杂、空间占用大等问题,尤其适合中国家庭厨房。自2015年推出首代水槽洗碗机以来,方太通过创新设计,如双层可翻转水流清洗系统和自动顶门透气干燥系统,大幅提升用户体验。此次Y系列不仅解决了洗锅难题,还增加了多功能料理台功能,进一步优化了厨房空间利用。方太凭借持续的技术创新和对中国家庭需求的深刻理解,成功引领了洗碗机市场的变革。
154 0
|
存储 数据采集 SQL
软考-系统架构设计师-3
数据库系统
255 3
|
编解码 算法 安全
推荐一款国产多通道肌电采集芯片及肌电模块
推荐一款国产多通道肌电采集芯片及肌电模块
|
存储 分布式计算 Hadoop
Hadoop的高扩展性
【4月更文挑战第13天】Hadoop展现高扩展性通过集群规模和节点资源水平、垂直扩展,适应TB至PB级大数据处理。支持云服务,实现按需自动扩展,降低成本,确保企业在灵活处理大规模数据时,满足复杂分析需求,助力业务决策。开源特性使构建与扩展数据处理能力更为经济高效。
260 1
|
传感器 监控 安全
工业控制系统】ICS (工业控制系统)安全简介第3 部分
工业控制系统】ICS (工业控制系统)安全简介第3 部分
|
安全 网络虚拟化
华为ensp模拟器 三层交换机
先用vlan把用户隔离开,再用三层交换机,将隔离的用户连起来。隔离:隔离的是故障连通:连通的是正常通信运用三层交换机实现。用LSW2交换机将两台pc机隔开,划分到不同的vlan里。再用LSW1交换机将两台pc机连接。这样两台pc机就不能直接通过LSW2交换机通信(隔离病毒的传播),而是需要通过LSW1这个交换机实现通信(实现通信)。 2、将连接pc机的接口设置为access接口(设置前要进入该接口 int命令) 3、将接口划分进入vlan里(设置前要进入该接口) 4、将连接另一台交换机的
华为ensp模拟器 三层交换机
|
机器人 测试技术 Python
Robot Framework(4)- 测试套件的基本使用
Robot Framework(4)- 测试套件的基本使用
702 0
Robot Framework(4)- 测试套件的基本使用
|
SQL HIVE 数据格式
|
Java 数据库连接 数据库
H2 Database入门
H2 Database做为轻量级的内嵌数据库,功能十分强大,而且运行时只需要一个jar包即可,下表是官网的描述: 更详细的对比见官网页面: http://www.h2database.com/html/features.
1830 0