📝个人主页:哈__
期待您的关注
今天给大家分享一道LeetCode的贪心类算法题目。
一、题目描述
给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。
示例 1 :
输入: 2736 输出: 7236 解释: 交换数字2和数字7。
示例 2 :
输入: 9973 输出: 9973 解释: 不需要交换。
注意:
- 给定数字的范围是 [0, 108]
二、方法及思路
看题目中的描述,给出的一个数字只让我们交换一次,然后让这个数字的值达到最大?一开始想区确实没有思路,但抛开代码层面, 如同示例1给出的2736,你又能很轻松的得知交换后的数字为7236,不是7632,也不是7263。这是因为题目给出了我们限制,只让我们交换仅仅一次。
既然选择贪心,那么我就可能想要挑出这个数组中最大的值交换到这个数前边的一个位置。2736就是7最大,然后和2交换。9973就是9最大(可以把这个最大的值的下标索引当作是第二个9,因为我们是倒着来遍历数组的),但是这个9前边又没有可以交换的值,所以9973不交换。
如果这样的话问题就来了,如果题目给出的是9937呢?你是否还想要挑出一个最大的数交换?如果是这样的话你挑出最大的值为9,但9无法和前边的数进行交换了,这样就会导致结果出错。
所以仅仅记录数组中最大值的坐标是不行的。
在这里我进行了三个变量的初始化,一个是maxIndex(最大值的下标索引),index1,index2(需要交换的值的两个索引)
我们先将maxIndex初始化为最后一个索引,在我们从后往前找的时候不仅要记录这个maxIndex的变化,同时还要记录一下index1和index2,这两个变量就是用来记录我们最后要交换哪两个值的,初始化都为-1。那么到底什么情况需要交换呢?当我们开始逆序遍历,maxIndex指向的值大于当前遍历的值时,我们就应该将这两个值交换。我们希望的是最后的maxIndex的值能越靠前放越好,所以我们使用index1和index2记录下这两个需要交换的坐标而不实际交换。
下面是遍历的记录。
当j遍历到3的时候,maxIndex指向的6>3更新index1和index2索引。
当j遍历到7的时候,7>maxIndex指向的6,更新maxIndex索引
当j遍历到2的时候, maxINdex指向的7>2,更新index1和index2
至此,遍历结束,最后交换index1和index2指向的值。
那么9937这样的值是否就可以正确的遍历了呢?
三、代码
class Solution {
public int maximumSwap(int num) {
String str = String.valueOf(num);
char [] arr = str.toCharArray();
int maxIndex = arr.length-1;
int index1 = -1;
int index2 = -1;
for(int i = arr.length-1;i>=0;i--){
if(arr[i]>arr[maxIndex]){
maxIndex = i;
}else if(arr[i]<arr[maxIndex]){
index2 = i;
index1 = maxIndex;
}
}
if(index1==-1) return num;
char tmpVal = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmpVal;
return Integer.parseInt(String.valueOf(arr));
}
}