學習目標:
每天2-3到簡單sql(刷完即止),每天復習代碼隨想錄上的題目3道算法(時間充足可以繼續),背誦的八股的問題也在這里記錄了
今日碎碎念:
1)偶爾還是貪玩游戲,但是進度有在往前,八股計劃準備這些,計網,JVM,JUC,Java基礎與集合,MySQL,Redis,Spring和Spring Boot,整體下來,熱門的能準備到70%就開投。
2)明天是java基礎和MySQL以及Redis的八股
3)哎還有科三科四沒考,只能約到3月15號的,剛好一邊準備面試。
4)項目還得優化一兩道,簡歷還會再修改幾次。
力扣刷題
SQL
力扣1075:1075. 項目員工 I
解答思路:
? ? ? ? 1)本題練習到了分組的思路,round函數和avg函數的使用
? ? ? ? 2)通過project_id一分組就可以求得分組后每個組里面的員工以及工作年限,此時使用avg就可以求得平均值了,不清楚的話也可以先通過sum(Employee.experience_years),來驗證工作年限和是否跟預期一樣
# 首先想到的肯定是根據Project_id來進行分組
# 然后去求得當前項目每個員工的工作年限,要實現這一想法就只能是兩表連接查詢了
# 最后求平均AVG,同時使用round來精確小數位數
select Project.project_id,round(avg(Employee.experience_years),2) as average_yearsfrom Project,Employeewhere Project.employee_id = Employee.employee_idgroup by Project.project_id
力扣1667:1667. 修復表中的名字
解答思路:
? ? ? ? 1)本題練習到基礎函數的使用,concat,upper,lower,substring(截取的字段,位置,截取長度)
# 本題就是練習到基礎函數的使用
# 通過substring截取首字母,然后通過UPPER轉化為大寫,LOWER轉化為小寫
# 最后使用concat來連接兩者
select user_id,concat(UPPER(substring(name,1,1)),LOWER(substring(name,2,length(name)))) as namefrom Usersorder by user_id
力扣1179:1179. 重新格式化部門表
解答思路:
? ? ? ? 1)這道題的解題以及代碼實現呢我都是沒見過的,就記錄一下吧
? ? ? ? 2)這類題都是行轉列
? ? ? ? 3)注意寫法:case month when 'Jan' then revenue end的意思是,如果month是Jan的話就返回對應的revenue的值
# 把所有的revenue聚合處理,如果month的值是Jan,那么結果就是revenue,否則忽略。
select id,sum(case month when 'Jan' then revenue end) as Jan_Revenue,sum(case month when 'Feb' then revenue end) as Feb_Revenue,sum(case month when 'Mar' then revenue end) as Mar_Revenue,sum(case month when 'Apr' then revenue end) as Apr_Revenue,sum(case month when 'May' then revenue end) as May_Revenue,sum(case month when 'Jun' then revenue end) as Jun_Revenue,sum(case month when 'Jul' then revenue end) as Jul_Revenue,sum(case month when 'Aug' then revenue end) as Aug_Revenue,sum(case month when 'Sep' then revenue end) as Sep_Revenue,sum(case month when 'Oct' then revenue end) as Oct_Revenue,sum(case month when 'Nov' then revenue end) as Nov_Revenue,sum(case month when 'Dec' then revenue end) as Dec_Revenue
from Department
group by id
算法
力扣19:19. 刪除鏈表的倒數第 N 個結點
解答思路:
? ? ? ? 1)要想一次遍歷就找到末尾,首先我們得使用雙指針
? ? ? ? 2)為什么要使用雙指針
? ? ? ? 3)可以想象這樣一個場景
? ? ? ? 4)兩個人賽跑,甲會一直領先乙100米,當甲到達終點的時候,乙很顯然還剩100米沒到終點,即剩下倒數100米
? ? ? ? 5)這里其實也是一樣的思路了,我們需要定義兩個指針,兩者距離n個節點
? ? ? ? 6)當快指針先到了尾部的時候,說明慢指針距離尾部差n個位置,也就找到了倒數第n個節點
? ? ? ? 7)但是我們要刪除的正是倒數第n個節點,因此我們得找到該節點的前一個節點,即要讓快指針先走n+1個節點
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {//要達到n+1,我們得建立虛擬頭節點ListNode dum = new ListNode(-1);ListNode fast = dum;ListNode slow = dum;dum.next = head;//讓fast先走n+1步for(int i = 0;i<=n;i++){fast = fast.next;}//然后一同前進while(fast != null){fast = fast.next;slow = slow.next;}//改變指向即可達到刪除目的slow.next = slow.next.next;return dum.next;}
}
力扣160:160. 相交鏈表
解答思路:
? ? ? ? 雙指針做法
? ? ? ? 1)我自己在做這些鏈表題目的時候,都會畫圖(腦子里也可以),畫圖之后就不一定會那么抽象了
? ? ? ? 2)舉個例子,你認識了一個女生,在認識之前,你倆各自走各自的路,各自活自己的,如果很幸運你倆結婚了(有相交點),那么以后的日子你倆將會陪伴終生(有相交部分,即交點后的元素都是相同的)
? ? ? ? 3)那么我們就需要先找到兩者的長度以及尾部,將兩者尾部對齊,然后移動到同一起點之后去判斷是否有交集即可
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) {* val = x;* next = null;* }* }*/
//簡單來說,就是求兩個鏈表交點節點的指針。
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode curA = headA;ListNode curB = headB;int lenA = 0, lenB = 0;while (curA != null) { // 求鏈表A的長度lenA++;curA = curA.next;}while (curB != null) { // 求鏈表B的長度lenB++;curB = curB.next;}//統計完之后,重置兩個curcurA = headA;curB = headB;//下面這段代碼的目的就是判斷誰更長,因為我們在讓兩者到尾部對齊的時候并沒有去判斷誰短誰長//都是用的A來移動// 讓curA為最長鏈表的頭,lenA為其長度if (lenB > lenA) {//1. swap (lenA, lenB);int tmpLen = lenA;lenA = lenB;lenB = tmpLen;//2. swap (curA, curB);ListNode tmpNode = curA;curA = curB;curB = tmpNode;}// 求長度差int gap = lenA - lenB;// 讓curA和curB在同一起點上(末尾位置對齊)while (gap-- > 0) {curA = curA.next;}// 遍歷curA 和 curB,遇到相同則直接返回while (curA != null) {if (curA == curB) {return curA;}curA = curA.next;curB = curB.next;}return null;}
}
評論區大牛做法
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA == null || headB == null) return null;ListNode pA = headA, pB = headB;while (pA != pB) {pA = pA == null ? headB : pA.next;pB = pB == null ? headA : pB.next;}return pA;
}作者:房建斌學算法
鏈接:https://leetcode.cn/problems/intersection-of-two-linked-lists/solutions/10774/tu-jie-xiang-jiao-lian-biao-by-user7208t/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
力扣142:142. 環形鏈表 II
解答思路:
? ? ? ? 1)本題在判斷入口在哪的證明過程直接去看隨想錄好了,我這里就記錄一下答案
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {//不太擅長寫遞歸,所以使用虛擬頭節點 + 迭代來做public ListNode swapPairs(ListNode head) {ListNode dum = new ListNode(-1);dum.next = head;ListNode cur = dum;ListNode tmp = null;ListNode firstNode = null;ListNode secondNode = null;//要交換必須要保證有兩個節點while(cur.next != null && cur.next.next != null){//先記錄第三個節點tmp = cur.next.next.next;//記錄第一個節點firstNode = cur.next;//記錄第二個節點secondNode = cur.next.next;//交換cur.next = secondNode;secondNode.next = firstNode;firstNode.next = tmp;//指針移動cur = firstNode;}return dum.next;}
}