leetcode 链接:https://leetcode-cn.com/problems/map-sum-pairs/

题目

image.png
image.png

解法

  1. class MapSum {
  2. private class TrieNode {
  3. private static final int size = 26;
  4. // 存入的值,路径上全为0,到结尾时设置为相应的key的value
  5. int value;
  6. // 子元素数组,数组索引0代表'a',索引1代表'b',以此类推
  7. TrieNode[] next;
  8. // 标识,用于减少遍历子元素数组的遍历,只要进行过插入就设置为true
  9. boolean hasChild;
  10. public TrieNode(int value) {
  11. this.value = value;
  12. this.next = new TrieNode[size];
  13. this.hasChild = false;
  14. }
  15. public TrieNode() {
  16. this(0);
  17. }
  18. public boolean containsKey(char ch) {
  19. return next[ch - 'a'] != null;
  20. }
  21. public TrieNode get(char ch) {
  22. return next[ch - 'a'];
  23. }
  24. public void set(char ch, TrieNode node) {
  25. hasChild = true;
  26. next[ch - 'a'] = node;
  27. }
  28. }
  29. // 根元素
  30. private final TrieNode root;
  31. /**
  32. * Initialize your data structure here.
  33. */
  34. public MapSum() {
  35. root = new TrieNode();
  36. }
  37. public void insert(String key, int val) {
  38. TrieNode curr = root;
  39. for (int i = 0; i < key.length(); i++) {
  40. char ch = key.charAt(i);
  41. // 如果当前位置没有元素,则进行set
  42. if (!curr.containsKey(ch)) {
  43. curr.set(ch, new TrieNode());
  44. }
  45. curr = curr.get(ch);
  46. }
  47. // 不管当前位置是否有值,均进行覆盖更新
  48. curr.value = val;
  49. }
  50. public int sum(String prefix) {
  51. TrieNode curr = root;
  52. // 循环到前缀的最后一个节点
  53. for (int i = 0; i < prefix.length(); i++) {
  54. char ch = prefix.charAt(i);
  55. // 如果前缀不匹配,则返回0
  56. if (!curr.containsKey(ch)) {
  57. return 0;
  58. }
  59. curr = curr.get(ch);
  60. }
  61. return cal(curr);
  62. }
  63. // 递归进行求值,路径上的元素皆为0,遍历上将路径上的值全部加上即可
  64. private int cal(TrieNode curr) {
  65. // 到达末尾,当前元素没有子元素,返回节点值
  66. if (!curr.hasChild) {
  67. return curr.value;
  68. }
  69. int sum = curr.value;
  70. // 遍历求和
  71. for (TrieNode trieNode : curr.next) {
  72. if (trieNode != null) {
  73. sum += cal(trieNode);
  74. }
  75. }
  76. return sum;
  77. }
  78. }