十道简单算法题(二)

简介: 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下,重温一下。

结果:

87.jpg


六、猴子吃桃子问题


猴子摘下了n个桃子,当天吃掉一半多一个,第二天也是吃掉剩下桃子的一半多一个,到了第十天,桃子只剩下了1个。问:猴子第一天摘了多少个桃子

思路:

  • 假设当天有n个桃子,它是前一天桃子的一半少1个,f(n - 1) = f(n)/2 - 1,
  • 我们就可以推出当天桃子的个数:根据递推公式:f(n) = 2 * f(n - 1) + 2

用递归和循环都可解决:

递归方式:


/**
     * 猴子吃桃问题
     * @param x 天数
     */
    public static int monkeyQue(int x) {
        if (x <= 0) {
            return 0;
        } else if (x == 1) {
            return 1;
        } else {
            return 2 * monkeyQue(x - 1) + 2;
        }
    }


循环方式:


int x = 1;
        for (int i = 1; i <= 9; i++) {
            x = (x + 1) * 2;
        }

结果:

88.png


七、计算单词的个数


输入一段字符,计算出里面单词的个数,单词之间用空格隔开 ,一个空格隔开,就代表着一个单词了

思路:

  • 把字符遍历一遍,累计由空格串转换为非空格串的次数,次数就是单词的个数
  • 定义一个标志性变量flag,0表示的是空格状态,1表示的是非空格状态
/**
     * 输入一段字符,计算出里面单词的个数
     *
     * @param str 一段文字
     */
    public static int countWord(String str) {
        // 0 表示空格状态,1 表示非空格状态
        int flag = 0;
        // 单词次数
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            if (String.valueOf(str.charAt(i)).equals(" ") ) {
                flag = 0;
            } else if (flag == 0) {
                num++;
                flag = 1;
            }
        }
        return num ;
    }

结果:

89.jpg

八、判断字母是否完全一样

给定两个字符串s和t,判断这两个字符串中的字母是不是完全一样(顺序可以不一样)

思路:

  • 遍历这两个字符串,用每个字符减去'a',将其分别存入到数组中去,随后看这两个数组是否相等即可

要点:

  • 'c'-'a'=2即可计算出存储的位置,如果有多个,则+1即可,后面我们来比较数组大小

代码实现:

/**
     * 给定两个字符串s和t,判断这两个字符串中的字母是不是完全一样(顺序可以不一样) 
     */
    public static void isAnagram() {
        //分别存储字符串的字符
        char[] array1 = new char[26];
        char[] array2 = new char[26];
        String s1 = "pleasefollowthewechatpublicnumber";
        String s2 = "pleowcnumberthewechatpubliasefoll";
        for (int i = 0; i < s1.length(); i++) {
            char value = s1.charAt(i);
            // 算出要存储的位置
            int index = value - 'a';
            array1[index]++;
        }
        for (int i = 0; i < s2.length(); i++) {
            char value = s2.charAt(i);
            // 算出要存储的位置
            int index = value - 'a';
            array2[index]++;
        }
        for (int i = 0; i < 26; i++) {
            if (array1[i] != array2[i]) {
                System.out.println("不相同");
                return;
            }
        }
        System.out.println("相同");
    }

结果:

90.jpg


九、判断一个数是不是2的某次方


判断一个数是不是2的某次方

思路:

  • 除2取余数,直至余数不为0【针对2的倍数这种情况】,看是不是等于1就可以判断是不是2的某次方了


/**
     * 判断是否是2的某次方
     */
    public static void isPowerOfTwo() {
        int num = 3;
        if (num == 0) {
            System.out.println("不是");
        }
        while (num % 2 == 0) {
            num = num / 2;
        }
        if (num == 1) {
            System.out.println("是");
        } else {
            System.out.println("不是");
        }
    }

结果:

91.png

这题还有另一种解决方式,就是位运算:

  • 2的n次方都有一个特点,二进制都是1000000
  • 如果 **2的n次方的二进制-1和2的n次方二进制做按位与运算,那么得出的结果肯定是0 **
if(num <= 0){
        System.out.println("不是");
    }
    else if(num == 1){
        System.out.println("是");
    }
    else{
        if( (num & (num-1) ) == 0){
            System.out.println("是");
        }
        else{
            System.out.println("不是");
        }
    }


十、判断一个数字是不是ugly number

判断一个数字是不是ugly number(分解出来的质因数只有2、3、5这3个数字)

思路:

  • 如果是由2,3,5组成的,那么这个数不断除以2,3,5,最后得出的是1,这个数就是纯粹用2,3,5组成的
  • 跟之前判断该数是否2的某次方是一样的思路~

代码:


