刷算法 - 算法练习

最近断断续续的刷了一些基础算法题. 我们做移动端开发的, 刷算法题有意义吗? 如果对这个问题有疑问, 可以在读这篇文章之前先读下巧神的文章: 搞 iOS 的学算法有意义吗?

下面这篇文章, 主要是用 OC 语言练习的几个小算法, 会不定期更新. 首先放两个不错的链接地址: 剑指offer 算法题, Leetcode 题解, 有兴趣的童鞋可以一起学习哈!

1. 1-n 阶乘之和

1-n阶乘之和怎么算?

  • 1的阶乘是1
  • 2的阶乘是1*2
  • 3的阶乘是123
  • 4的阶乘是123*4
  • .........

现在我们要求这些阶乘的和。思路:

  • 3阶乘的和其实上就是2阶乘的和+3的阶乘
  • 4阶乘的和其实上就是3阶乘的和+4的阶乘
  • .......
/** 1-n 阶乘之和 */
- (NSInteger)factorialWithNumber:(NSInteger)number {
    // 总和
    NSInteger sum = 0;
    // 阶乘值, 初始化为1
    NSInteger factorial = 1;
    for (NSInteger i = 1; i <= number; i++) {
        factorial = factorial * i;
        sum = (int) (sum + factorial);
    }
    return sum;
}

2. 跳台阶问题

一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

我们假设到第 n 阶总共有 f(n) 种跳法,而且想跳到第 n 阶只有两种可能,要么从第 n-1 阶跳一阶到达,要么从第 n-2 阶跳两阶到达,所以递推式为f(n) = f(n-1) + f(n-2)。特殊情况为,n=0 的时候跳法为 0;n=1时,跳法为1;n=2时,跳法为2;

/** 跳台阶问题 */
- (NSInteger)jumpFloor:(NSInteger)number {
    if(number < 1)
        return 0;
    if(number == 1)
        return 1;
    if(number == 2)
        return 2;
    return [self jumpFloor:(number-1)] + [self jumpFloor:(number-2)];
}

3. 变态跳台阶问题

一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级……它也可以跳上 n 级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

  • 先看 n = 0 时,跳法 f(0) = 0;
  • n = 1,只能是从第 0 个台阶跳过来,跳法 f(1) = 1;
  • n = 2,可能是第 0 个台阶跳了 2 阶或者从第 1 个台阶跳了 1 阶,跳法f(2) = 2 * f(1) = 2;
  • n = 3,可能是第 0 个台阶跳了 3 阶、第 1 个台阶跳了 2 阶、第 2 个台阶跳了 1 阶、各跳 1 阶,跳法 f(3) = 2 * f(2) = 4;
  • ...
  • n = n-1,跳法 f(n-1) = 2f(n-2);
  • n = n,跳法 2f(n-1);
  • 由上面两个等式得:f(n) = 2f(n-1)
/** 变态跳台阶问题 */
- (NSInteger)jumpFloorII:(NSInteger)number {
    if(number < 1)
        return 0;
    if(number == 1)
        return 1;
    return 2*[self jumpFloorII:(number-1)];
}

4. 求1+2+3+...+n

求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)

题目要求不能使用乘除法、for、while、if、else、switch、case 等关键字及条件判断语句,那么首先就要思考怎么才能使 n 一次次的相加且到 0 的时候结束。首先递归可以实现每次 n-1 的相加,即类似于 n + f(n-1) 这样的。但是这样做的话递归的出口在哪呢,也就是我们不能使用条件语句来控制递归何时停止。
仔细想想还有什么运算符可以达到条件控制的效果,这个时候 && 运算符就出现了

/** 求1+2+3+...+n */
- (NSInteger)sum_Solution:(NSInteger)number {
    number && (number += [self sum_Solution:(number-1)]);
    return number;
}

5. 不用加减乘除做加法

写一个函数,求两个整数之和,要求在函数体内不得使用 +、-、*、/ 四则运算符号。

a ^ b 表示没有考虑进位的情况下两数的和,(a & b) << 1 就是进位。

递归会终止的原因是 (a & b) << 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。

/** 不用加减乘除做加法 */
- (NSInteger)sumA:(NSInteger)a b:(NSInteger)b {
    return b == 0 ? a : [self sumA:(a ^ b) b:((a & b) << 1)];
}

6. 圆圈中最后剩下的数

让小朋友们围成一个大圈。然后,他随机指定一个数 m,让编号为 0 的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续 0...m-1 报数 .... 这样下去 .... 直到剩下最后一个小朋友,可以不用表演。

约瑟夫环,圆圈长度为 n 的解可以看成长度为 n-1 的解再加上报数的长度 m。因为是圆圈,所以最后需要对 n 取余。

/** 圆圈中最后剩下的数 */
- (NSInteger)lastRemaining_Solution:(NSInteger)n m:(NSInteger)m {
    // 特殊输入的处理
    if (n == 0)
        return -1;
    if (n == 1)
        return 0;
    return ([self lastRemaining_Solution:n-1 m:m] + m) % n;
}

7. 从 1 到 n 整数中 1 出现的次数

/** 从 1 到 n 整数中 1 出现的次数 */
- (NSInteger)numberOf1Between1AndN:(NSInteger)n {
    NSInteger number = 0;
    for (NSInteger m = 1; m <= n; m *= 10) {
        NSInteger a = n / m, b = n % m;
        number += (a + 8) / 10 * m + (a % 10 == 1 ? b + 1 : 0);
    }
    return number;
}

代码在这里, 算法练习: NNAlgorithm, 有兴趣的童鞋可以下载下 demo, 看下打印效果.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容