yubのAlgorithm.0x13
最大二叉树link:654. 最大二叉树 - 力扣(LeetCode)
思路分析在数组中遍历找到最大值(根节点),分割得到左右子树,再回溯遍历左右子树(还是先找到最大值作为子树的根节点再遍历)
递归12345678910111213141516171819202122232425262728293031323334353637383940414243/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = ...
yubのAlgorithm.0x12
找树左下角的值link:513. 找树左下角的值 - 力扣(LeetCode)
思路分析看题目给出的样例分析,觉得可以从深度入手.如果是左子树深度最大,那直接输出最左边的左子树节点即可(只有一个左节点的话也是如出一辙)又假设二叉树中至少有一个节点,就已经列举出一种特殊需要判断的情况了.
递归12345678910111213141516171819202122232425262728293031323334353637383940414243/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * ...
yubのAlgorithm.0x11
二叉树的最大深度link:104. 二叉树的最大深度 - 力扣(LeetCode)
思路分析高度:后序遍历深度:前序遍历但是其实这里我们可以选择后序遍历,根节点的高度就是树的深度.
递归1234567891011121314151617181920212223242526272829/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = righ ...
yubのAlgorithm.0x1
二分查找link:704. 二分查找 - 力扣(LeetCode)
思路分析题目给出数组升序 ,想到二分查找(好吧其实题目也给出来了w)找到mid,根据逻辑大小缩小范围比较.
全包围[lefg,right]假如数组大小为6,取值范围就是[0,5].闭区间使得定义left = 0,right = nums.length-1(防止越界指针无效,也是根据此处可以反推没有左开右闭情况)left指针是0.right是5,这个时候left == right是有效的,结束条件也就是left<=right,再根据mid位置进行判断,target是再mid左边还是右边或者是幸运的查找到目标位置.
123456789101112131415161718192021class Solution { public int search(int[] nums, int target) { //看到数组习惯性反应越界问题 //闭区间 int right = num ...
yubのAlgorithm.0x10
二叉树的层序遍历(广度优先遍历)link:102. 二叉树的层序遍历 - 力扣(LeetCode)
思路分析题目说明从左往右进行遍历,其实可以堪称给二叉树每一层都画横线分割开来,left first,right last.
n代表null 输出只从存在的节点中输出.最先想到的就是递归,按照创建树的思路,pass掉空节点就好.先前做过队列模拟栈,其实这里用队列来解决也很优雅.
队列BFS12345678910111213141516171819202122232425262728293031323334353637383940414243/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode ...
yubのAlgorithm.0x2
移除元素link:27. 移除元素 - 力扣(LeetCode)
思路分析1.常规遍历数组,比较vaule值是否相等,若不相等往前拷贝覆盖即可,相等跳过,更新下标(可以理解为数组长度减少).【时间复杂度O(n) 空间复杂度O(1)】2.快慢指针.快指针遍历进行筛选,慢指针对应常见存储的数组.找到目标vaule后fast和slow指针拉开距离开始遍历维护更新.【时间复杂度O(n) 空间复杂度O(1)】
拷贝覆盖123456789101112class Solution { public int removeElement(int[] nums, int val) { int k = 0; for(int num:nums){ if(num != val){ nums[k] = num; k++; } } return k; } ...
yubのAlgorithm.0x3
有序数组的平方link:977. 有序数组的平方 - 力扣(LeetCode)非递减顺序一个数列中的元素从左到右依次不减,或者说不降序排列.比如:1233445,12345.
思路分析如果看到数组能条件反射到双指针那已经是win了.根据题意平方之后的数一定在数组的两端.两个指针一首一尾,从后往前更新数组.
1234567891011121314151617181920class Solution { public int[] sortedSquares(int[] nums) { //非递减数组可得最大值平方后会出现在数组两头 int left = 0; int right = nums.length - 1; int[] result = new int[nums.length]; int index = result.length - 1 ; while(left <= right) { if(nums[left]*nums[left] > nums[right ...
yubのAlgorithm.0x4
移除列表元素link:203. 移除链表元素 - 力扣(LeetCode)
首先单向链表是有一个数据域和指针域且在内存中不连续.链表的查找需要从头往后一个个查找【时间复杂度为O(n)】,但是数组查找只需要访问对应元素下标即可【时间复杂度为O(1)】.查找频繁:数组是更好的选择,因为通过索引访问的时间复杂度是 O(1),链表则需要遍历.
插入/删除频繁:链表更适合,因为它可以高效地插入和删除元素,时间复杂度为 O(1)(假设已找到插入或删除位置)。相反,数组在插入和删除时需要移动大量元素,时间复杂度为 O(n).
思路分析看到题目最第一反应就是常规解法,遍历链表找到target直接进行删除操作.【目标是头节点和不是头节点两种情况】(其实还是想有更优雅的解法 不用单独处理移除头节点的情况)
直接删除1234567891011121314151617181920212223class Solution { public ListNode removeElements(ListNode head, int val) { if(head == null)& ...
yubのAlgorithm.0x5
反转链表link:206. 反转链表 - 力扣(LeetCode)
思路分析与数组不同,链表没必要定义新的链表进行存储【对内存空间的浪费】直接改变next指针即可.注意头节点指向的下一个节点为null
双指针法123456789101112131415161718class Solution { public ListNode reverseList(ListNode head) { //双指针操作 ListNode prev = null; ListNode cur = head; //记录节点 ListNode temp = null; while(cur != null) { temp = cur.next;//保存下一个节点 cur.next = prev; //赋值之后整体向后移动//注意先移动prev 不如cur已经移动后记录不到prev新的位置 prev = cur ...
yubのAlgorithm.0x8
两个数组的交集link:349. 两个数组的交集 - 力扣(LeetCode)
思路分析首先想到合并两个数组,遍历找重复项存储到新的数组中但其实用HashSet是更加方便的,【HashSet不存在重复数据】
**注意:使用数组做哈希表的题目都限制了大小 例如只有小写字母或者数值大小在【0-1000】内 **
HashSet12345678910111213141516171819202122232425262728293031import java.util.HashSet;import java.util.Set;class Solution { public int[] intersection(int[] nums1, int[] nums2) { if(nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0 ) { return new int[0]; } //创建需要的set表 ...