思路一:使用数组 由于链表只能单向访问,故我们可以将链表中的值先保存到 List
中,再使用双指针分别指向 List
的头尾来依次判断对应元素是否相等
(也可以将所有的节点值入栈中,再比较各节点元素和栈顶元素是否相等)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public boolean isPalindrome (ListNode head) { ArrayList<Integer> list = new ArrayList <>(); while (head != null ) { list.add(head.val); head = head.next; } int i = 0 , j = list.size() - 1 ; while (i < j) { if (!list.get(i).equals(list.get(j))) return false ; i++; j--; } return true ; } }
思路二:快慢指针 + 翻转 先通过快慢指针找到链表中点,再将中点后面的链表倒转,最后进行比较判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { public boolean isPalindrome (ListNode head) { ListNode slow = head, fast = head, pre = null ; while (fast != null && fast.next != null ) { slow = slow.next; fast = fast.next.next; } while (slow != null ) { ListNode temp = slow.next; slow.next = pre; pre = slow; slow = temp; } while (head != null && pre != null ) { if (head.val != pre.val) return false ; head = head.next; pre = pre.next; } return true ; } }
思路一:递归 因为题目中给的是 BST,故两个子节点的值一定在他们公共祖先的值左右
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public TreeNode lowestCommonAncestor (TreeNode root, TreeNode p, TreeNode q) { if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q); else if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q); else return root; } }
思路二:迭代 与递归思路相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution { public TreeNode lowestCommonAncestor (TreeNode root, TreeNode p, TreeNode q) { int pVal = p.val; int qVal = q.val; TreeNode node = root; while (node != null ) { int parentVal = node.val; if (pVal > parentVal && qVal > parentVal) { node = node.right; } else if (pVal < parentVal && qVal < parentVal) { node = node.left; } else { return node; } } return null ; } }
思路 函数中只给了一个参数(要删除的节点),要充分利用所给的条件
将要删除节点的值变为下一个节点的值
将要删除节点的下一个节点变为下下个节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public void deleteNode (ListNode node) { node.val = node.next.val; node.next = node.next.next; } }
思路一:递归 一开始想到使用递归,但是递归时无法使用 List 保存已有的路径和全部路径
参考官方解答后发现可以构造一个新的函数 ,将已有路径和全部路径都作为参数传入,这样就能完美解决这一问题!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { public void constructPaths (TreeNode root, String path, LinkedList<String> paths) { if (root != null ) { path += Integer.toString(root.val); if (root.left == null && root.right == null ) paths.add(path); else { path += "->" ; constructPaths(root.left, path, paths); constructPaths(root.right, path, paths); } } } public List<String> binaryTreePaths (TreeNode root) { LinkedList<String> paths = new LinkedList <>(); constructPaths(root, "" , paths); return paths; } }
思路二:迭代
上面的算法也可以使用迭代(宽度优先搜索)的方法实现。我们维护一个队列,存储节点以及根到该节点的路径。一开始这个队列里只有根节点。在每一步迭代中,我们取出队列中的首节点,如果它是一个叶子节点,则将它对应的路径加入到答案中。如果它不是一个叶子节点,则将它的所有孩子节点加入到队列的末尾。当队列为空时,迭代结束。
作者:LeetCode 链接:https://leetcode-cn.com/problems/binary-tree-paths/solution/er-cha-shu-de-suo-you-lu-jing-by-leetcode/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution { public List<String> binaryTreePaths (TreeNode root) { LinkedList<String> paths = new LinkedList (); if (root == null ) return paths; LinkedList<TreeNode> node_stack = new LinkedList (); LinkedList<String> path_stack = new LinkedList (); node_stack.add(root); path_stack.add(Integer.toString(root.val)); TreeNode node; String path; while (!node_stack.isEmpty()) { node = node_stack.pollLast(); path = path_stack.pollLast(); if ((node.left == null ) && (node.right == null )) paths.add(path); if (node.left != null ) { node_stack.add(node.left); path_stack.add(path + "->" + Integer.toString(node.left.val)); } if (node.right != null ) { node_stack.add(node.right); path_stack.add(path + "->" + Integer.toString(node.right.val)); } } return paths; } }
思路:递归
先排除 num
为 0 或 num
小于 0 的情况
如果 num
能被 2 、3、5 整除,判断整除后的结果是否为丑数即可
num
等于 1 时返回 true
,其余结果返回 false
1 2 3 4 5 6 7 8 9 class Solution { public boolean isUgly (int num) { if (num < 1 ) return false ; if (num % 2 == 0 ) return isUgly(num / 2 ); if (num % 3 == 0 ) return isUgly(num / 3 ); if (num % 5 == 0 ) return isUgly(num / 5 ); return num == 1 ; } }
方法一:排序 将数组排序后进行遍历,如果数组中元素与其下标不同,则为确实元素
1 2 3 4 5 6 7 8 9 class Solution { public int missingNumber (int [] nums) { Arrays.sort(nums); for (int i = 0 ; i < nums.length; i++) { if (nums[i] != i) return i; } return nums.length; } }
方法二:哈希表 将数组中的值存入 hash表 中,遍历 1 到 nums.length
,返回哈希表中不包含的数
1 2 3 4 5 6 7 8 9 10 11 class Solution { public int missingNumber (int [] nums) { Set<Integer> set = new HashSet <>(); for (int i = 0 ; i < nums.length; i++) set.add(nums[i]); for (int i = 0 ; i < nums.length; i++) { if (!set.contains(i)) return i; } return nums.length; } }
方法三:位运算
1 2 3 4 5 6 7 8 9 10 class Solution { public int missingNumber (int [] nums) { int res = nums.length; for (int i = 0 ; i < nums.length; i++) { res ^= nums[i]; res ^= i; } return res; } }
方法四:数学方法 求 1 到 nums.length
的和,减去数组中所有元素的和,结果就是缺少的数字(有整型溢出风险)
1 2 3 4 5 6 7 8 9 10 11 class Solution { public int missingNumber (int [] nums) { int sum = 0 ; for (int i = 0 ; i < nums.length; i++){ sum += nums[i]; } return nums.length * (nums.length + 1 ) / 2 - sum; } }