今日LeetCodeで質問をして少し得したのでここに記録しておきます。簡単な質問、簡単な説明で、いくつかの点が得られ、それらの点がすべて直線上にあるかどうかを判断します。(タイトルと記事の最後にあるリンクを参照してください)。
私が最初に考えることは、最初の 2 点の傾きを求め、次に後続のすべての点と最初の点の傾きをそれぞれ求め、それらが等しいかどうかを比較し、等しくない場合は直接 false を返すことです。最終的にすべてが等しい場合は true を返します。ここで、傾きが必要な場合は割り算が必要で、割り算では分子が0かどうかを判断する必要があります。したがって、私の具体的な方法は次のとおりです。
1. 最初の点と 2 番目の点の横座標が同じかどうかを判断します。同じ場合は2へ進みます。そうでない場合は、3 に進みます。
2. 残りの点の横座標が最初の点と同じかどうかを判断し、途中で同じでない場合は false を返します。それ以外の場合は、終了時に true を返します。
3. 最初の点と 2 番目の点の傾き K を計算し、残りの点と最初の点の傾きK i K_iをそれぞれ計算します。K私はそしてそれがKに等しいかどうかを判断します。途中で等しくない場合は false を返し、等しくない場合は終了後に true を返します。
私の解決策は次のとおりです。
class Solution {
public:
bool checkStraightLine(vector<vector<int>>& coordinates) {
int len = coordinates.size();
if(len <= 2)
return true;
if(coordinates[0][0] == coordinates[1][0])//如果前两个数x相同,则判读后面的数x是否都和第一个相同
{
for(int i = 2;i < len;++i)
if(coordinates[i][0] != coordinates[0][0])
return false;
}
else
{
//计算两点的斜率,然后判断后面每个点和第一个点的斜率,如果出现不相同则false
float k = (coordinates[1][1] - coordinates[0][1]) * 1.0 / (coordinates[1][0] - coordinates[0][0]);
for(int i = 2;i < len;++i)
{
if((coordinates[i][1] - coordinates[0][1]) * 1.0 / (coordinates[i][0] - coordinates[0][0]) != k)
return false;
}
}
return true;
}
};
問題が終わった後、解き方を見に行ったところ、割り算と0による割り算の判定を回避できる非常に興味深い方法を発見しました。実際、彼は非常に賢い変換を行っただけで、その後、傾きが等しいかどうかを判断するのではなく、傾きの公式を変形させます。たとえば、最初に判断したのは( y 2 − y 1 ) / ( x 2 − x 1 ) = = ( yi − y 1 ) / ( xi − x 1 ) (y_2 - y_1)/(x_2 - x_1) = でした。 =( y_i - y_1)/(x_i - x_1)( y2−y1) / ( ×2−バツ1)==( y私は−y1) / ( ×私は−バツ1)を相互乗算して、( y 2 − y 1 ) ∗ ( xi − x 1 ) = = ( yi − y 1 ) ∗ ( x 2 − x 1 ) (y_2 - y_1)*(x_i - x_1 ) を判断します。 ==(y_i - y_1)*(x_2-x_1)( y2−y1)∗( ×私は−バツ1)==( y私は−y1)∗( ×2−バツ1) . 以下は、変更されたソリューションです。
class Solution {
public:
bool checkStraightLine(vector<vector<int>>& coordinates) {
int len = coordinates.size();
if(len <= 2)
return true;
//为了避免除法和除零的判断,可以转变为乘法,乘法效率比除法高
int preDx = coordinates[1][0] - coordinates[0][0],preDy = coordinates[1][1] - coordinates[0][1],dx,dy;
for(int i = 2;i < len;++i)
{
dx = coordinates[i][0] - coordinates[0][0];
dy = coordinates[i][1] - coordinates[0][1];
if(dy * preDx != dx * preDy)
return false;
}
return true;
}
};
この質問は、後者の方法の効率が大幅に向上したことを意味するものではありませんが、考え方を柔軟に変えることを教えてくれました。掛け算に変換してみよう、やっても同じこともある、一方向で良い結果が得られなかったのなら、逆に考えてみるとまた違った経験ができるかもしれません。
元のタイトルとリンク:
在一个 XY 坐标系中有一些点,我们用数组 coordinates 来分别记录它们的坐标,其中 coordinates[i] = [x, y] 表示横坐标为 x、纵坐标为 y 的点。
请你来判断,这些点是否在该坐标系中属于同一条直线上,是则返回 true,否则请返回 false。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/check-if-it-is-a-straight-line
例 1:
输入:coordinates = [[1,2],[2,3],[3,4],[4,5],[5,6],[6,7]]
输出:true
例 2:
输入:coordinates = [[1,1],[2,2],[3,4],[4,5],[5,6],[7,7]]
输出:false
ヒント:
- 2 <= 座標.長さ <= 1000
- 座標[i].length == 2
- -10^4 <= 座標[i][0]、座標[i][1] <= 10^4
- 座標内に重複した点はありません