[英]Digit root of some positive integer is defined as the sum of all of its digits
I am trying to solve this challenge on an online challenge site and I am a bit stuck. 我正在尝试在一个在线挑战网站上解决此挑战,但我有些困惑。 Here is a bit more about the problem:
以下是有关该问题的更多信息:
You are given an array of integers. 您将得到一个整数数组。 Sort it in such a way that if a comes before b then the digit root of a is less than or equal to the digit root of b.
按以下方式对其进行排序:如果a在b之前,则a的数字根小于或等于b的数字根。 If two numbers have the same digit root, the smaller one (in the regular sense) should come first.
如果两个数字具有相同的数字根,则较小的一个(通常是)应排在第一位。 For example 4 and 13 have the same digit root, however 4 < 13 thus 4 comes before 13 in any digitRoot sorting where both are present.
例如4和13具有相同的数字根,但是4 <13因此4在出现两者的任何digitRoot排序中都在13之前。
Here is my output: 这是我的输出:
Input: a: [13, 20, 7, 4]
Output: [20, 13, 4, 7]
Expected Output: [20, 4, 13, 7]
Here is my code: 这是我的代码:
int digitRoot(int b) {
int c, sum = 0;
while(b>0) {
c=b%10;
sum=sum+c;
b=b/10;
}
return sum;
}
int[] digitRootSort(int[] a) {
HashMap<Integer, ArrayList<Integer>> map = new HashMap<Integer, ArrayList<Integer>>();
int[] a1 = new int[a.length];
for (int i=0;i<a.length;i++) {
a1[i]=digitRoot(a[i]);
if (map.containsKey(a1[i])) {
ArrayList<Integer> temp = map.get(a1[i]);
temp.add(a[i]);
map.put(a1[i], temp);
}
else {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(a[i]);
map.put(a1[i], list);
}
}
Arrays.sort(a1);
for (int i=0;i<a.length;i++) {
ArrayList<Integer> temp = map.get(a1[i]);
for(int j=0;j<temp.size();j++) {
a[i]=temp.get(j);
if (j<temp.size()-1)
i++;
}
}
return a;
}
But if I change map.put(a1[i], temp); 但是如果我改变map.put(a1 [i],temp); to map.put(a1[i], Collections.sort(temp));, I get this error: file.java on line 24:
到map.put(a1 [i],Collections.sort(temp));,出现此错误:第24行上的file.java:
error: 'void' type not allowed here
map.put(a1[i], Collections.sort(list));
You seem to be trying to insert the sorted value of the collection. 您似乎正在尝试插入集合的排序值。
Collections.sort(List)
, for better or for worse, sorts that list in-place and returns nothing. 无论好坏,
Collections.sort(List)
对列表进行原位排序,但不返回任何内容。 Sort the list first, then insert it into the map. 首先对列表进行排序,然后将其插入地图。
Just include this one Collections.sort(temp);
只需包括这个
Collections.sort(temp);
at your last for loop this is necessary because multiple numbers can have the same digitRoot and should be put on the list sorted. 在您的最后一个for循环中,这是必要的,因为多个数字可以具有相同的digitRoot,并应按排序放在列表中。
for (int i=0;i<a.length;i++) {
ArrayList<Integer> temp = map.get(a1[i]);
Collections.sort(temp);
for(int j=0;j<temp.size();j++) {
a[i]=temp.get(j);
if (j<temp.size()-1)
i++;
}
}
Input: a: [13, 20, 7, 4]
Output: [20, 4, 13, 7]
Edit: about the error 编辑:关于错误
because in put(a1[i], Collections.sort(list))
the put method is expecting put(int, List)
, but you are giving it put(int, void)
, because the return type of Collections.sort()
is void
, you just have to first sort the list and pass afterwards 因为在
put(a1[i], Collections.sort(list))
,put方法期望的是put(int, List)
,但是您给它put(int, void)
,因为Collections.sort()
的返回类型是void
,您只需要首先对列表进行排序,然后再传递
Seems you're over-complicating things. 看来您过于复杂了。 Write a
Comparator
implementing the sorting rules, and simply sort the values. 编写一个实现排序规则的
Comparator
,然后简单地对值进行排序。
Since you cannot sort an int[]
using a Comparator
, you first have to box the values, but otherwise it's very easy, especially using Java 8+ streams. 由于您不能使用
Comparator
对int[]
进行排序,因此首先必须对值进行装箱,否则非常容易,尤其是使用Java 8+流时。
static int[] digitRootSort(int... values) {
return IntStream.of(values).boxed()
.sorted(new DigitRootComparator())
.mapToInt(Integer::intValue).toArray();
}
static final class DigitRootComparator implements Comparator<Integer> {
@Override
public int compare(Integer a, Integer b) {
int cmp = Integer.compare(digitRoot(a), digitRoot(b));
return (cmp != 0 ? cmp : Integer.compare(a, b));
}
private static int digitRoot(int value) {
int sum = 0;
for (int remain = value; remain > 0; remain /= 10)
sum += remain % 10;
return sum;
}
}
Test 测试
System.out.println(Arrays.toString(digitRootSort(13, 20, 7, 4)));
Output 输出量
[20, 4, 13, 7]
You do not need to sort the array while putting in the map. 放入地图时,无需对数组进行排序。 Instead, you can sort it on retrieval in the last loop:
相反,您可以在最后一个循环中对它进行排序:
Arrays.sort(a1);
for (int i=0;i<a.length;i++) {
ArrayList<Integer> temp = map.get(a1[i]);
Collections.sort(temp);
for(int j=0;j<temp.size();j++) {
a[i]=temp.get(j);
if (j<temp.size()-1)
i++;
}
}
If you need to sort at the time of putting in the map, you should use a SortedSet as that will automatically keep the elements sorted: 如果需要在放入地图时进行排序,则应使用SortedSet,因为这将自动使元素保持排序:
int[] digitRootSort(int[] a) {
HashMap<Integer, TreeSet<Integer>> map = new HashMap<Integer, TreeSet<Integer>>();
int[] a1 = new int[a.length];
for (int i = 0; i < a.length; i++) {
a1[i] = digitRoot(a[i]);
if (map.containsKey(a1[i])) {
TreeSet<Integer> set = map.get(a1[i]);
set.add(a[i]);
map.put(a1[i], set);
} else {
TreeSet<Integer> set = new TreeSet<Integer>();
set.add(a[i]);
map.put(a1[i], set);
}
}
Arrays.sort(a1);
for (int i = 0; i < a.length;) {
TreeSet<Integer> set = map.get(a1[i]);
for (int j : set) {
a[i] = j;
i++;
}
}
return a;
}
However, there is even a simpler way to do with sorted set, by using an appropriate comparator: 但是,通过使用适当的比较器,甚至还有一种更简单的方式来处理排序集:
int[] digitRootSort(int[] a) {
SortedSet<Integer> set = new TreeSet<Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
int result = Integer.compare(digitRoot(a), digitRoot(b));
result = result == 0 ? Integer.compare(a, b) : result;
return result;
}
});
for (int i : a) {
set.add(i);
}
int i = 0;
for (int j : set) {
a[i++] = j;
}
return a;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.