如何在简单的 Map 中重新排列键的长度?

Sth*_*hra 2 java arrays string hashmap

我们得到一个句子文本(一个句子是一串空格分隔的单词),格式如下:

第一个字母大写。文本中的每个单词都由一个空格分隔。我们的任务是重新排列文本中的单词,以便所有单词都按其长度递增的顺序重新排列。如果两个单词的长度相同,我们将它们按原来的顺序排列。

Example:

Input: text = "Keep calm and code on"
Output: "On and keep calm code"
Explanation: Output is ordered as follows:
"On" 2 letters.
"and" 3 letters.
"keep" 4 letters in case of tie order by position in the original text.
"calm" 4 letters.
"code" 4 letters.
Run Code Online (Sandbox Code Playgroud)

解决办法是:

Example:

Input: text = "Keep calm and code on"
Output: "On and keep calm code"
Explanation: Output is ordered as follows:
"On" 2 letters.
"and" 3 letters.
"keep" 4 letters in case of tie order by position in the original text.
"calm" 4 letters.
"code" 4 letters.
Run Code Online (Sandbox Code Playgroud)

我知道在拆分文本并将其存储在 String 数组中之后,我们使用 HashMap 将单词的长度存储为键,并将该长度的单词存储为长度的值。但是键没有在 HashMaps 中排序,所以长度也没有排序。那么,在将每个键的单词(每个单词的长度)附加到“sb”之后,我们如何确保单词按长度递增的顺序重新排列?

编辑:

好吧,这不是我的代码。这是在讨论板上发布的解决方案之一。这个问题发布在 Leetcode 上,问题的链接在这里

这个解决方案也通过了所有 75 个测试用例,所以我认为这不是偶然的。

Mar*_*mus 5

HashMap首先将键转换为称为哈希值的整数,将键存储在映射中。这是通过调用hashCode()对象上的方法来完成的。然后根据这个哈希值在哈希表中找到一个 bin。

如果您使用的是 Oracle 或 OpenJDK,则hashCode()integer 很可能返回 int 本身(因为哈希值也只是一个int):

/**
 * Returns a hash code for a {@code int} value; compatible with
 * {@code Integer.hashCode()}.
 *
 * @param value the value to hash
 * @since 1.8
 *
 * @return a hash code value for a {@code int} value.
 */
public static int hashCode(int value) {
    return value;
}
Run Code Online (Sandbox Code Playgroud)

HashMap 的默认实现似乎严重依赖于 java 版本。原理(幼稚的实现)是取哈希值的模数和表的长度来得到索引:

index = hash % table.length; // Don't try this, it breaks for negative hash values.
Run Code Online (Sandbox Code Playgroud)

Java 11 的实现似乎做了一些树数组的把戏,它遍历表来查找哈希。


至少,我可以用 Java 11 重现你的例子,我可以通过改变这一行来打破你的例子:

    Map<Integer, List<String>> lengthToWordsMap = new HashMap<>(4);
Run Code Online (Sandbox Code Playgroud)

请注意,即使该Integer.hashCode()方法也没有指定它如何计算哈希值,因此它碰巧使用标识函数计算它的事实是没有记录的,因此永远不应依赖。

你的问题的答案是,这是因为有利条件合谋(和具体的实施细节),而不是因为定义的逻辑。