文章目录
<1> 第一题
题目
拆分数位后四位数字的最小和
示例
示例1
:
输入:num = 2932
输出:52
解释:可行的 [new1, new2] 数对为 [29, 23] ,[223, 9] 等等。
最小和为数对 [29, 23] 的和:29 + 23 = 52 。
示例2
:
输入:num = 4009
输出:13
解释:可行的 [new1, new2] 数对为 [0, 49] ,[490, 0] 等等。
最小和为数对 [4, 9] 的和:4 + 9 = 13 。
提示
1000 <= num <= 9999
⭐思路⭐
思路
这道题是签到题,我的做法就是将每个数位进行分解放置数组中进行排序(因为题目中的数据范围表明其就是一个四位数),然后我们将最大的放置于个位。所以返回结果就是nums[0] * 10 + nums[1] * 10 + nums[2] + nums[3]
。
代码实现
class Solution {
public int minimumSum(int num) {
int[] nums = new int[4];
int index = 0;
while(num != 0){
nums[index ++] = num % 10;
num /= 10;
}
Arrays.sort(nums);
return nums[0] * 10 + nums[1] * 10 + nums[2] + nums[3];
}
}
运行结果
<2> 第二题
题目
根据给定数字划分数组
示例
示例1
:
输入:nums = [9,12,5,10,14,3,10], pivot = 10
输出:[9,5,3,10,10,12,14]
解释:
元素 9 ,5 和 3 小于 pivot ,所以它们在数组的最左边。
元素 12 和 14 大于 pivot ,所以它们在数组的最右边。
小于 pivot 的元素的相对位置和大于 pivot 的元素的相对位置分别为 [9, 5, 3] 和 [12, 14] ,它们在结果数组中的相对顺序需要保留。。
示例2
:
输入:nums = [-3,4,3,2], pivot = 2
输出:[-3,2,4,3]
解释:
元素 -3 小于 pivot ,所以在数组的最左边。
元素 4 和 3 大于 pivot ,所以它们在数组的最右边。
小于 pivot 的元素的相对位置和大于 pivot 的元素的相对位置分别为 [-3] 和 [4, 3] ,它们在结果数组中的相对顺序需要保留。
提示
1 <= nums.length <= 105
-106 <= nums[i] <= 106
pivot
等于nums
中的一个元素
⭐思路⭐
思路
其实这道题我的思路也是十分的简单,我们先对大于、小于以及等于pivot
的数组元素进行计数。那么我们就可以确定对应元素的放置的起始位置,那么就可以进行遍历放置了。
代码实现
class Solution {
public int[] pivotArray(int[] nums, int pivot) {
int[] num = new int[nums.length];
int cnt1 = 0, cnt2 = 0, cnt3 = 0;
for(int i = 0; i < nums.length; i ++){
if(nums[i] < pivot) cnt1 ++;
else if(nums[i] == pivot) cnt2 ++;
else cnt3 ++;
}
int l = 0, m = cnt1, n = cnt1 + cnt2;
for(int i = 0; i < nums.length; i ++){
if(nums[i] < pivot){
num[l ++] = nums[i];
}else if(nums[i] == pivot){
num[m ++] = nums[i];
}else num[n ++] = nums[i];
}
return num;
}
}
运行结果
<3> 第三题
题目
设置时间的最少代价
示例
示例1
:
输入:startAt = 1, moveCost = 2, pushCost = 1, targetSeconds = 600
输出:6
解释:以下为设置加热时间的所有方法。
- 1 0 0 0 ,表示 10 分 0 秒。
手指一开始就在数字 1 处,输入 1 (代价为 1),移到 0 处(代价为 2),输入 0(代价为 1),输入 0(代价为 1),输入 0(代价为 1)。
总代价为:1 + 2 + 1 + 1 + 1 = 6 。这是所有方案中的最小代价。
- 0 9 6 0,表示 9 分 60 秒。它也表示 600 秒。
手指移到 0 处(代价为 2),输入 0 (代价为 1),移到 9 处(代价为 2),输入 9(代价为 1),移到 6 处(代价为 2),输入 6(代价为 1),移到 0 处(代价为 2),输入 0(代价为 1)。
总代价为:2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 = 12 。
- 9 6 0,微波炉自动补全为 0960 ,表示 9 分 60 秒。
手指移到 9 处(代价为 2),输入 9 (代价为 1),移到 6 处(代价为 2),输入 6(代价为 1),移到 0 处(代价为 2),输入 0(代价为 1)。
总代价为:2 + 1 + 2 + 1 + 2 + 1 = 9 。
示例2
:
输入:startAt = 0, moveCost = 1, pushCost = 2, targetSeconds = 76
输出:6
解释:最优方案为输入两个数字 7 6,表示 76 秒。
手指移到 7 处(代价为 1),输入 7 (代价为 2),移到 6 处(代价为 1),输入 6(代价为 2)。总代价为:1 + 2 + 1 + 2 = 6
其他可行方案为 0076 ,076 ,0116 和 116 ,但是它们的代价都比 6 大。
提示
0 <= startAt <= 9
1 <= moveCost, pushCost <= 105
1 <= targetSeconds <= 6039
⭐思路⭐
思路
这道题也是一道暴力枚举题,由于最多就是四位数,所以我们且每一位上的数的范围是0 ~ 9
,所以可以进行暴力枚举。然后就是我们先不忽略前缀0
的影响进行求值sum
,然后将前缀0
的影响剔除之后进行求值sum
,记住每一次需要进行判读取最小值。还有就是我上面这种做法的话需要去除第一次是否会有移动开销代价的影响。
代码实现
class Solution {
public int minCostSetTime(int startAt, int moveCost, int pushCost, int s) {
/**
暴力通过
*/
int[] num = new int[4];
int res = Integer.MAX_VALUE;
for(int i = 0; i <= 9; i ++){
for(int j = 0; j <= 9; j ++){
int minuteSecond = (i * 10 + j) * 60;
if(minuteSecond > s) continue;
for(int k = 0; k <= 9; k ++){
int m = s - minuteSecond - k * 10;
if(m < 0 || m >= 10) continue;
int sum = 0;
int index = startAt;
num[0] = i; num[1] = j; num[2] = k; num[3] = m;
// 未去除前缀0时
for(int t = 0; t < 4; t ++){
if(num[t] == index){
sum += pushCost;
}else{
sum += (moveCost + pushCost);
index = num[t];
}
}
res = Math.min(res,sum);
//去除前缀0
int t;
for(t = 0; t < 4; t ++){
if(num[t] != 0) break;
if(t == 0){
if(startAt != num[t]){
sum -= (moveCost + pushCost);
}else{
sum -= pushCost;
}
//System.out.println(res + " " + sum);
res = Math.min(res,sum);
}else{
if(num[t] != num[t - 1]){
sum -= (moveCost + pushCost);
}else{
sum -= pushCost;
}
//System.out.println(res + " " + sum);
res = Math.min(res,sum);
}
}
// 去除第一次是否会有移动代价影响
if(t != 0){
if(startAt == num[t] && num[t] != num[t - 1]){
sum -= moveCost;
res = Math.min(res,sum);
}else if(startAt != num[t] && num[t] == num[t - 1]){
sum += moveCost;
res = Math.min(res,sum);
}
}
}
}
}
return res;
}
}