前言
需要开通vip的题目暂时跳过
笔记导航
点击链接可跳转到所有刷题笔记的导航链接
605. 种花问题
假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。
-
解答
public boolean canPlaceFlowers(int[] flowerbed, int n) { int len = flowerbed.length; int res = 0; if(len == 1 && flowerbed[0] == 0){ flowerbed[0] = 1; res++; }else if(flowerbed[0] == 0 && flowerbed[1] == 0){ flowerbed[0] = 1; res++; } for(int i =1 ;i < len-1;i++){ if(flowerbed[i] == 1)continue; if(flowerbed[i-1] == 0 && flowerbed[i+1] == 0){ flowerbed[i] = 1; res++; } } if(len-1 >= 1 && flowerbed[len-1] == 0 && flowerbed[len-2] == 0)res++; return res >= n; }
-
分析
- 贪心,从前往后遍历,能插入花的位置就插入
- 最后返回插入花的数量 是否大于等于n即可
-
提交结果
606. 根据二叉树创建字符串
你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串。
空节点则用一对空括号 “()” 表示。而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。
-
解答
public String tree2str(TreeNode t) { String res = ""; if(t == null)return ""; res += t.val; if(t.left != null && t.right !=null) res = res + "(" + tree2str(t.left)+")" + "(" + tree2str(t.right) + ")"; else if(t.left != null) res = res + "(" + tree2str(t.left)+")"; else if(t.right != null) res = res + "()" + "(" + tree2str(t.right) + ")"; return res; }
-
分析
- 递归实现
- 若左右子树都不为空 那么 当前结点对应的字符串就是 t.val + (左子树的字符串) + (右子树的字符串)
- 若左子树不为空 那么 当前结点对应的字符串就是 t.val + (左子树的字符串)
- 若右子树不为空 那么 当前结点对应的字符串就是 t.val + ()+ (右子树的字符串)
-
提交结果
609. 在系统中查找重复文件
给定一个目录信息列表,包括目录路径,以及该目录中的所有包含内容的文件,您需要找到文件系统中的所有重复文件组的路径。一组重复的文件至少包括二个具有完全相同内容的文件。
输入列表中的单个目录信息字符串的格式如下:
“root/d1/d2/…/dm f1.txt(f1_content) f2.txt(f2_content) … fn.txt(fn_content)”
这意味着有 n 个文件(f1.txt, f2.txt … fn.txt 的内容分别是 f1_content, f2_content … fn_content)在目录 root/d1/d2/…/dm 下。注意:n>=1 且 m>=0。如果 m=0,则表示该目录是根目录。
该输出是重复文件路径组的列表。对于每个组,它包含具有相同内容的文件的所有文件路径。文件路径是具有下列格式的字符串:
“directory_path/file_name.txt”
-
解答
public List<List<String>> findDuplicate(String[] paths) { Map<String,List<String>> map = new HashMap<>(); for(int i = 0;i < paths.length;i++){ String cur = paths[i]; String curStrs[] = cur.split(" "); String p = curStrs[0]; for(int j = 1;j < curStrs.length;j++){ int index = curStrs[j].indexOf("("); String pa = p + "/" + curStrs[j].substring(0,index); String context = curStrs[j].substring(index + 1,curStrs[j].length()); List<String> list = map.getOrDefault(context,new ArrayList<>()); list.add(pa); map.put(context,list); } } List<List<String>> res = new ArrayList<>(); for(String key:map.keySet()){ List<String> l = map.get(key); if(l.size() > 1) res.add(l); } return res; }
-
分析
- 遍历路径
- 根据空格将当前路径分割开来,第一个是公共的路径名字,后面的都是文件名字
- 然后遍历后面的文件名字,从中分割出内容context 括号前面的文件名字 拼接上公共路径的名字 得到这个文件的路径。
- 内容context作为key,文件路径放入列表中作为value 保存在map当中。
- 遍历map 若对应的value的大小大于1 则说明有重复的文件内容,将其添加到res集合当中。
-
提交结果
611. 有效三角形的个数
给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。
-
解答
//方法1 public int triangleNumber(int[] nums) { int len = nums.length; int res = 0; Arrays.sort(nums); for(int i = 0;i < nums.length-2;i++){ for(int j = i + 1;j < nums.length-1;j++){ for(int k = j + 1;k < nums.length;k++){ if(nums[i] + nums[j] > nums[k])res++; } } } return res; } //方法2 int binarySearch(int nums[], int l, int r, int x) { while (r >= l && r < nums.length) { int mid = (l + r) / 2; if (nums[mid] >= x) r = mid - 1; else l = mid + 1; } return l; } public int triangleNumber(int[] nums) { int res = 0; Arrays.sort(nums); for (int i = 0; i < nums.length - 2; i++) { int k = i + 2; for (int j = i + 1; j < nums.length - 1 && nums[i] != 0; j++) { k = binarySearch(nums, k, nums.length - 1, nums[i] + nums[j]); res += k - j - 1; } } return res; } //方法3 public int triangleNumber(int[] nums) { int res = 0; Arrays.sort(nums); for (int i = 0; i < nums.length - 2; i++) { int k = i + 2; for (int j = i + 1; j < nums.length - 1 && nums[i] != 0; j++) { while(k < nums.length && nums[j] + nums[i] > nums[k]) k++; res += k - j - 1; } } return res; }
-
分析
- 方法1 暴力
- 两边之和大于第三边,满足这个条件res++
- 方法2 二分查找
- 第三层for循环其实是不必要的,已知两条边a和b 那么可以满足构成三角形的第三条边一定小于a+b,所以最大就是a+b-1.所以可以通过二分查找 来找a+b,若找不到a+b 返回的也是最接近a+b的值 总数就等于res += k-j+1
- 方法3 双指针
- 固定了一位后,j和k双指针,若nums[j] + nums[i] > nums[k] 那么k后移
- 否则res += k-j-1,j后移
-
提交结果
方法1
方法2
方法3
617. 合并二叉树
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
-
解答
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) { if(t1 != null && t2 != null){ t1.val += t2.val; }else if(t2 == null){ return t1; }else if(t1 == null){ return t2; } t1.left = mergeTrees(t1.left,t2.left); t1.right = mergeTrees(t1.right,t2.right); return t1; }
-
分析
- 若当前两个结点都不为空,那么两个结点的值相加
- 若一个为空,则返回另一个。
- 递归的合并左子树和右子树。
-
提交结果