题目1:给定一个整数数组,长度为n,找到[1,n]中所有未出现在A中的数
inplace算法:使得i位置上放i+1
3 2 1 6 2 7 5
0 1 2 3 4 5 6
0位置放1,所以3和2位置的数换,1位置放2,2位置放3,.....
//请保证arr[0..N-1]上的数字都在[1~n]之间
public static void printNumberNoInArray(int[] arr) {
if (arr == null || arr.length == 0){
return ;
}
for (int value : arr){ // 争取做到,i位置上,放的数是 i + 1
modify(value,arr);
}
for(int i = 0; i < arr.length; i++){
if (arr[i] != i + 1){// 没做到的位置,就知道缺的数字
System.out.println(i + 1);
}
}
}
public static void modify(int value, int[] arr){
while(arr[value - 1] != value){
int tmp = arr[value - 1];
arr[value - 1] = value;
value = tmp;
}
}
题目2:(主播打赏问题) 初始人气值a(设为偶数),目标人气值b(偶数) a小于等于b
方案1)点赞,花费x, 人气值+2
2)送礼 ,花费Y,人气值*2
3)私聊,花费Z,人气值-2
使得a = b,至少花费几个币
//想要达到的目标是end
//目前达到的分数是cur
//三种决策
//1) cur + 2
//2) cur * 2
//3) cur - 2
public static int func(int x, int y, int z, int end, int cur){
if(cur == end){
return 0;
}
int p1 = process(x, y, z, end, cur + 2) + x;
int p2 = process(x, y, z, end, cur * 2) + y;
int p3 = process(x, y, z, end, cur - 2) + z;
return Math.min(p1, Math.min(p2, p3));
}
存在的问题:递归跑不完
缺少限制条件,basecase的量不够
1)求出频繁解,设通过一直点赞得答案,花费x币,所以添加设置,当花费超过x时return(通用)
2)通过存在a>b,再减,例如a*2 - 2 = b,则a不能超过目标的两倍
public static int minCoins1(int add, int times, int del, int start, int end){
if (start > end){
return -1;
}
return process(0, end, add, times, del, start, end * 2, ((end - start) / 2) * add);
}
//preMoney 之前花了多少币 可变
//aim 目标
//int add, int times, int del 固定
//start当前来到的人气
//limitAim人气达到什么程度不需要再尝试 固定
//limitCoin已经使用的币大到什么程度不需要再尝试了 固定
//返回最小币数
public static int process(int preMoney, int aim, int add, int times, int del, int start, int limitAim, int limitCoin){
if (preMoney > limitCoin){
return Integer.MAX_VALUE;
}
if (start < 0){
return Integer.MAX_VALUE;
}
if (start > limitAim){
return Integer.MAX_VALUE;
}
if (aim == start){
return preMoney;
}
int min