最近一段时间找实习惨败,心情也一直因此不太好。想沉淀自己,真正蜕变!
当时有点幸运地考上了研究生,方向是计算机视觉,两年制意味着研一下学期开始要找实习。算法肯定找不到,开始转后端,在学校里的鄙视链,总是算法>后端>前端>客户端>测试。我一向是好强的人,但是要补的东西实在太多了,从头开始学的java语法,不能光看网课不思考吧。八股文背的时候也不能光背啊,得理解吧。项目得有吧,不会自己弄,看网课学着别人弄,但是最近忽视了最重要的力扣题,最有希望拿的offer却因为一道简单的题没了,荒谬且心酸。
那就干脆刷题提升自己吧,加油,调整心态。
class Solution {
public int jump(int[] nums) {
int maxPosition = 0;
int end = 0;
int steps = 0;
if (nums.length == 0)
return 0;
for (int i = 0; i < nums.length; i++) {
maxPosition = Math.max(maxPosition, i + nums[i]);
if ( maxPosition >= nums.length - 1)
return (steps + 1);
if (i == end) {
end = maxPosition;
steps++;
}
}
return steps;
}
}
题目链接:leetcode 02.05. 链表求和
输入:(7 -> 1 -> 6) + (5 -> 9 -> 2),即617 + 295 输出:2 -> 1 -> 9,即912
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int carry = 0;
ListNode res = new ListNode(-1);
ListNode cur = res;
while ( l1 != null || l2 != null) {
int num1 = l1 == null ? 0 : l1.val;
int num2 = l2 == null ? 0 : l2.val;
int sum = num1 + num2 + carry;
carry = sum / 10;
cur.next = new ListNode(sum%10);
cur = cur.next;
l1 = l1 == null ? null : l1.next;
l2 = l2 == null ? null : l2.next;
}
if (carry > 0) {
cur.next = new ListNode(carry);
}
return res.next;
}
}
/**
进阶:正向相加,即个位排在链表尾部
思想:先用两个栈分别把两个链表的元素装进去,新建一个链表需要用头插法插入元素
*/
/** public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Deque stack1 = new ArrayDeque();
Deque stack2 = new ArrayDeque();
ListNode res = null;
while (l1 != null) {
stack1.addFirst(l1.val);
l1 = l1.next;
}
while (l2 != null) {
stack2.addFirst(l2.val);
l2 = l2.next;
}
int carry = 0;
while (!stack1.isEmpty() || !stack2.isEmpty()) {
int num1 = stack1.isEmpty() ? 0 : stack1.pollFirst();
int num2 = stack2.isEmpty() ? 0 : stack2.pollFirst();
int sum = num1 + num2 + carry;
ListNode cur = new ListNode(sum % 10);
carry = sum / 10;
cur.next = res;
res = cur;
}
if (carry > 0) {
ListNode cur = new ListNode(carry);
cur.next = res;
res = cur;
}
return res;
}
}
*/
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode ReverseList(ListNode head) {
if (head == null)
return null;
ListNode res = new ListNode(-1);
res.next = head;
ListNode cur = head;
while (cur.next != null) {
ListNode temp = cur.next;
cur.next = temp.next;
temp.next = res.next;
res.next = temp;
}
return res.next;
}
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param m int整型
* @param n int整型
* @return ListNode类
*/
public ListNode reverseBetween (ListNode head, int m, int n) {
// write code here
if (head == null) {
return null;
}
ListNode res = new ListNode(-1);
res.next = head;
ListNode pre = res;
ListNode cur = head;
for (int i = 0; i < m-1; i++ ) {
pre = cur;
cur = cur.next;
}
for (int j = m; j < n; j++ ) {
ListNode temp = cur.next;
cur.next = temp.next;
temp.next = pre.next;
pre.next = temp;
}
return res.next;
}
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode reverseKGroup (ListNode head, int k) {
ListNode pre = null;
ListNode cur = head;
ListNode tail = head;
for (int i = 0; i < k; i++) {
if (tail == null)
return head;
tail = tail.next;
}
while (cur != tail) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
head.next = reverseKGroup(cur, k);
return pre;
}
}
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
ListNode res = new ListNode(-1);
ListNode cur = res;
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
cur.next = list1;
list1 = list1.next;
cur = cur.next;
} else {
cur.next = list2;
list2 = list2.next;
cur = cur.next;
}
}
if (list1 != null)
cur.next = list1;
if (list2 != null)
cur.next = list2;
return res.next;
}
}
import java.util.*;
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode mergeKLists(ArrayList lists) {
return merge(lists, 0, lists.size()-1);
}
public ListNode merge(ArrayList lists, int l, int r) {
int mid = l + (r - l)/2;
if (l > r)
return null;
else if (l == r)
return lists.get(l);
else
return mergeTwoList(merge(lists, l, mid), merge(lists, mid+1, r));
}
public ListNode mergeTwoList(ListNode node1, ListNode node2) {
ListNode res = new ListNode(-1);
ListNode cur = res;
while (node1 != null && node2 != null) {
if (node1.val <= node2.val) {
cur.next = node1;
node1 = node1.next;
}else {
cur.next = node2;
node2 = node2.next;
}
cur = cur.next;
}
cur.next = node1 != null ? node1 : node2;
return res.next;
}
}
第一部分{3,2,0,-4}代表一个链表,第二部分的1表示,-4到位置1(注:头结点为位置0),即-4->2存在一个链接,组成传入的head为一个带环的链表,返回true
import java.util.*;
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow)
return true;
}
return false;
}
}
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead) {
ListNode slow = hasFloop(pHead);
ListNode fast = pHead;
if (slow == null)
return null;
while (fast != slow) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
public ListNode hasFloop(ListNode pHead) {
ListNode fast = pHead;
ListNode slow = pHead;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow)
return slow;
}
return null;
}
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
if (k == 0)
return null;
ListNode fast = pHead;
ListNode slow = pHead;
for (int i=0; i < k; i++)
// 一定要注意边界条件,否则容易出现超出边界非法访问的问题
if (fast != null)
fast = fast.next;
else
slow = null;
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
输入:s = "()" 输出:true
输入:s = "()[]{}" 输出:true
class Solution {
public boolean isValid(String s) {
Deque stack = new ArrayDeque();
for (char c : s.toCharArray()) {
if (c == '(' || c == '[' || c == '{')
stack.push(c);
else if (c == ')' && !stack.isEmpty() && stack.peek() == '(')
stack.pop();
else if (c == ']' && !stack.isEmpty() && stack.peek() == '[')
stack.pop();
else if (c == '}' && !stack.isEmpty() && stack.peek() == '{')
stack.pop();
// 如果不满足上述我们对于括号匹配的正确筛选,就返回false
else
return false;
}
return stack.isEmpty();
}
}
输入:{1,2},2 。返回值:{2}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param n int整型
* @return ListNode类
*/
public ListNode removeNthFromEnd (ListNode head, int n) {
// write code here
ListNode res = new ListNode(-1);
res.next = head;
ListNode slowPre = res;
ListNode slow = head;
ListNode fast = head;
for (int i = 0; i < n; i++) {
if (fast != null)
fast = fast.next;
else
return res.next;
}
// 找到倒数第n个结点slow
while (fast != null) {
slowPre = slowPre.next;
fast = fast.next;
slow = slow.next;
}
// 删除倒数第n个结点
slowPre.next = slow.next;
return res.next;
}
}
输入:{1,2,3},{4,5},{6,7}。返回值:{6,7}
说明:第一个参数{1,2,3}代表是第一个链表非公共部分,第二个参数{4,5}代表是第二个链表非公共部分,最后的{6,7}表示的是2个链表的公共部分 这3个参数最后在后台会组装成为2个两个无环的单链表,且是有公共节点的。
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode longer = pHead1, shorter = pHead2;
int len1 = 0, len2 = 0;
// 分别计算两个链表的长度
while (longer != null) {
longer = longer.next;
len1++;
}
while (shorter != null) {
shorter = shorter.next;
len2++;
}
// 找到两个链表的长度差值
int diff = Math.abs(len1 - len2);
// 重新更正两个指针的位置,长指针指向更长的那一个链表
if (len1 < len2) {
longer = pHead2;
shorter = pHead1;
} else {
longer = pHead1;
shorter = pHead2;
}
// 使两个指针处于同一个起点
while (diff > 0) {
longer = longer.next;
diff--;
}
// 同时向后走,找公共结点
while (longer != shorter && longer != null) {
longer = longer.next;
shorter = shorter.next;
}
return longer;
}
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
public ListNode mergeSort (ListNode h1, ListNode h2) {
if (h1 == null)
return h1;
if (h2 == null)
return h2;
ListNode res = new ListNode(0);
ListNode cur = res;
while (h1 != null && h2 != null) {
if (h1.val <= h2.val) {
cur.next = h1;
h1 = h1.next;
} else {
cur.next = h2;
h2 = h2.next;
}
cur = cur.next;
}
if (h1 != null)
cur.next = h1;
if (h2 != null)
cur.next = h2;
// cur.next = h1 == null ? null : h1;
// cur.next = h2 == null ? null : h2;
return res.next;
}
public ListNode sortInList (ListNode head) {
if (head == null || head.next == null)
return head;
// write code here
ListNode mid = head;
ListNode fast = head;
ListNode pre = new ListNode(-1);
pre.next = mid;
while (fast != null && fast.next != null) {
fast = fast.next.next;
mid = mid.next;
pre = pre.next;
}
// 将链表断开
pre.next = null;
return mergeSort(sortInList(head), sortInList(mid));
}
}
root
,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。输入:root = [3,9,20,null,null,15,7] 输出:[[3],[20,9],[15,7]]
/**
* 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 List> zigzagLevelOrder(TreeNode root) {
List > res = new LinkedList<> ();
if (root == null)
return res;
Queue que = new LinkedList();
que.offer(root);
boolean flag = false;
while (!que.isEmpty()) {
int size = que.size();
LinkedList row = new LinkedList();
for (int i = 0; i < size; i++) {
TreeNode temp = que.poll();
row.add(temp.val);
if (temp.left != null)
que.offer(temp.left);
if (temp.right != null)
que.offer(temp.right);
}
if (flag)
Collections.reverse(row);
flag = !flag;
res.add(row);
}
return res;
}
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类 the head
* @return bool布尔型
*/
public ListNode reverse (ListNode head) {
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
public boolean isPail (ListNode head) {
// write code here
if (head == null)
return true;
ListNode fast = head;
ListNode slow = head;
// 找链表的中点
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
// 相当于将链表断开为两部分
fast = head;
// 将从中点处反转
slow = reverse(slow);
while (slow != null) {
if (fast.val != slow.val)
return false;
fast = fast.next;
slow = slow.next;
}
return true;
}
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode oddEvenList (ListNode head) {
// write code here
if (head == null || head.next == null)
return head;
ListNode odd = head;
ListNode even = head.next;
// 记录偶数头
ListNode evenHead = even;
while (even != null && even.next != null) {
odd.next = even.next;
odd = odd.next;
even.next = odd.next;
even = even.next;
}
// 奇数后面接上偶数头
odd.next = evenHead;
return head;
}
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode deleteDuplicates (ListNode head) {
// write code here
if (head == null || head.next == null)
return head;
ListNode cur = head;
while (cur != null && cur.next != null) {
if (cur.val == cur.next.val)
cur.next = cur.next.next;
else
cur = cur.next;
}
return head;
}
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode deleteDuplicates (ListNode head) {
// write code here
if (head == null || head.next == null)
return head;
ListNode res = new ListNode(-1);
res.next = head;
ListNode pre = res;
ListNode cur = head;
while (cur != null && cur.next != null) {
if (cur.val == cur.next.val){
int temp = cur.val;
while (cur != null && cur.val == temp)
cur = cur.next;
pre.next = cur;
}
else {
pre = cur;
cur = cur.next;
}
}
return res.next;
}
}
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++){
if (grid[i][j] == 1) {
int a = landArea(grid, i, j);
res = Math.max(res, a);
}
}
}
return res;
}
public int landArea (int[][] grid, int r, int c) {
if (!isLand(grid, r, c))
return 0;
if (grid[r][c] != 1)
return 0;
grid[r][c] = 2;
return 1
+ landArea(grid, r - 1, c)
+ landArea(grid, r + 1, c)
+ landArea(grid, r, c - 1)
+ landArea(grid, r, c + 1);
}
public boolean isLand (int[][] grid, int r, int c) {
return 0 <= r && r < grid.length && 0 <= c && c < grid[0].length;
}
}
leetcode827. 最大人工岛https://leetcode.cn/problems/making-a-large-island/
class Solution {
public int largestIsland(int[][] grid) {
if (grid==null || grid.length == 0){
return 1;
}
int res = 0;
int index = 2;
HashMap indexAndAreas = new HashMap<>();//岛屿编号:岛屿面积
/**
* 计算每个岛屿的面积,并标记是第几个岛屿
*/
for (int r=0;r hashSet = findNeighbour(grid,r,c);//把上下左右邻居放入set去重
if (hashSet.size() < 1)continue;//如果海洋格子周围没有格子不必计算
int twoIsland = 1;//填充这个格子,初始为1,这个变量记录合并岛屿后的面积
for (Integer i: hashSet){
twoIsland += indexAndAreas.get(i);//该格子填充,则上下左右的陆地的都连接了,通过序号获得面积,加上面积
}
res = Math.max(res,twoIsland);//比较得到最大的面积
}
}
}
return res;
}
/**
* 对于海洋格子,找到上下左右
* 每个方向,都要确保有效inArea以及是陆地格子,则表示是该海洋格子的陆地邻居
* @param grid
* @param r
* @param c
* @return
*/
private HashSet findNeighbour(int[][] grid,int r,int c){
HashSet hashSet = new HashSet<>();
if (inArea(grid,r-1,c)&&grid[r-1][c] != 0){
hashSet.add(grid[r-1][c]);
}
if (inArea(grid,r+1,c) && grid[r+1][c] != 0){
hashSet.add(grid[r+1][c]);
}
if (inArea(grid,r,c-1) && grid[r][c-1] != 0){
hashSet.add(grid[r][c-1]);
}
if (inArea(grid,r,c+1) && grid[r][c+1] != 0){
hashSet.add(grid[r][c+1]);
}
return hashSet;
}
/**
* dfs方法,将格子填充为index,即表示这个格子属于哪个岛的
* 计算岛屿面积,上下左右,当然这个可以优化的,因为不需要计算上面的,会有重复
* @param grid
* @param r
* @param c
* @param index
* @return
*/
private int area(int[][] grid, int r, int c,int index){
if (!inArea(grid,r,c)){
return 0;
}
//不为1,表示为海洋格子或者已经遍历过了
if (grid[r][c] != 1){
return 0;
}
grid[r][c] = index;//设置当前格子为某个岛屿编号
return 1 + area(grid,r-1,c,index) + area(grid,r+1,c,index) + area(grid,r,c-1,index) + area(grid,r,c+1,index);
}
/**
* 判断grid[r][c]是否大小合适
* @param grid
* @param r
* @param c
* @return
*/
private boolean inArea(int[][] grid,int r,int c){
return r>=0 && r=0 && c
BM17 二分查找-Ihttps://www.nowcoder.com/practice/d3df40bd23594118b57554129cadf47b
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @param target int整型
* @return int整型
*/
public int search (int[] nums, int target) {
// write code here
if (nums.length < 1 )
return -1;
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
return -1;
}
}
BM18 二维数组中的查找https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e
public class Solution {
public boolean Find(int target, int [][] array) {
if (array.length == 0 || array[0].length == 0)
return false;
for (int i = array.length - 1, j = 0; i >= 0 && j < array[0].length;) {
if (array[i][j] == target)
return true;
// 元素较大往右走
else if (array[i][j] < target)
j++;
// 元素较小往上走
else
i--;
}
return false;
}
}
BM19 寻找峰值https://www.nowcoder.com/practice/fcf87540c4f347bcb4cf720b5b350c76
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型
*/
public int findPeakElement (int[] nums) {
// write code here
int left = 0;
int right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > nums[mid + 1])
right = mid;
else
left = mid + 1;
}
return left;
}
}
BM20 数组中的逆序对https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5
/*归并排序的改进,把数据分成前后两个数组(递归分到每个数组仅有一个数据项),
合并数组,合并时,出现前面的数组值array[i]大于后面数组值array[j]时;则前面
数组array[i]~array[mid]都是大于array[j]的,count += mid+1 - i
参考剑指Offer,但是感觉剑指Offer归并过程少了一步拷贝过程。
还有就是测试用例输出结果比较大,对每次返回的count mod(1000000007)求余
*/
public class Solution {
public int InversePairs(int [] array) {
int size = array.length;
int[] copy = new int[size];
return InversePairsCore(array, copy, 0, size - 1);
}
private int InversePairsCore(int[] array,int[] copy,int low,int high) {
if (low >= high)
return 0;
int mid = low + (high - low) / 2;
int i = low, j = mid + 1;
int leftCount = InversePairsCore(array, copy, 0, mid) % 1000000007;
int rightCount = InversePairsCore(array, copy, mid + 1, high) % 1000000007;
int count = leftCount + rightCount;
for (int m = low; m <= high; m++)
copy[m] = array[m];
for (int m = low; m <= high; m++) {
// 如果左面的全找完了
if (i == mid + 1)
array[m] = copy[j++];
// 如果右面的全找完了或者是左面小于右面的
else if (j == high + 1 || copy[i] <= copy[j])
array[m] = copy[i++];
// 只剩下左面的大于右面的这种情况,这就属于逆序对
else {
// 统计逆序对,就是看左面还剩几个。这里是计算跨左右的逆序对
count = count + mid - i + 1;
// 相当于是归并排序顺便计算逆序对,就是放较小的进去就行
array[m] = copy[j++];
}
}
return count % 1000000007;
}
}
BM21 旋转数组的最小数字https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba
import java.util.*;
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
int left = 0;
int right = array.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
// 无法判断的时候,挨个试
if (array[mid] == array[right])
right--;
else if (array[mid] > array[right])
left = mid + 1;
else
right = mid;
}
return array[left];
}
}
BM22 比较版本号https://www.nowcoder.com/practice/2b317e02f14247a49ffdbdba315459e7
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 比较版本号
* @param version1 string字符串
* @param version2 string字符串
* @return int整型
*/
public int compare (String version1, String version2) {
// write code here
int l1 = version1.length();
int l2 = version2.length();
int i = 0, j = 0;
while (i < l1 || j < l2) {
long num1 = 0, num2 = 0;
// 将.前面的加起来进行比较
while (i < l1 && version1.charAt(i) != '.')
// 注意charAt取出来的是char,所以减去的应该是‘0’
num1 = num1 * 10 + (version1.charAt(i++) - '0');
// 为了跳过‘.’,方便下一轮比较
i++;
// 这里强调j < l2是怕j++的过程中越界
while (j < l2 && version2.charAt(j) != '.')
num2 = num2 * 10 + (version2.charAt(j++) - '0');
// 为了跳过‘.’,方便下一轮比较
j++;
if (num1 > num2)
return 1;
else if (num1 < num2)
return -1;
}
return 0;
}
}
leetcode15. 三数之和 https://leetcode.cn/problems/3sum/
class Solution {
public List> threeSum(int[] nums) {
List> res = new ArrayList();
if (nums == null || nums.length < 3)
return res;
// 排序后将三数之和问题转换为两数之和
Arrays.sort(nums);
// 开始遍历
for (int i = 0; i < nums.length; i++) {
// 因为是排序后的序列,如果最小的都大于0,说明不可能满足三数之和等于0了
if (nums[i] > 0)
break;
// 对i去重
if (i >= 1 && nums[i] == nums[i - 1])
continue;
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
// 三数之和为0
if (sum == 0) {
// 对left去重
while (left < right && nums[left] == nums[left + 1])
left++;
// 对right去重
while (left < right && nums[right] == nums[right - 1])
right--;
res.add(Arrays.asList(nums[i], nums[left], nums[right]));
left++;
right--;
}
else if (sum > 0)
right--;
else
left++;
}
}
return res;
}
}
leetcode1353. 最多可以参加的会议数目https://leetcode.cn/problems/maximum-number-of-events-that-can-be-attended/
class Solution {
public int maxEvents(int[][] events) {
// 我这里使用了lambda表达式,这里a[0] - b[0]就相当于是升序了
Arrays.sort(events, (a,b)->a[0]-b[0]);
PriorityQueue q = new PriorityQueue ((a,b)->(a[1]-b[1]));
int size = events.length;
int i = 0;
int res = 0;
int curDay = 1;
while (i < size || !q.isEmpty()) {
// 将开始时间相同的放入堆中
while (i < size && events[i][0] == curDay ) {
int[] event = events[i];
q.add(event);
i++;
}
// 队列中没有元素的话,说明开始时间不合适,将开始时间向后移动一天
if (q.isEmpty()) {
curDay++;
continue;
}
// 如果结束时间比开始时间都晚,说明已经错过了
while (!q.isEmpty() && q.peek()[1] < curDay)
q.poll();
// 这里剩下的终于是我们能参加的会议了,贪心得到满足了
if (!q.isEmpty()) {
q.poll();
res++;
}
curDay++;
}
return res;
}
}
/**
* 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 List preorderTraversal(TreeNode root) {
List list = new ArrayList();
preorder(list, root);
return list;
}
public void preorder(List list, TreeNode root) {
if (root == null)
return;
list.add(root.val);
preorder(list, root.left);
preorder(list, root.right);
}
}
/**
* 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 List inorderTraversal(TreeNode root) {
List list = new ArrayList();
inorder(list, root);
return list;
}
public void inorder(List list, TreeNode root) {
if (root == null)
return ;
inorder(list, root.left);
list.add(root.val);
inorder(list, root.right);
}
}
/**
* 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 List postorderTraversal(TreeNode root) {
List list = new ArrayList();
postorder(list, root);
return list;
}
public void postorder(List list, TreeNode root) {
if (root == null)
return;
postorder(list, root.left);
postorder(list, root.right);
list.add(root.val);
}
}
/**
* 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 List> levelOrder(TreeNode root) {
List> res = new ArrayList();
if (root == null)
return res;
Queue q = new ArrayDeque();
q.add(root);
while (!q.isEmpty()) {
List row = new ArrayList();
int len = q.size();
for (int i = 0; i < len; i++) {
TreeNode temp = q.poll();
row.add(temp.val);
if (temp.left != null)
q.add(temp.left);
if (temp.right != null)
q.add(temp.right);
}
res.add(row);
}
return res;
}
}
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList > Print(TreeNode pRoot) {
ArrayList > res = new ArrayList >();
if (pRoot == null) {
return res;
}
// BFS需要先存储入口的根结点
Queue temp = new LinkedList();
temp.offer(pRoot);
// 需要标识符来看是否翻转
boolean flag = false;
while (!temp.isEmpty()) {
// 需要将每一行的元素记录下来
ArrayList row = new ArrayList();
int size = temp.size();
for (int i = 0; i < size; i++) {
TreeNode t = temp.poll();
row.add(t.val);
if (t.left != null)
temp.offer(t.left);
if (t.right != null)
temp.offer(t.right);
}
if (flag)
Collections.reverse(row);
flag = !flag;
res.add(row);
}
return res;
}
}
/**
* 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 int maxDepth(TreeNode root) {
if (root == null)
return 0;
int leftDepth = maxDepth(root.left);
int rightDepth = maxDepth(root.right);
return Math.max(leftDepth, rightDepth) + 1;
}
}
BM29 二叉树中和为某一值的路径(一)https://leetcode.cn/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/
/**
* 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 {
LinkedList> res = new LinkedList<>();
LinkedList path = new LinkedList<>();
public List> pathSum(TreeNode root, int sum) {
recur(root, sum);
return res;
}
void recur(TreeNode root, int tar) {
if(root == null) return;
path.add(root.val);
tar -= root.val;
if(tar == 0 && root.left == null && root.right == null)
res.add(new LinkedList(path));
recur(root.left, tar);
recur(root.right, tar);
path.removeLast();
}
}
leetcode134. 加油站https://leetcode.cn/problems/gas-station/
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int gasSum = 0, costSum = 0;
for (int i = 0; i < gas.length; i++) {
gasSum += gas[i];
costSum += cost[i];
}
// 先整体判断整条环路是否满足总油耗小于总加油量
if (gasSum < costSum)
return -1;
int curGas = 0;
int start = 0;
for (int i = 0; i < gas.length; i++) {
curGas = curGas + gas[i] - cost[i];
// 如果小于0,说明起始点不满足条件,就得从起始点的下一个结点开始
if (curGas < 0) {
curGas = 0;
start = i + 1;
}
}
return start;
}
}
class Solution {
public List> permute(int[] nums) {
List> res = new ArrayList> ();
int len = nums.length;
int depth = 0;
Deque path = new ArrayDeque();
boolean[] used = new boolean[len];
if (len < 1)
return res;
dfs(nums, len, depth, path, used, res);
return res;
}
public void dfs (int[] nums, int len, int depth, Deque path, boolean[] used, List> res) {
if (len == depth) {
res.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < len; i++) {
if (used[i])
continue;
else {
path.push(nums[i]);
used[i] = true;
dfs(nums, len, depth + 1, path, used, res);
// 回溯
used[i] = false;
path.pop();
}
}
}
}
import java.util.*;
public class Solution {
public ArrayList> permuteUnique(int[] num) {
Arrays.sort(num);
int len = num.length;
boolean[] used = new boolean[len];
int depth = 0;
ArrayList> res = new ArrayList>();
ArrayList path = new ArrayList();
if (len < 1)
return res;
dfs(num, len, used, depth, path, res);
return res;
}
public void dfs (int[] num, int len, boolean[] used, int depth, ArrayList path, ArrayList> res) {
if (depth == len) {
res.add(new ArrayList(path));
return;
}
for (int i = 0; i < len; i++) {
if (used[i])
continue;
if (i > 0 && num[i] == num[i - 1] && used[i - 1] == true)
continue;
else {
path.add(num[i]);
used[i] = true;
dfs(num, len, used, depth + 1, path, res);
path.remove(path.size() - 1);
used[i] = false;
}
}
}
}
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
/**
int[] res = new int[temperatures.length];
//双层循环遍历-暴力:时间复杂度O(n^2),空间复杂度O(n)
for (int i = 0; i < temperatures.length - 1; i++) {
for (int j = i + 1; j < temperatures.length; j++) {
if (temperatures[j] > temperatures[i]) {
res[i] = j - i;
break;
}
}
}
return res;
*/
/**
// 时间复杂度O(n),空间复杂度O(n)
int len = temperatures.length;
int[] res = new int[len];
// res[len - 1] = 0;
// 从后往前遍历
// 因为对于最后一天,肯定没有比它温度再高的,所以直接从倒数第二天开始
for (int i = len - 2; i >= 0; i--) {
for (int j = i + 1; j < len; j += res[j]) {
if (temperatures[i] < temperatures[j]) {
res[i] = j - i;
break;
} else if (res[j] == 0) {
res[i] = 0;
break;
}
}
}
return res;
}
*/
// 栈,时间复杂度O(n),空间复杂度O(n)
// 如果比栈顶元素大,就出栈并计算下标差值,否则入栈。
int len = temperatures.length;
int[] res = new int[len];
Deque stack = new LinkedList();
for (int i = 0; i < len; i++) {
while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {
int preIndex = stack.pop();
res[preIndex] = i - preIndex;
}
stack.push(i);
}
return res;
}
}
/**
* 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 int res;
public int diameterOfBinaryTree(TreeNode root) {
res = 0;
if (root == null)
return res;
dfs(root);
return res;
}
private int dfs (TreeNode root) {
// 最底层递归出口
if (root == null)
return 0;
// 中间层递归形式
int L = dfs(root.left);
int R = dfs(root.right);
//返回所需的结果,求的是直径即边长,所以是L+R,而不是L+R-1
res = Math.max(res, L + R);
// 最上层的公式求深度
return Math.max(L, R) + 1;
}
}
40.