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;
}
}