Given the radius and x-y positions of the center of a circle, write a function randPoint
which generates a uniform random point in the circle.html
Note:git
randPoint
returns a size 2 array containing x-position and y-position of the random point, in that order.Example 1:github
Input:
["Solution","randPoint","randPoint","randPoint"]
[[1,0,0],[],[],[]] Output: [null,[-0.72939,-0.65505],[-0.78502,-0.28626],[-0.83119,-0.19803]]
Example 2:web
Input:
["Solution","randPoint","randPoint","randPoint"]
[[10,5,-7.5],[],[],[]] Output: [null,[11.52438,-8.33273],[2.46992,-16.21705],[11.13430,-12.42337]]
Explanation of Input Syntax:app
The input is two lists: the subroutines called and their arguments. Solution
's constructor has three arguments, the radius, x-position of the center, and y-position of the center of the circle. randPoint
has no arguments. Arguments are always wrapped with a list, even if there aren't any.dom
這道題給了咱們一個圓,包括中點位置和半徑,讓隨機生成圓中的任意一個點。這裏說明了圓上也看成是圓中,並且這裏的隨機意味着要等機率。思緒飄回了高中時代,努力搜索着那一絲絲殘留的記憶,終於,博主把還給老師的知識又要了回來,圓的方程表示爲 (x - a) ^ 2 + (y - b) ^ 2 = r ^ 2,這裏的 (a, b) 是圓心位置,r爲半徑。那麼如何生成圓中的任意位置呢,若是用這種方式來生成,先隨機出一個x,隨機出y的時候還要考慮其是否在圓中間,比較麻煩。繼續回到高中時代,模糊的記憶中飄來了三個字,極座標。是的,圓還能夠用極座標的形式來表示,只需隨機出一個角度 theta,再隨機出一個小於半徑的長度,這樣就能夠獲得圓中的座標位置了,哦耶~ 先來生成 theta吧,因爲一圈是 360 度,即 2pi,因此隨機出一個 [0, 1] 中的小數,再乘以 2pi,就能夠了。而後就是隨機小於半徑的長度,這裏有個問題須要注意一下,這裏並非直接隨機出一個 [0, 1] 中的小數再乘以半徑r,而是要對隨機出的 [0, 1] 中的小數取個平方根再乘以半徑r。這是爲啥呢,簡單來講,是爲了保證等機率。若是不用平方根的話,那麼表示圓的時候 (len * cos(theta)) ^ 2 + (len * sin(theta) ^ 2,這裏就至關於對隨機出的 [0, 1] 中的小數平方了,那麼其就不是等機率的了,由於兩個小於1的小數相乘了,其會更加靠近0,這就是爲啥要平方一下的緣由。最後在求點位置的時候要加上圓心的偏移便可,參見代碼以下:ide
解法一:post
class Solution { public: Solution(double radius, double x_center, double y_center) { r = radius; centerX = x_center; centerY = y_center; } vector<double> randPoint() { double theta = 2 * M_PI * ((double)rand() / RAND_MAX); double len = sqrt((double)rand() / RAND_MAX) * r; return {centerX + len * cos(theta), centerY + len * sin(theta)}; } private: double r, centerX, centerY; };
咱們也能夠不用極座標來作,因爲以前剛作過 Implement Rand10() Using Rand7(),對其中的拒絕採樣 Rejection Sampling 還有印象,因此也能夠用其來作。這其實就是拒絕採樣的經典應用,在一個正方形中有均勻分佈的點,隨機出其內切圓中的一個點,那麼就是隨機出x和y以後,而後算其平方和,若是小於等於r平方,說明其在圓內,能夠返回其座標,記得加上圓心偏移,不然從新進行採樣。關於拒絕採樣的方法能夠參見博主以前那篇博客 Implement Rand10() Using Rand7(),參見代碼以下:spa
解法二:code
class Solution { public: Solution(double radius, double x_center, double y_center) { r = radius; centerX = x_center; centerY = y_center; } vector<double> randPoint() { while (true) { double x = (2 * (double)rand() / RAND_MAX - 1.0) * r; double y = (2 * (double)rand() / RAND_MAX - 1.0) * r; if (x * x + y * y <= r * r) return {centerX + x, centerY + y}; } } private: double r, centerX, centerY; };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/478
相似題目:
Implement Rand10() Using Rand7()
參考資料:
https://leetcode.com/problems/generate-random-point-in-a-circle/