/**
     * 判断一个数字是不是ugly number(分解出来的质因数只有2、3、5这3个数字)
     * @param num
     */
    public static void isUgly(int num) {
        if (num <= 0) {
            System.out.println("不是");
        } else {
            while (num % 2 == 0) {
                num = num / 2;
            }
            while (num % 3 == 0) {
                num = num / 3;
            }
            while (num % 5 == 0) {
                num = num / 5;
            }
            if (num == 1) {
                System.out.println("是");
            } else {
                System.out.println("是");
            }
        }
    }

结果:

92.jpg


总结


没错,你没看错,简单的小算法也要总结!

其实我觉得这些比较简单的算法是有"套路"可言的,你如果知道它的套路,你就很容易想得出来,如果你不知道它的套路,那么很可能就不会做了(没思路)。

积累了一定的"套路"以后,我们就可以根据经验来推断,揣摩算法题怎么做了。

举个很简单的例子:

  • 乘法是在加法的基础之上的,那乘法我们是怎么学的?背(积累)出来的,9*9乘法表谁没背过?比如看到2+2+2+2+2,会了乘法(套路)以后,谁还会慢慢加上去。看见了5个2,就直接得出2*5

  1. 1-n阶乘之和
  • 求n的阶乘就用1*2*3*4*...n,实际上就是一个循环的过程,求和就套个sum变量即可!
  1. 获取二维数组每列最小的值
  • 外层循环控制列数,内层循环控制行数,这就是遍历每列的方法~
  1. 求"1!+4!(2的平方)+9!(3的平方)+…+n的值
  • 先求平方,再求阶乘,最后套个sum变量
  1. 数组对角线元素之和
  • 行和列的位置相等,即是对角线上的元素
  1. 打印杨辉三角形
  • 找出杨辉三角形的规律:第一行、第一列和列值等于行值时上的元素都是1,其余的都是头上的值加头上的左边的值
  1. 猴子吃桃子问题
  • 根据条件,我们可以推算出前一天桃子,进而推出当天桃子(规律)。猴子都是在相等的条件(剩下桃子的一半多一个),因此就应该想到循环或者递归
  1. 计算单词的个数
  • 利用每个单词间会有个空格的规律,用变量来记住这个状态(字母与空格)的转换,即可计算出单词的个数!
  1. 判断字母是否完全一样
  • 将每个字母都分别装载到数组里面去,'c-a'就是字母c数组的位置了(也就是2)。由于字母出现的次数不唯一,因此我们比较的是数组的值(如果出现了两次,那么值为2,如果出现了3次,那么值为3)。只要用于装载两个数组的值都吻合,那么字母就是一样!
  1. 判断一个数是不是2的某次方
  • 最佳方案:2的某次方在二进制都有个特点:10000(n个0)--->ps:程序员的整数~……….那么比这个数少一位的二进制肯定是01111,它俩做&运算,那么肯定为0。用这个特性就非常好判断该数是否是2的某次方了
  • 次方案:2的某次方的数不断缩小(只要number % 2 == 0就可以缩小,每次number / 2),最后的商必然是1。
  1. 判断一个数字是不是ugly number
  • 分解出来的质因数只有2、3、5这3个数字,这题其实就是判断该数是否为2的某次方的升级版。将这个数不断缩小(只要number%2||%3||%5==0,每次number / 2 | / 3 /5),最后的商必然是1
目录
相关文章
|
6月前
|
算法 前端开发
每天一算法,脑子不生锈(真押韵)
每天一算法,脑子不生锈(真押韵)
|
6月前
【编程题-错题集】非对称之美(找规律 / 贪心)
【编程题-错题集】非对称之美(找规律 / 贪心)
四道好题分享(看似简单,但是棘手)
四道好题分享(看似简单,但是棘手)
102 0
|
算法 Java 测试技术
大厂面试题:求根号2简单?高级算法你肯定不会
大厂面试题:求根号2简单?高级算法你肯定不会
238 0
大厂面试题:求根号2简单?高级算法你肯定不会
|
算法 Python
简单算法
python 简单算法
66 0
|
存储 机器人 Java
肝了好多天-动态规划十连-超细腻解析
【刷题打卡】周末肝了几道动态规划题,写一下我的心得笔记,故事开头,文章循序渐进,如果看官出现头疼不适,望休息,但是别放弃一定要看完!号外:每道题都有单元测试,看官们直接copy就可以debug了。
130 0
再学一道算法题: 食物链(带权并查集)
再学一道算法题: 食物链(带权并查集)
再学一道算法题: 食物链(带权并查集)
|
算法
重温算法之加油站
有时候自己一直找不到突破口是因为自己把问题想困难了,其实有的问题很简单,需要不断的分解。无论怎么样,这也是自己思考后的产物
121 0
重温算法之加油站
【面试高频题】难度 1.5/5,脑筋急转弯类模拟题
【面试高频题】难度 1.5/5,脑筋急转弯类模拟题
|
算法 Java 数据安全/隐私保护