题解3

12. 整数转罗马数字

/*
将所有数值从大到小排列存储到一个数值中,每一个数值相应的符号按相同顺序存储在另一个数组中
遍历数组,如果num大于当前数,就添加对应的符号,一直到num小于当前数,然后接着判断下一个数
*/
class Solution {
    public String intToRoman(int num) {
        int[] values={1000,900,500,400,100,90,50,40,10,9,5,4,1};
        String[] character={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
        int t = 1;
        String roman_num = "0";
        for(int i=0; i<13; i++){
            while(num>=values[i]){
                if(t == 1){
                    roman_num = character[i];
                    t = 0;
                } else {
                    roman_num += character[i];
                }
                num -= values[i];
            }
        }
        return roman_num;
    }
}

698. 划分为k个相等的子集

class Solution {
    /*相当于有k个盒子,然后从最大数开始放入盒子,递归尝试每一种可能
    如果存在一种结果可以使每个盒子都满足题意,则返回true*/
    public boolean search(int[] groups, int row, int[] nums, int ave) {
        //row为可进行分配的最后一个数的下标
        if(row < 0)
            return true;
        int v = nums[row];
        row --;
        // 暴力循环遍历,只要有一种情况能成功就是成功,否则返回false
        for (int i = 0; i < groups.length; i++) {
            if(groups[i] + v <= ave) {
                groups[i] += v;
                if(search(groups, row, nums, ave))
                    return true;
                //放错了,重新放
                groups[i] -= v;
            }
            //如果groups全为0的时候,把v放到groups[0]不成功,所以直接break
            if (groups[i] == 0) break;
        }
        return false;
    }

    public boolean canPartitionKSubsets(int[] nums, int k) {
        int num = 0;
        for(int i = 0; i < nums.length; i ++){
            num += nums[i];
        }
        //如果数组总和不能平分k份,那么怎么组合都不能满足题意
        if(num % k != 0)
            return false;
        //ave为每个子集的和
        int ave = num / k;  
        //排序
        Arrays.sort(nums);
        int row = nums.length - 1;
        //如果数组最大值大于子集的和,则返回false
        if(nums[row] > ave)
            return false;
        //将所有等于ave的数拿出
        while (row >= 0 && nums[row] == ave) {
            row--;
            k--;
        }
        return search(new int[k], row, nums, ave);
    }
}

136. 只出现一次的数字

解法一:

class Solution {
    public int singleNumber(int[] nums) {
        //key存储数,value存储该数出现的次数
        Map<Integer, Integer> map = new HashMap<>();
        for (Integer i : nums) {
            //如果找不到该数,则表示目前该数还未出现,count为1;若找到该数,则count+1
            Integer count = map.get(i);
            count = count == null ? 1 : ++count;
            map.put(i, count);
        }
        //找到出现次数为1的数返回
        for (Integer i : map.keySet()) {
            Integer count = map.get(i);
            if (count == 1) {
                return i;
            }
        }
        return -1;
    }
}

解法二:

class Solution {
/*
a^b^a=a^a^b=b,相当于nums[0]^nums[1]^nums[2]^nums[3]^...
然后再把相等的数合并到一起进行异或,然后再与只出现过一次的元素进行异或,
这样最后的结果就是,只出现过一次的元素
*/
    public int singleNumber(int[] nums) {
        int num = 0;
        for (int i = 0; i < nums.length; i ++) {
            num ^= nums[i];
        }
        return num;
    }
}

292. Nim游戏

class Solution {
    /*
    如果是4的整数倍根那么一定会输
    你拿n根对手就会拿4-n根,保证每回合共减4根,你永远都是4的倍数根
    如果最开始不是4的倍数,你可以拿掉多余的,刚好剩下4的整数倍根,让对手永远是4的倍数根。
    */
    public boolean canWinNim(int n) {
        if(n % 4 == 0)
            return false;
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值