Deque接口与List接口中的remove方法的区别
太长不看系列: Deque的remove(Object o)。指定的是元素,List的remove(int index),指定的是索引。
在刷力扣113.路径总和 II 时使用Deque的remove方法出现错误,记录一下原因和理清相关概念。
先上代码:
在回溯时应该使用Deque
的removeLast
方法,错误使用将Deque
的remove
方法当做List
的remove
来使用,导致程序结果错误。
class Solution {List<List<Integer>> res = new ArrayList<>();Deque<Integer> path = new LinkedList<>();public List<List<Integer>> pathSum(TreeNode root, int targetSum) {if (root == null) return res;dfs(root, targetSum);return res;}private void dfs(TreeNode root, int targetSum) {path.add(root.val);if (root.left == null && root.right == null) {if (targetSum == root.val) {res.add(new ArrayList<>(path));}return;}if (root.left != null) {dfs(root.left, targetSum - root.val);path.removeLast(); // 此处!!! 错误代码:path.remove(path.size() - 1)}if (root.right != null) {dfs(root.right, targetSum - root.val);path.removeLast(); // 此处!!!}}
}
具体原因:Deque接口中的remove用来移除指定值的元素,List接口中的remove是index
List
在 List
接口中,remove(int index)
方法是用来移除位于指定位置的元素的。而 LinkedList
实现了 List
接口,所以 path.remove(path.size() - 1)
会尝试移除位于指定索引位置的元素。
Deque
LinkedList
同时也实现了 Deque
接口,而 Deque
接口中有一个方法 remove(Object o)
,它是用来移除第一次出现的指定元素的。当 path.remove(path.size() - 1)
被调用时,如果 path.size() - 1
正好也是 LinkedList
中的一个整数值,remove
方法可能会将这个整数值误解为要移除的元素,而不是索引。
这会导致两个问题:(使用Deque接口的remove(path.size() - 1))
- 如果
path.size() - 1
作为整数值存在于列表中,它会移除这个值的第一次出现,而不是最后一个元素。 - 如果
path.size() - 1
作为整数值不存在于列表中,它会抛出IndexOutOfBoundsException
。
因此,当使用 LinkedList
作为 Deque
使用时,应该使用 addLast
、removeLast
等明确的 Deque
操作来避免可能的混淆和错误。