2020/08/04
标注了困难的题目是需要学习方法的,其余的主要是学习java。
1.Tues. 课程表
一道极其典型的拓扑排序题目,比较推荐的方法就是采用维护一个入度矩阵,采用BFS的方法。这里只写Java方法。
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
List<List<Integer>> edges = new ArrayList<List<Integer>>();
for (int i = 0; i < numCourses; i++){
edges.add(new ArrayList<Integer>());
}
int[] nums = new int[numCourses];
for (int[] info: prerequisites){
edges.get(info[1]).add(info[0]);
nums[info[0]]++;
}
Queue<Integer> queue = new LinkedList<Integer>();
for (int i = 0; i<numCourses; i++){
if (nums[i] == 0) queue.offer(i);
}
while (!queue.isEmpty()){
numCourses--;
int cur = queue.poll();
for (int next:edges.get(cur)){
nums[next]--;
if (nums[next] == 0) queue.offer(next);
}
}
return numCourses == 0;
}
}
2. Mon. 字符串相加
主要是学习StringBuffer下的方法。
- ans.append(string s) 后面加上一个字符串,但是这个也可以是其他类型,会被先转为字符串.
- ans.reverse() 反转
- ans.toString() 转为字符串
class Solution {
public String addStrings(String num1, String num2) {
int i = num1.length()-1, j = num2.length()-1, add = 0;
StringBuffer ans = new StringBuffer();
while(i>=0 || j >= 0 || add!=0){
int x = i>=0 ? num1.charAt(i)-'0':0;
int y = j>=0 ? num2.charAt(j)-'0':0;
int res = x+y+add;
ans.append(res%10);
add = res/10;
i--;
j--;
}
ans.reverse();
return ans.toString();
}
}
3. Sun. 二叉树转为链表
主要学习二叉树的方法,判断一个节点有无,是cur == null
,声明一个节点是TressNode nex = root.left
/**
* 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 = right;
* }
* }
*/
class Solution {
public void flatten(TreeNode root) {
while (root != null){
if (root.left != null){
TreeNode next = root.left;
while (next.right != null){
next = next.right;
}
next.right = root.right;
root.right = root.left;
root.left = null;
}
root = root.right;
}
}
}
4. Sat. 最小区间(hard)
这道题目还是颇具难度的,思路是采用双指针,但是这里的双指针有一些不一样,可以考虑利用堆。
思路是,构建一个k个数字的堆,每次计算最大值和最小值的差距。
或者采用双指针的方法,维护一个数组统计当前某个数组多少数字被包括。
- Java方法,主要联系优先队列的使用。需要继承
Comparator
,重写compare
方法。
class Solution {
public int[] smallestRange(List<List<Integer>> nums) {
// 注意这里不可以int br = Integer.MAX_VALUE, bl = Integer.MIN_VALUE; 相减会出错
int br = Integer.MAX_VALUE, bl = 0;
//int br = 100000, bl = -100000;
// 这里只能用 size
int size = nums.size();
// next 数组配合pq队列,pq队列存储是第几个数组的索引,next是数组的指针,比较的是指针对应的数值的大小。
int[] next = new int[size];
// PriorityQueue需要重写Comparator方法
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(new Comparator<Integer>(){
// 接口Comparator 需要重写方法compare 需要实现两个数的差
public int compare(Integer index1, Integer index2){
return nums.get(index1).get(next[index1])-nums.get(index2).get(next[index2]);
}
});
// PriorityQueue的入队offer,出队poll
int maxnum = Integer.MIN_VALUE;
for (int i = 0; i<size; i++ ){
pq.offer(i);
maxnum = Math.max(maxnum, nums.get(i).get(0));
}
while (true){
int minindex = pq.poll();
int currange = maxnum - nums.get(minindex).get(next[minindex]);
if (currange < br-bl){
br = maxnum;
bl = nums.get(minindex).get(next[minindex]);
}
if (next[minindex] == nums.get(minindex).size()-1) break;
next[minindex]++;
maxnum = Math.max(maxnum, nums.get(minindex).get(next[minindex]));
pq.offer(minindex);
}
return new int[]{bl, br};
}
}
python 方法,参见。
5. 寻宝(困难)
很经典的题目:传送门