[Java]剑指offer46-50题_day10

46.孩子们的游戏

题目描述

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

思路:LinkedList

package com.matajie;

import java.util.LinkedList;

/**
 * 46.孩子们的游戏
 * 题目描述
 *
 * 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。
 * HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:
 * 首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。
 * 每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,
 * 从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,
 * 并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?
 * (注:小朋友的编号是从0到n-1)
 *
 * 我的程序才不会有bug!
 * 天不生我lyj,万古Java如长夜
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class LastRemaining_Solution {
    public int LastRemaining_Solution(int n, int m) {
        LinkedList<Integer>  list = new LinkedList<>();
        for(int i = 0;i<n;i++){
            list.add(i);
        }
        int bt = 0;
        while (list.size() > 1){
            bt = (bt + m - 1) % list.size();
            list.remove(bt);
        }
        return list.size() == 1 ? list.get(0) : -1;
    }
}

47.求1+2+3+…+n

题目描述

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

思路:利用短路与,前面不成立不会执行后面

package com.matajie;

/**
 * 47.求1+2+3+...+n
 * 题目描述
 *
 * 求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
 *
 * 我的程序才不会有bug!
 * 天不生我lyj,万古Java如长夜
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class Sum_Solution {
    public int Sum_Solution(int n) {
       int sum = n;
       boolean flag = (sum > 0) && ((sum += Sum_Solution(--n)) > 0);
       return sum;
    }
}

48.不用加减乘除做加法

题目描述

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

思路:

三步走,例如 5 + 7 = 12.
5转为二进制是101;
7转为二进制是111.
第一步:相加各位的值,不算进位,得到010,相当于各位做异或操作,101 ^ 111.
第二步:计算进位值,得到1010,相当于各位做与操作得到101,再向左移一位得1010
(101 & 111) << 1(如果进位值为0,那么第一步得到的值就是最终结果)
第三步:重复上述两步,各位相加010^1010 = 1000,进位值为100 = (010 &1010)<<1.
继续重复上述两步,1000^100 = 1100,进位值为0,跳出循环,1100为最终结果.

package com.matajie;

/**
 * 48.不用加减乘除做加法
 * 题目描述
 *
 * 写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
 *
 * 我的程序才不会有bug!
 * 天不生我lyj,万古Java如长夜
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class Add {
    public int Add(int num1,int num2) {
        while (num2 != 0){
            int temp = num1 ^ num2;
            num2 = (num1 & num2) << 1;
            num1 = temp;
        }
        return num1;
    }
}

49.把字符串转换成整数

题目描述

将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。

package com.matajie;

/**
 * 49.把字符串转换成整数
 * 题目描述
 *
 * 将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,
 * 但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。
 * 数值为0或者字符串不是一个合法的数值则返回0。
 *
 * 我的程序才不会有bug!
 * 天不生我lyj,万古Java如长夜
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class StrToInt {
    public static boolean flag;
    public int StrToInt(String str) {
        flag = false;
        if(str == null || str.trim().equals("")){//判断输入是否合法
            flag = true;
            return 0;
        }
        int symbol = 0;//symbol = 0,说明该数为正数,symbol = 1,该数为负数
        int start = 0;// start用来区分第一位是否是符号位
        char[] chars = str.trim().toCharArray();
        if(chars[0] == '+'){
            start = 1;
        }else if(chars[0] == '-'){
            start = 1;
            symbol = 1;
        }
        int result = 0;
        for(int i = start;i<chars.length;i++){
            if(chars[i] > '9' || chars[i] < '0'){
                flag = true;
                return 0;
            }
            int sum = result * 10 + (int)(chars[i] - '0');
            if((sum - (int)(chars[i] - '0'))/10 != result){
                flag = true;
                return 0;
            }
            result = result * 10 + (int)(chars[i] - '0');
            result = (int)Math.pow(-1,symbol) * result;
        }
            return result;
    }
}

注意:当value = 2147483648时,在计算机内部的表示应该是-2147483648.
Java中-1的n次方不能用(-1)^n异或运算,当value = -2147483648时,value = -value.

50.数组中重复的数字

题目描述

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

package com.matajie;

/**
 * 50.数组中重复的数字
 *
 * 题目描述
 * 在一个长度为n的数组里的所有数字都在0到n-1的范围内。
 * 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。
 * 请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},
 * 那么对应的输出是第一个重复的数字2。
 *
 * 我的程序才不会有bug!
 * 天不生我lyj,万古Java如长夜
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class Duplicate {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
      boolean[] k = new boolean[length];
      for(int i = 0;i<k.length;i++){
          if(k[numbers[i]] == true){
              duplication[0] = numbers[i];
              return true;
          }
          k[numbers[i]] = true;
      }
      return false;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值