Java O(1)的映射搜索键和值
假设我有一门课:Java O(1)的映射搜索键和值,java,algorithm,data-structures,kotlin,hashmap,Java,Algorithm,Data Structures,Kotlin,Hashmap,假设我有一门课: data class User(val userId: String, val roles: List<String>) 数据类用户(val userId:String,val角色:List) 另外,我有一些字符串sessionId,我需要O(1)时间来通过sessionId和userId检索数据 我原以为BiMap可以解决我的问题,但按用户搜索不是O(1),因为我需要先将User转换为userId 另一个解决方案是覆盖User的hashcode/equals,
data class User(val userId: String, val roles: List<String>)
数据类用户(val userId:String,val角色:List)
另外,我有一些字符串sessionId
,我需要O(1)
时间来通过sessionId
和userId
检索数据
我原以为BiMap
可以解决我的问题,但按用户搜索不是O(1)
,因为我需要先将User
转换为userId
另一个解决方案是覆盖
User
的hashcode/equals,它只考虑userId
,但这是一个肮脏的攻击。将User
转换为userId
是O(1)
。如果你在做复杂度分析,你只需要取指数最大的项,去掉其余项
如果您执行相同的操作1000次,如果总是执行1000次操作,则仍然是O(1)
。如果操作的数量是恒定的,并且不取决于输入的大小O(1)
复杂度,但您有高恒定因子
至于你的问题:
您可以使用任意数量的Map
s来查找用户
s,但仍然是O(1)
:
val sessionLookup=mapOf()
val userIdLookup=mapOf()
这里有两个Map
s,它们将会话ID和用户ID映射到user
本身
这里重要的是为用户
-用户
和会话ID
-用户
创建查找(例如:在用户
和会话ID之间的映射),并且通过会话ID或用户ID获取用户的操作是O(1)
,因为您不必搜索。您可以将空间复杂度(映射的大小)转换为时间复杂度(将O(n)
搜索转换为O(1)
查找)
如果你真的想进行渐进复杂性分析,我建议。从sessionId
到userId
的Map
和从userId
到User
的第二个Map
怎么样?“按用户搜索不是O(1),因为我需要先将用户转换为userId。”这是没有意义的。强制转换的复杂性是O(1)。并且有两个O(1)操作仍然会使整个算法也是O(1)。@ErwinBolwidt我需要迭代所有元素,强制转换它们(N),然后进行搜索(1),还是我错了?你能详细说明一下吗?你需要更多地了解复杂性。即使你按顺序组合1000个步骤,每个步骤都是O(1),结果仍然是O(1)。当你想“按用户搜索”时,你的输入是什么若要获取会话id?角色列表是否是搜索输入的必要部分?如果否,则拥有从UserId到SessionID的第二个映射是一个有效的解决方案。如果愿意,可以将这两个映射包装在facade类中,以保持同步。或者,使用equals()正如您所建议的,如果它适合您的其余业务逻辑,也会很好。的确,但现在出现了两个映射的同步问题,不是吗?这始终是一个折衷办法。您可以执行搜索O(n)
或查找O(1)
。因为您已经维护了一个用户列表(我猜)维护两个Map
s也不难。
val sessionLookup = mapOf<String, User>()
val userIdLookup = mapOf<String, User>()