剑指offer 46-50

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

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

如果没有小朋友,请返回-1
java中直接使用一个list来模拟,并使用一个索引cur类指向删除的位置,当cur的值为list的size,就让cur到头位置。
import java.util.*;
public class Solution {
    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);
    }
}
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;

    }
}

 

47求1+2 +3+...

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

public class Solution {
    public int Sum_Solution(int n) {
        int sum=(int)Math.pow(n, 2)+n;
        return sum>>1;
    }
}

48不用加减乘除做加法

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

两个二进制的相加结果是用一个异或门实现的;
两个二进制的进位结果是用一个与门来实现的。

public class Solution {
    public int Add(int num1,int num2) {
        if(num2==0)return num1;
        while(num2!=0){
            int a=num1^num2;
            int b=(num1&num2)<<1;
           num1=a;
            num2=b;
        }
        return num1;
       
    }
}

 

8. 字符串转换整数 (atoi)

 

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:

  • 如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
  • 假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
  • 该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0 。

提示:

  • 本题中的空白字符只包括空格字符 ' '
  • 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231,  231 − 1]。如果数值超过这个范围,请返回  INT_MAX (231 − 1) 或 INT_MIN (−231) 。

 

示例 1:

输入: "42"
输出: 42

示例 2:

输入: "   -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
     我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

示例 3:

输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

示例 4:

输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
     因此无法执行有效的转换。

示例 5:

输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 
     因此返回 INT_MIN (−2
31
) 。
class Solution {
    public int myAtoi(String str) {
        str=str.trim();
        if(str.length()==0||(!Character.isDigit(str.charAt(0))&&str.charAt(0)!='+'&&str.charAt(0)!='-'))return 0;
        long ans=0L;
        int i=Character.isDigit(str.charAt(0))?0:1;
        boolean neg=(str.charAt(0)=='-');
        while(i<str.length()&&Character.isDigit(str.charAt(i))){
            ans=ans*10+(str.charAt(i++)-'0');
            if(!neg&&ans>Integer.MAX_VALUE){
                ans=Integer.MAX_VALUE;
                break;
            }
            if(neg&&ans>1L+Integer.MAX_VALUE){
                ans=1L+Integer.MAX_VALUE;
                break;
            }
        }
        return neg?(int) -ans:(int) ans;
    }
}

 

 

49字符串转化为整数

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0

 

public int StrToInt(String str) {
         //最优解
        if(str == null || "".equals(str.trim()))return 0;
        str = str.trim();
        char[] arr = str.toCharArray();
        int i = 0;
        int flag = 1;
        int res = 0;
        if(arr[i] == '-'){
            flag = -1;
        }
        if( arr[i] == '+' || arr[i] == '-'){
            i++;
        }
        while(i<arr.length ){
            //是数字
            if(isNum(arr[i])){
                int cur = arr[i] - '0';
                if(flag == 1 && (res > Integer.MAX_VALUE/10 || res == Integer.MAX_VALUE/10 && cur >7)){
                    return 0;
                }
                if(flag == -1 && (res > Integer.MAX_VALUE/10 || res == Integer.MAX_VALUE/10 && cur >8)){
                    return 0;
            }
                res = res*10 +cur;
                i++;
            }else{
                //不是数字
                return 0;
            }
        }
        return res*flag;
    }
    public static boolean isNum(char c){
        return c>='0'&& c<='9';
    } 

50数组中重复的数字

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

public class Solution {

    public boolean duplicate(int numbers[],int length,int [] duplication) {
        int[] count=new int[length];
        for(int i=0;i<length;i++){
            count[numbers[i]]++;
        }
        for(int i=0;i<length;i++){
            if(count[i]>1){
                duplication[0]=i;
                return true;
            }
        }
        return false;
    }
}

 

class Solution { public int myAtoi(String str) { str=str.trim(); if(str.length()==0||(!Character.isDigit(str.charAt(0))&&str.charAt(0)!='+'&&str.charAt(0)!='-'))return0; long ans=0L; int i=Character.isDigit(str.charAt(0))?0:1; boolean neg=(str.charAt(0)=='-'); while(i<str.length()&&Character.isDigit(str.charAt(i))){ ans=ans*10+(str.charAt(i++)-'0'); if(!neg&&ans>Integer.MAX_VALUE){ ans=Integer.MAX_VALUE; break; } if(neg&&ans>1L+Integer.MAX_VALUE){ ans=1L+Integer.MAX_VALUE; break; } } return neg?(int) -ans:(int) ans; } }
一流的解决方案{
公众诠释myAtoi(字符串str){
STR = str.trim();
如果(str.length()== 0 ||(Character.isDigit(str.charAt(0))&& str.charAt(0)= '+' && str.charAt(0)=!!! ' - '))的回报0;
长ANS = 0L;
INT I = Character.isDigit(str.charAt(0))?0:1;
布尔NEG =(str.charAt(0)== ' - ');
而(ⅰ<str.length()&& Character.isDigit(str.charAt(I))){
ANS = ANS * 10 +(str.charAt(I ++) - '0');
如果(!NEG && ANS> Integer.MAX_VALUE的){
ANS = Integer.MAX_VALUE的;
打破;
}
如果(NEG && ANS> 1L + Integer.MAX_VALUE的){
ANS = 1L + Integer.MAX_VALUE的;
打破;
}
}
返回NEG(INT)-ans:(INT)ANS;
}
}
posted @ 2020-06-05 13:08  我们村里的小花儿  阅读(136)  评论(0编辑  收藏  举报