Java演算法面試題(005) 求n邊形周長的k等分點座標(今日頭條)
題目
本題來自今天頭條的筆試:
有一個n邊形(P0, P1, ..., Pn), 每一條邊皆為垂直或水平線段。現給定數值k,以P0為起點將n邊形的周長分為k段,每段的長度相等,請列印出k等分點的座標(T0, T1, ..., Tk)的座標。
分析
首先,假設n邊形在二維平面的上,每個頂點具有X座標和Y座標。
其次,n邊形的邊具有特殊的性質,每條邊皆為垂直或水平線段。因此,如果我們計算線段長度時,可以通過線段端點的X座標或Y座標相減得到。
最後,由於需要計算n邊形周長和等分點座標,這需要計算兩個相鄰點的距離,考慮到這個特性,我們可以採用線性結構來進行儲存。
接下來我們分析一下具體實現。
Java實現
首先我們來實現表示n邊形頂點座標的類:
public class Coordinate {
private double x, y;
public Coordinate(double x, double y) {
super();
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
@Override
public String toString() {
return "x = " + x + ", y=" + y;
}
}
下面是n邊形的實現類:
public class Polygon {
private Coordinate[] coArray = null;
public Polygon(Coordinate[] array) {
coArray = array;
}
/**
* 計算多邊形邊長
*
* @return
*/
public double getPerimeter() {
double perimeter = 0;
for (int i = 0; i < coArray.length; i++) {
int next = i + 1;
// 如果最後一個頂點的話,需要計算和起點的距離
if (i == coArray.length - 1) {
next = 0;
}
// 計算每條邊的邊長
if (coArray[i].getX() == coArray[next].getX()) {
perimeter += Math.abs(coArray[i].getY() - coArray[next].getY());
} else {
perimeter += Math.abs(coArray[i].getX() - coArray[next].getX());
}
}
return perimeter;
}
public Coordinate[] getKDivid(int k) {
double perimeter = getPerimeter();
double divLen = perimeter / k;
double len = divLen;
Coordinate[] coordinates = new Coordinate[k];
int index = 0;
for (int i = 0; i < coArray.length; i++) {
int next = i + 1;
// 如果最後一個頂點的話,需要計算和起點的距離
if (i == coArray.length - 1) {
next = 0;
}
//判斷當前的邊是垂直還是水平方向
if (coArray[i].getX() == coArray[next].getX()) {
double distance = Math.abs(coArray[i].getY() - coArray[next].getY());
if (len < distance) {//當前邊上存在k等分點,而且存在多個的情況
//用來記錄距離當前線段起點距離
double base = 0;
while (len <= distance) {
if (coArray[i].getY() > coArray[next].getY()) {
coordinates[index] = new Coordinate(coArray[i].getX(), coArray[i].getY() - (len + base));
} else {
coordinates[index] = new Coordinate(coArray[i].getX(), coArray[i].getY() + (len + base));
}
base += len;
distance -= len;
len = divLen;
index++;
}
//len記錄了當前邊計算完k等分點後還剩餘多長
len = divLen - distance;
} else {
len -= distance;
}
} else { //處理垂直方向的情況
double distance = Math.abs(coArray[i].getX() - coArray[next].getX());
if (len < distance) {
double base = 0;
while (len <= distance) {
if (coArray[i].getX() > coArray[next].getX()) {
coordinates[index] = new Coordinate(coArray[i].getX() - (len + base), coArray[i].getY());
} else {
coordinates[index] = new Coordinate(coArray[i].getX() + (len + base), coArray[i].getY());
}
base += len;
index++;
distance -= len;
len = divLen;
}
len = divLen - distance;
} else {
len -= distance;
}
}
}
return coordinates;
}
}
實現上有幾個技巧:
1. 由於n邊形採用了線性陣列的儲存結構,在計算周長和k等分點的函式中,處理最後一條邊時,需要計算陣列最後一個節點和第一個節點的距離。我們使用了一個next索引變數來記錄下一個索引的位置,如果是最後一個節點,則下一個節點為第一個節點。
2. 在計算k等分點時,需要區分水平線段還是垂直線段,這個影響到座標的計算;另外需要考慮的時,可能存在一個線段上存在多個等分點的情況。
單元測試
設計一些測試用例來計算K等分點,這塊需要注意的是K等分點計算機浮點數表示可能和你手工計算出來的不同,需要做一下處理。
相關文章
- 今日頭條實習面試題解析面試題
- 今日頭條Android面試Android面試
- 「前端面試題系列1」今日頭條 面試題和思路解析前端面試題
- java程式設計師最難面試之“今日頭條”Java程式設計師面試
- 今日頭條程式設計題1 找"最大"點程式設計
- 記一次今日頭條面試面試
- 朝夕光年——今日頭條的“遊戲據點”遊戲
- Facebook 面試題 | 島的周長面試題
- java簡單的爬蟲(今日頭條)Java爬蟲
- 位元組跳動(今日頭條)推薦演算法實習生面試演算法面試
- Facebook 面試題 | 凸多邊形面試題
- 半年工作經驗今日頭條和美團面試題面經分享面試題
- 今日頭條招聘golang開發--薪酬 30-70kGolang
- 模仿今日頭條app開發遇到的問題APP
- 手記 《半年工作經驗今日頭條和美團面試題面經分享》面試題
- MDN新增“HTTP有條件請求”標頭HTTP
- Qt 求圓和橢圓上任意角度點的座標QT
- 今日頭條與一點資訊,誰能找到演算法匹諾曹的藍仙子演算法
- 今日頭條極速版和今日頭條有什麼區別?
- 第11周-八邊形Octagon類Go
- 【計算幾何】求線段相交交點座標
- Swift 4 - 模仿今日頭條Swift
- 今日頭條怎麼設定黑色背景?今日頭條app開啟深色模式的技巧APP模式
- 2020年開春最新面試!今日頭條 Android 面試題及答案 (已拿到 offer)Android面試題
- 今日頭條怎麼賺錢?頭條號的賺錢思路
- 今日頭條的小遊戲戰術遊戲
- (Java) 演算法題:2的N次方Java演算法
- 前端學習演算法3:一道來自頭條的面試題前端演算法面試題
- 今日頭條上央視新聞 很快今日頭條回應廣告“二跳”事件事件
- 推薦演算法是今日頭條的核心競爭力嗎?演算法
- 求多邊形凸包(線性演算法)--陳氏凸包演算法--演算法
- 深度解析某頭條的一道面試題面試題
- 高德面試題-座標轉化為最簡單的字串面試題字串
- 【三角函式】已知直角三角形的斜邊長度和一個銳角角度,求另外兩條直角邊的長度函式
- thinkphp仿今日頭條原始碼PHP原始碼
- AI領域我重點關注的幾個今日頭條號AI
- 今日頭條:2017今日頭條圖書閱讀大資料(附下載)大資料
- 一道java面試題,演算法,求大家幫忙解答!Java面試題演算法