从简单面试题说起

背景

突发奇想, 在探索各种app的时候, 好奇 soul 的主页星球的效果是怎么实现的, 因此诞生此文.

从一个题说起

上述是背景, 先按下不表, 先从一个经典的面试题说起

走楼梯: n阶楼梯, 每次可向上走1层或2层, 问有多少种方式走到最上方.
例子: 3阶楼梯, 有 111, 12, 21 三种方式

解法

视角放在第 k 个台阶上, 有两种方式到达 k , 从 k - 1 层跨一层, 或者从 k - 2 层跨两层.

有 f(k) 表示走到第 k 个台阶的方法数, 则 f(k) = f(k-1) + f(k-2) , k>2 ; f(1) = 1, f(2) = 2

f(k) 会组成一个数列 1, 2, 3, 5, 8, 13, ....

代码

递归 O(n)

function f(int n) {
    if (n == 0 || n == 1) return 1;
    if (f[n]) return f[n];
    return f[n] = f[n-1] + f[n-2];
}

递推 O(n)

f[0] = 1; f[1] = 1;
for (i = 2; i < n; i ++) {
    f[i] = f[i-1] + f[i-2];
}

矩阵法

快速幂 O(lgn)
function quickPowInt(int x, int n) {
    if (n == 1) return x;
    return quickPow(x, n>>1) * quickPow(x, n>>1) * ((n&1)*x);
}
矩阵快速幂 O(lgn)
function quickPowMatrix(Matrix x, int n) {
    if (n == 1) return x;
    return quickPow(x, n>>1) * quickPow(x, n>>1) * ((n&1)*x);
}

function (Matrix a, Matrix b) * { // 定义矩阵乘法运算
    // ...
}

通项公式

斐波那契数列的特性

黄金分割

斐波那契螺旋

最密排布 (黄金角)

10561 怎样在球面上「均匀」排列许多点?(下)

回到正题

Soul 要实现的效果实际是要实现在球面的均匀分布

CGFloat p1 = M_PI * (sqrt(5) - 1);
CGFloat p2 = 2. / tags.count;

for (NSInteger i = 0; i < tags.count; i ++) {

    CGFloat y = i * p2 - 1 + (p2 / 2);  // (2n+1)/N - 1  in range [1/N-1, 1-1/N]
    CGFloat r = sqrt(1 - y * y);                                 
    CGFloat p3 = i * p1;               
    CGFloat x = cos(p3) * r;
    CGFloat z = sin(p3) * r;

    DBPoint point = DBPointMake(x, y, z);
    [self setTagOfPoint:point andIndex:i];
}

参考

https://kvme0lwwge.feishu.cn/docx/LWWXdAOu3oiu1UxNhFdcTuZMnKd

我在向日葵里找到了黄金比例!斐波那契数列与自然_哔哩哔哩_bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值