【剑指Offer中的数学题】

二进制中1的个数

题目描述
输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
示例1
输入
复制
10
返回值
复制
2

解题思路

public class Solution {
    public int NumberOf1(int n) {
        int count = 0;
        while( n!= 0){
            count++;
            n = n&(n - 1);
        }
        return count;
    }
}

数值的整数次方

题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0。不得使用库函数,同时不需要考虑大数问题,也不用考虑小数点后面0的位数。
示例1
输入
复制
2.00000,3
返回值
复制
8.00000
示例2
输入
复制
2.10000,3
返回值
复制
9.26100
示例3
输入
复制
2.00000,-2
返回值
复制
0.25000
说明
2的-2次方等于1/4=0.25

解题思路

public class Solution {
    public double Power(double base, int exponent) {
        if(exponent == 0){
            return 1;
        }else if(exponent == 1){
            return base;
        }else if(exponent > 1){
            double sum = 1;
            for(int i = 1;i <= exponent;i++){
                sum = sum * base;
            }
            return sum;
        }else{
            double sum = 1;
            for(int i = -1;i >= exponent;i--){
                sum = sum * base;
            }
            return 1/sum;
        }
    }
}

整数中1出现的次数(从1到n整数中1出现的次数)

题目描述
输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数
例如,1~13中包含1的数字有1、10、11、12、13因此共出现6次
示例1
输入
复制
13
返回值
复制
6

public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        StringBuilder temp = new StringBuilder();
        for (int i = 1;i <= n;i++){
            temp.append(i);
            //System.out.println(temp);//输出temp的值
        }
        int count = 0;
        //System.out.println(temp.getClass().toString());//查看temp的数据类型
        for (int i = 0;i < temp.length();i++){
            if(temp.charAt(i) == '1')
                count++;

        }
        return count;
    }
}

丑数

题目描述
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
示例1
输入
复制
7
返回值
复制
8

public class JZ33 {

    public static int ugly(int n){
        if(n <= 0)return 0;
        int p2 = 0,p3 = 0,p5 = 0;
        int[] dp = new int[n];
        dp[0] = 1;
        for (int i = 1; i < n; i++) {
            dp[i] = Math.min(dp[p2] * 2,Math.min(dp[p3] * 3,dp[p5] * 5));
            if (dp[i] == dp[p2] * 2) p2++;
            if (dp[i] == dp[p3] * 3) p3++;
            if (dp[i] == dp[p5] * 5) p5++;

        }
        return dp[n - 1];
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

    }
}

孩子们的游戏(圆圈中最后剩下的数)

题目描述
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

如果没有小朋友,请返回-1
示例1
输入
复制
5,3
返回值
复制
3

约瑟夫环问题

public class Solution {
    public int LastRemaining_Solution(int n, int m) {
        if(n <= 0 || m <= 0) return -1;
        int ans = 0;
        for(int i = 2; i <= n; i++){
            ans = (ans + m) % i;
        }
        return ans;
    }
}
public class JZ46 {
    public int LastRemaining_Solution_1(int n, int m) {
        if (n <= 0 || m <= 0)
            return -1;
        return n == 1 ? 0 : (LastRemaining_Solution_1(n - 1,m) + m) % n;
    }

    public int LastRemaining_Solution(int n, int m) {
        if (n < 1 || m < 1){
            return -1;
        }
        List<Integer> list = new ArrayList<>();
        //构建list
        for (int i = 0;i < n;i++){
            list.add(i);
        }
        int cur = -1;
        while (list.size() > 1){
            for (int i = 0;i < m;i++){
                cur++;
                if (cur == list.size()){
                    cur = 0;
                }
            }
            list.remove(cur);
            cur--;//cur--的原因,因为新的list中cur指向了下一个元素,为了保证移动m个准确性,所以cur向前移动一位。

        }
        return list.get(0);
    }
}

求1+2+3+…+n

题目描述
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
示例1
输入
复制
5
返回值
复制
15

public class JZ47 {
    public int Sum_Solution(int n) {
        //等差数列的和,n/2 + n方/2
        int sum = (int)Math.pow(n,2) + n;
        //右移一位除以2
        return sum >> 1;
    }
}

不用加减乘除做加法

题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
示例1
输入
复制
1,2
返回值
复制
3

public class Solution {
    public int Add(int num1,int num2) {
        int result;
        int ans;
        do{
            result = num1 ^ num2;
            ans = (num1 & num2) << 1;
            num1 = result;
            num2 = ans;
        }while(ans != 0);
        return result;
    }
}

把字符串转换成整数

题目描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
输入描述:
输入一个字符串,包括数字字母符号,可以为空
返回值描述:
如果是合法的数值表达则返回该数字,否则返回0
示例1
输入
复制
“+2147483647”
返回值
复制
2147483647
示例2
输入
复制
“1a33”
返回值
复制
0

public class JZ49 {
    public int StrToInt(String str){
        int res = 0;
        int flag = 0; //用来标识是整数还是负数
        for (int i = 0;i < str.length();i++){
            if (str.charAt(i) >= '0' && str.charAt(i) <= '9'){
                res = res * 10 + str.charAt(i) - '0';
            }else if (str.charAt(i) == '+'){
                if (i > 0 || flag != 0)
                    return 0;
                flag = 1;  //置为整数
            }else if (str.charAt(i) == '-'){
                if (i > 0 || flag != 0) //
                    return 0;
                flag = -1;  //置为负数
            }else
                return 0;
        }
        return flag >= 0 ? res : res * flag;
    }
}

剪绳子

题目描述
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],…,k[m]。请问k[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
输入描述:
输入一个数n,意义见题面。(2 <= n <= 60)
返回值描述:
输出答案。
示例1
输入
复制
8
返回值
复制
18

public class JZ67 {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        System.out.println(cutRope(n));
    }

    private static int cutRope(int target) {

        int a = 0;
        int c = 0;
        int maxValue = 2;
        if (target == 2){
            return 1;
        }
        if (target == 3){
            return 2;
        }
        if (target % 3 == 0){
            maxValue = (int) Math.pow(3,target/3);
        }else {
            a = target - 2;
            c = a % 3;
            maxValue = maxValue * (int)Math.pow(3,a/3);
            if ( 0 != c){
                maxValue = maxValue * c;
            }
        }
        return maxValue;
    }

}

posted @ 2021-04-24 20:46  your_棒棒糖  阅读(44)  评论(0编辑  收藏  举报