文章目錄
- 資源
- Shell
- 數據庫
- 多線程
- 劍指Offer
- 面試題03 數組中重複的數字
- 面試題04 二維數組中的查找
- 面試題05 替換空格
- 面試題06 從尾到頭打印鏈表
- 面試題07 重建二叉樹
- 面試題09 用兩個棧實現隊列
- 面試題10- I 斐波那契數列
- 面試題10- II 青蛙跳臺階問題
- 面試題11 旋轉數組的最小數字
- 面試題12 矩陣中的路徑
- 面試題13 機器人的運動範圍
- 面試題14- I 剪繩子
- 面試題14- II 剪繩子 II
- 面試題15 二進制中1的個數
- 面試題16 數值的整數次方
- 面試題17 打印從1到最大的n位數
- 面試題18 刪除鏈表的節點
- 面試題19 正則表達式匹配
- 面試題20 表示數值的字符串
- 面試題21 調整數組順序使奇數位於偶數前面
- 面試題22 鏈表中倒數第k個節點
- 面試題24 反轉鏈表
- 思路:2指針遍歷,1個指向舊隊頭,1個指向新隊頭,1個臨時指針用於完成節點從舊隊到新隊。也可遞歸求解,得到子序列後將原頭結點放到該子序列的末尾(子序列原末尾爲原頭結點的next節點,故O(1)完成)。
- 面試題25 合併兩個排序的鏈表
- 面試題26 樹的子結構
- 面試題27 二叉樹的鏡像
- 面試題28 對稱的二叉樹
- 面試題29 順時針打印矩陣
- 面試題30 包含min函數的棧
- 面試題31 棧的壓入、彈出序列
- 面試題32 - I 從上到下打印二叉樹
- 面試題32 - II 從上到下打印二叉樹 II
- 面試題32 - III 從上到下打印二叉樹 III
- 面試題33 二叉搜索樹的後序遍歷序列
- 面試題34 二叉樹中和爲某一值的路徑
- 面試題35 複雜鏈表的複製
- 面試題36 二叉搜索樹與雙向鏈表
- 面試題37 序列化二叉樹
- 面試題38 字符串的排列
- 面試題39 數組中出現次數超過一半的數字
- 面試題40 最小的k個數
- 面試題41 數據流中的中位數
- 面試題42 連續子數組的最大和
- 面試題43 1~n整數中1出現的次數
- 面試題44 數字序列中某一位的數字
- 面試題45 把數組排成最小的數
- 面試題46 把數字翻譯成字符串
- 面試題47 禮物的最大價值
- 面試題48 最長不含重複字符的子字符串
- 面試題49 醜數
- 面試題50 第一個只出現一次的字符
- 面試題51 數組中的逆序對
- 面試題52 兩個鏈表的第一個公共節點
- 面試題53 - I 在排序數組中查找數字 I
- 面試題53 - II 0~n-1中缺失的數字
- 面試題54 二叉搜索樹的第k大節點
- 面試題55 - I 二叉樹的深度
- 面試題55 - II 平衡二叉樹
- 面試題56 - I 數組中數字出現的次數
- 面試題56 - II 數組中數字出現的次數 II
- 面試題57 和爲s的兩個數字
- 面試題57 - II 和爲s的連續正數序列
- 面試題58 - I 翻轉單詞順序
- 面試題58 - II 左旋轉字符串
- 面試題59 - I 滑動窗口的最大值
- 面試題59 - II 隊列的最大值
- 面試題60 n個骰子的點數
- 面試題61 撲克牌中的順子
- 面試題62 圓圈中最後剩下的數字
- 面試題63 股票的最大利潤
- 面試題64 求1+2+…+n
- 面試題65 不用加減乘除做加法
- 面試題66 構建乘積數組
- 面試題67 把字符串轉換成整數
- 面試題68 - I 二叉搜索樹的最近公共祖先
- 面試題68 - II 二叉樹的最近公共祖先
資源
在線題庫:https://leetcode-cn.com/problemset/all/
在線題庫:https://www.nowcoder.com/activity/oj
Shell
192 統計詞頻
from: https://leetcode-cn.com/problems/word-frequency/
思路:管道和常用命令,如cat, tr, grep, sort, uniq, sed等
cat words.txt | tr ' ' '\n' | grep -E -v '^$' | sort | uniq -c | sort -n -r | awk '{print $2,$1}'
cat words.txt | sed -e 's/^[ ]*//' -e 's/[ ]*$//' -e 's/[ ][ ]*/\n/g' | sort | uniq -c | sort -n -r | awk '{print $2,$1}'
193 有效電話號碼
from: https://leetcode-cn.com/problems/valid-phone-numbers/
思路:grep和正則表達式
cat file.txt | grep -E '(^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$)|(^[0-9]{3}-[0-9]{3}-[0-9]{4}$)'
194 轉置文件
from: https://leetcode-cn.com/problems/transpose-file/
思路:awk運用或單行for循環
num=`head -1 file.txt | awk '{print NF}'`;for i in `seq $num`;do cut -d ' ' -f $i file.txt | tr '\n' ' ' | sed 's/ $/\n/';done
awk '{for(i=1;i<=NF;i++)if(NR==1){rst[i]=$i}else{rst[i]=rst[i]" "$i}} END {for(i=1;i<=NF;i++)print rst[i]}' file.txt
awk '{for(i=1;i<=NF;i++)rst[i]=rst[i]" "$i} END {for(i=1;i<=NF;i++)print substr(rst[i],2)}' file.txt
195 第十行
from: https://leetcode-cn.com/problems/tenth-line/
思路:文件遍歷行
sed -n '10p' file.txt
head -10 file.txt | tail -n +10
i=1;while read line;do if (( $i == 10 )); then echo $line; fi; i=$(($i+1));done < file.txt
數據庫
175 組合兩個表
from: https://leetcode-cn.com/problems/combine-two-tables
思路:left join用法
select a.FirstName, a.LastName, b.City, b.State from Person as a left join Address as b on a.PersonId = b.PersonId;
176 第二高的薪水
from: https://leetcode-cn.com/problems/second-highest-salary/
思路:limit用法,或者邏輯轉換:第二高的薪水,即比最高薪水小的最大薪水,使用臨時表求解,或者邏輯轉換:第二高的薪水,即比它高的薪水去重後個數等於1,使用子查詢求解。另外,答案外加select是爲了當沒有結果輸出時仍然輸出null結果。
select (select e.Salary from Employee as e group by Salary order by Salary desc limit 1,1) as SecondHighestSalary;
select max(a.Salary) SecondHighestSalary from Employee as a, (select max(Salary) as maxSalary from Employee) as b where a.Salary < b.maxSalary;
select (select distinct a.Salary from Employee as a where (select count(distinct b.Salary) from Employee as b where b.Salary > a.Salary) = 1) as SecondHighestSalary;
177 第N高的薪水
思路:存儲過程中IF,變量和計算表達式等和limit用法
178 分數排名
from: https://leetcode-cn.com/problems/rank-scores/
思路:在查詢結果裏使用查詢語句,使用查詢語句構造臨時表
select a.Score as Score, (select count(b.distinctScore) + 1 from (select distinct(Score) as distinctScore from Scores) as b where b.distinctScore > a.Score) as Rank from Scores as a order by a.Score desc;
180 連續出現的數字
from: https://leetcode-cn.com/problems/consecutive-numbers/
思路:轉換邏輯:連續出現的數字即Id遞增,可使用多表條件查詢
select distinct a.Num as ConsecutiveNums from Logs as a, Logs as b, Logs as c where a.Num = b.Num and b.Num = c.Num and a.Id + 1 = b.Id and b.Id + 1 = c.Id;
181 超過經理收入的員工
from: https://leetcode-cn.com/problems/employees-earning-more-than-their-managers/
思路:基礎的多表條件查詢
select a.Name as Employee from Employee as a, Employee as b where a.ManagerId = b.Id and a.Salary > b.Salary;
182 查找重複的電子郵箱
from: https://leetcode-cn.com/problems/duplicate-emails/
思路:基礎的多表條件查詢
select distinct a.Email as Email from Person as a, Person as b where a.Id != b.Id and a.Email = b.Email;
183 從不訂購的客戶
from: https://leetcode-cn.com/problems/customers-who-never-order/
思路:基礎的子查詢
select a.Name as Customers from Customers as a where a.Id not in (select CustomerId from Orders);
184 部門工資最高的員工
from: https://leetcode-cn.com/problems/department-highest-salary/
思路:多表查詢和子查詢
select b.Name as Department, a.Name as Employee, a.Salary as Salary from Employee as a, Department as b where a.DepartmentId = b.Id and a.Salary = (select max(c.Salary) from Employee as c where c.DepartmentId = a.DepartmentId);
185 部門工資前三高的所有員工
from: https://leetcode-cn.com/problems/department-top-three-salaries/
思路:轉換邏輯:“工資前三高”即“比它高的工資去重後小於等於2”
select b.Name as Department, a.Name as Employee, a.Salary as Salary from Employee as a, Department as b where a.DepartmentId = b.Id and (select count(distinct c.Salary) from Employee as c where c.DepartmentId = a.DepartmentId and c.Salary > a.Salary) < 3;
196 刪除重複的電子郵箱
from: https://leetcode-cn.com/problems/delete-duplicate-emails/
思路:被刪除的表不能用於子查詢,故需要建立臨時表
delete from Person where Id in (select b.Id from (select * from Person) as b, (select * from Person) as c where b.Id > c.Id and b.Email = c.Email);
197 上升的溫度
from: https://leetcode-cn.com/problems/rising-temperature/
思路:DATEDIFF函數
select b.Id as Id from Weather as a, Weather as b where DATEDIFF(b.RecordDate, a.RecordDate) = 1 and b.Temperature > a.Temperature;
262 行程和用戶
from: https://leetcode-cn.com/problems/trips-and-users/
思路:查詢結果使用查詢語句,round函數
select a.Request_at as Day, round( (select count(*) from Trips as b where b.Request_at = a.Request_at and b.Status != 'completed' and b.Client_Id in (select Users_Id from Users where Banned = 'No') and b.Driver_Id in (select Users_Id from Users where Banned = 'No')) / count(*), 2) as 'Cancellation Rate' from Trips as a where a.Request_at <= '2013-10-03' and a.Request_at >= '2013-10-01' and a.Client_Id in (select Users_Id from Users where Banned = 'No') and a.Driver_Id in (select Users_Id from Users where Banned = 'No') group by a.Request_at;
595 大的國家
from: https://leetcode-cn.com/problems/big-countries/
思路:HelloWord類型
select name, population, area from World as a where a.area > 3000000 or a.population > 25000000;
596 超過5名學生的課
from: https://leetcode-cn.com/problems/classes-more-than-5-students/
思路:子查詢和count distinct
select distinct a.class as class from courses as a where (select count(distinct b.student) from courses as b where b.class = a.class) >= 5;
601 體育館的人流量
from: https://leetcode-cn.com/problems/human-traffic-of-stadium/
思路:基本的多表條件查詢,and/or的使用
select distinct a.id as id, a.visit_date as visit_date, a.people as people from stadium as a, stadium as b, stadium as c where a.people >= 100 and b.people >= 100 and c.people >= 100 and ((a.id + 1 =b.id and a.id + 2 = c.id) or (a.id -1 = b.id and a.id + 1 = c.id) or (a.id -2 = b.id and a.id -1 = c.id)) order by a.id;
620 有趣的電影
from: https://leetcode-cn.com/problems/not-boring-movies/
思路:基礎的條件查詢和order by
select * from cinema where description != 'boring' and id % 2 = 1 order by rating desc;
626 換座位
from: https://leetcode-cn.com/problems/exchange-seats/
思路:使用多表條件查詢,或者left join配合IF函數
select a.id as id, b.student as student from seat as a, seat as b, (select max(id) as maxId from seat) as c where (a.id % 2 = 1 and a.id + 1 = b.id) or (a.id % 2 = 0 and a.id - 1 = b.id) or (a.id %2 = 1 and a.id = c.maxId and b.id = a.id) order by a.id;
select a.id as id, IF(a.id % 2 = 1, IF(a.id = (select max(id) from seat), a.student, b.student), c.student) as student from seat as a left join seat as b on a.id + 1 = b.id left join seat as c on a.id -1 = c.id order by a.id;
627 交換工資
from: https://leetcode-cn.com/problems/swap-salary/
思路:IF函數
update salary set sex = IF(sex = 'm', 'f', 'm');
1179 重新格式化部門表
from: https://leetcode-cn.com/problems/reformat-department-table/
思路:group by裏對SUM和IF函數的運用
SELECT id, sum(IF(
month='Jan',revenue,NULL)) Jan_Revenue, sum(IF(
month='Feb',revenue,NULL)) Feb_Revenue, sum(IF(
month='Mar',revenue,NULL)) Mar_Revenue, sum(IF(
month='Apr',revenue,NULL)) Apr_Revenue, sum(IF(
month='May',revenue,NULL)) May_Revenue, sum(IF(
month='Jun',revenue,NULL)) Jun_Revenue, sum(IF(
month='Jul',revenue,NULL)) Jul_Revenue, sum(IF(
month='Aug',revenue,NULL)) Aug_Revenue, sum(IF(
month='Sep',revenue,NULL)) Sep_Revenue, sum(IF(
month='Oct',revenue,NULL)) Oct_Revenue, sum(IF(
month='Nov',revenue,NULL)) Nov_Revenue, sum(IF(
month='Dec',revenue,NULL)) Dec_Revenue FROM Department group by id;
多線程
1114 按序打印
from: https://leetcode-cn.com/problems/print-in-order/solution/javayou-jie-by-no-one-9/
https://leetcode-cn.com/problems/print-in-order/solution/an-xu-da-yin-by-leetcode/
https://leetcode-cn.com/problems/print-in-order/solution/javabing-fa-gong-ju-lei-da-lian-bing-by-kevinbauer/
思路:1)synchronized對對象加鎖,加鎖區域操作作爲標記的普通變量,退出加鎖區域前調用lock.notifyAll()喚醒其餘線程;2)使用AtomicInteger;3)無鎖方案,volatile和int賦值操作(int讀寫是原子操作,i++不是)4)其他:CountDownLatch的使用;Semaphore的使用;
1115 交替打印FooBar
思路:類似上題,無鎖方案中,死循環裏要使用Thread.yield()以避免循環一直佔用CPU導致超時
1116 打印零與奇偶數
思路:類似上題,無鎖方案裏,volatile int的值使用0,1,2表示3種狀態。
1117 H2O 生成
from: https://leetcode-cn.com/problems/building-h2o/solution/xin-hao-liang-by-hansin1997-3/
思路:Semaphore用法
1195 交替打印字符串
from: https://leetcode-cn.com/problems/fizz-buzz-multithreaded/solution/liang-chong-javajie-jue-fang-an-shi-yong-semaphore/
https://leetcode-cn.com/problems/fizz-buzz-multithreaded/solution/1ge-reentrantlock-1ge-condition-1ge-volatilebian-l/
思路:Semaphore用法或者無鎖方案
1226 哲學家進餐
思路:避免死鎖的幾種策略見下,使用Semaphore,ReentrantLock,synchronized等實現
1)哲學家0先爭用左手叉,再爭用右手叉;其他哲學家先爭用右手叉,再爭用左手叉。(所以,哲學家0,1會爭用它們之間的叉子,肯定有一個爭不到,避免了5人同時進餐的死鎖情況)
2)設置信號量最多運行4個哲學家同時進食(包括選擇叉子-吃-放下叉子),並且對每個叉子設置信號量防止被2個哲學家同時使用。
3)設置信號量最多運行4個哲學家同時選擇叉子,並且對每個叉子設置信號量防止被2個哲學家同時使用。
4)選擇叉子時設置臨界區,拿到2個叉子後再退出臨界區(同一時刻只有1個哲學家可以選擇叉子,防止全部人搶叉子造成死鎖),並且對每個叉子設置信號量防止被2個哲學家同時使用。
5)設置臨界區每次只讓1個哲學家進食(包括選擇叉子-吃-放下叉子),此時無需對叉子進行限制。
劍指Offer
面試題03 數組中重複的數字
from: https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
思路:使用map來遍歷一遍就可以找出重複的字符
面試題04 二維數組中的查找
from: https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/
思路:右上角開始查找,大了往左走,小了往下走。
面試題05 替換空格
from: https://leetcode-cn.com/problemset/lcof/
思路:遍歷字符串
面試題06 從尾到頭打印鏈表
from: https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/
思路:使用棧或者數組暫存遍歷鏈表的值,再反向輸出
面試題07 重建二叉樹
from: https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/
思路:遞歸求解。中序遍歷結果爲:[左子樹遍歷結果,根節點,右子樹遍歷結果];前序遍歷結果爲:[根節點,左子樹前遍歷結果,右子樹前遍歷結果](根據左子樹節點數目來確定分界線)。
面試題09 用兩個棧實現隊列
from: https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/
思路:Stack1正向進入,隊頭在棧底,用於進隊列操作;Stack2逆向進入,隊頭在棧頂,用於出隊列操作;tag標記當前使用的是哪個棧;如果操作時使用的棧不對就先做一次倒庫。
面試題10- I 斐波那契數列
from: https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/
思路:遞歸實現思路簡單,但會超時。改爲循環來實現,2個變量保留前2個歷史值。
面試題10- II 青蛙跳臺階問題
from: https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/
思路:根據遞歸分析可知,和斐波那契數列同解
面試題11 旋轉數組的最小數字
from: https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/
思路:左右2個排序數組,原數組的隊頭和隊尾分別是2個排序數組的最小和最大值;理由此特點二分查找,並和隊尾比較來確定位置。
面試題12 矩陣中的路徑
from: https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/
思路:深度優先搜索(遞歸實現)。已走過的路徑需要標記下(賦值爲非字母)。
面試題13 機器人的運動範圍
from: https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/
思路:深度優先搜索(遞歸實現)或廣度優先搜索(循環操作隊列實現)。已走過的路徑需要使用矩陣來標記。
面試題14- I 剪繩子
from: https://leetcode-cn.com/problems/jian-sheng-zi-lcof/
思路:貪心算法,爲使乘積最大,儘量切分成更多段(每段最小長度爲3),剩餘的部分:2保留,1和前面的3合併後再拆爲2+2
面試題14- II 剪繩子 II
from: https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/
思路:同上題,還需要冪求餘(循環求餘 、 快速冪求餘)
面試題15 二進制中1的個數
from: https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/
思路:使用與運算每位循環求解;使用n&n-1的特點(消除最高位的1)
面試題16 數值的整數次方
from: https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/
思路:快速冪法(轉換爲位運算)
面試題17 打印從1到最大的n位數
from: https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/
思路:序列上限是10^n-1
面試題18 刪除鏈表的節點
from: https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/
思路:雙指針或者添加假頭
面試題19 正則表達式匹配
from: https://leetcode-cn.com/problems/zheng-ze-biao-da-shi-pi-pei-lcof/
思路:遞歸求解,對對於*或者.*的匹配,最大長度不超過目標字符串長度,故可以類舉。也可以使用動態規劃方法求解。
面試題20 表示數值的字符串
from: https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/
思路:正則表達式匹配,可以根據運行的錯誤結果不斷調整正則表達式(因爲無法直接總結出有效數值的模式,所以正則的設計會有錯誤)
面試題21 調整數組順序使奇數位於偶數前面
from: https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/
思路:首位雙指針遍歷交換奇偶
面試題22 鏈表中倒數第k個節點
from: https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/
思路:雙指針,保持k距離,一個指針探尾時,另一個指針即所求
面試題24 反轉鏈表
from: https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/
思路:2指針遍歷,1個指向舊隊頭,1個指向新隊頭,1個臨時指針用於完成節點從舊隊到新隊。也可遞歸求解,得到子序列後將原頭結點放到該子序列的末尾(子序列原末尾爲原頭結點的next節點,故O(1)完成)。
面試題25 合併兩個排序的鏈表
from: https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/
思路:歸併排序,合併後的鏈表可以添加僞頭來方便操作
面試題26 樹的子結構
from: https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/
思路:遞歸求解,A的當前節點和B的根節點值不相等時,遞歸A的2個子樹;相等時,再判斷A是否包含B(另一個遞歸來求解)。
面試題27 二叉樹的鏡像
from: https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/
思路:遞歸求解,類似先序遍歷
面試題28 對稱的二叉樹
from: https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/
思路:原問題轉化爲它的2個子樹是鏡像;判斷2個樹是否是鏡像,可以寫成遞歸
面試題29 順時針打印矩陣
from: https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/
思路:設定矩陣4個邊界值,循環進行上、右、下、左的遍歷,每結束一邊就通過改變邊界值來刪除該邊,直至邊界差(寬或高)小於0。
面試題30 包含min函數的棧
from: https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/
思路:使用輔助棧保存最小值序列,進棧時比輔助棧棧頂小時進輔助棧,出棧時僅當和輔助棧棧頂一樣時出輔助棧。由棧的先進後出特性可知其他情況不處理是不影響最小值的。
面試題31 棧的壓入、彈出序列
from: https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/
思路:棧模擬順序入棧,當棧頂和出棧序列頭元素相同時出棧,最後檢查模擬棧是否爲空。
面試題32 - I 從上到下打印二叉樹
from: https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/
思路:廣度優先搜索(隊列+循環)
面試題32 - II 從上到下打印二叉樹 II
from: https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/
思路:廣度優先搜索(隊列+循環),每次操作當前隊列所有元素(即對應一層)
面試題32 - III 從上到下打印二叉樹 III
from: https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/submissions/
思路:廣度優先搜索(隊列+循環),每次操作當前隊列所有元素(即對應一層),偶數層時將當前層的數據先反轉,再放入結果中
面試題33 二叉搜索樹的後序遍歷序列
from: https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/
思路:後序遍歷序列是[左子樹,右子樹,根節點],可知根節點,二叉排序樹特定是左子樹<根節點<右子樹(本題沒有值相等的節點),可以劃分出左右子樹,再遞歸驗證。
面試題34 二叉樹中和爲某一值的路徑
from: https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/
思路:深度優先搜索(遞歸)
面試題35 複雜鏈表的複製
from: https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/
思路:使用Map存儲<舊節點,新節點>對,直接複製2個指針
面試題36 二叉搜索樹與雙向鏈表
from: https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/
思路:爲結果鏈表創建僞頭節點,保留頭尾指針,在中序遍歷中不斷將當前節點添加到結果鏈表的末尾(但是不將結果鏈表首位相連,是因爲結果鏈表的末尾即當前節點,它的右子樹還需要遍歷,所以右指針不能動)。不創建僞頭的話,需要每次操作尾指針時判斷是否是第一次操作,是的話初始化當前節點爲結果鏈表的第1個節點
面試題37 序列化二叉樹
from: https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/
思路:方法1)標記方法:按層輸出,將所有空節點和不存在節點記爲"null",補全每一層。序列化:廣度優先搜索(隊列+循環),每次操作當前隊列所有元素(即對應一層),每個元素打印其值(爲null打印"null"),節點爲null添加2個null,否則添加左右節點,當該層均爲null時停止。反序列化:根據序列化字符串構造節點數組,對數組中每個非null節點鏈接其左右節點,數組首節點即所求。注:該方法當樹的層次較深時會超時,無法通過驗證。方法2)標記方法:按層輸出,將所有空節點記爲"null",不補全不存在的節點。序列化:同方法1,但節點爲null時什麼也不添加。反序列化:廣度優先搜索(隊列+循環),使用輔助隊列保存所有值;初始化時,輔助隊列彈出隊首,構造根節點後放入BFS隊列;每次BFS隊列彈出一個節點,就從輔助隊列彈出2個值來構造左右子節點,並將非null子節點放入BFS隊列;當輔助隊列爲空時結束。
面試題38 字符串的排列
from: https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/
思路:遞歸遍歷字符串獲取排列(bool數組保存是否已經訪問過);使用Set存儲結果以去重。
面試題39 數組中出現次數超過一半的數字
from: https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/
思路:對消方法。keep記錄當前值,count記錄次數。循環數組,當count==0時,當前值記入keep並count++;否則,比較當前值和keep,相同count++,不同count–
面試題40 最小的k個數
from: https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/
思路:大頂堆(基於堆排序);基於計數排序;基於快排(判斷切分點的位置==k-1)
面試題41 數據流中的中位數
from: https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/
思路:1)大頂推+小頂堆。大頂堆存儲小於等於中位數的值(奇數時存入中位數),小頂堆存儲大於等於中位數的值,小頂堆和大頂堆的數目在偶數時相等,奇數時大頂堆=小頂堆+1。插入時,根據值大小決定插入到大頂堆或小頂堆,然後調整堆大小使得滿足前面提到的約束。查找中位數時,奇數時爲大頂堆堆頂,偶數時爲大頂堆小頂堆的堆頂的均值。2)二分查找插入,維護有序數組,使用二分查找來確定位置並插入。
面試題42 連續子數組的最大和
from: https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/
思路:每當sum小於0就置0,並記錄sum的最大值。
面試題43 1~n整數中1出現的次數
from: https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/
思路:使用循環的方法依次計算每位上可能出現的1的個數;
面試題44 數字序列中某一位的數字
from: https://leetcode-cn.com/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/
思路:先統計出每位數有多少個數字,然後,確定是幾位數,再確定是哪個數的哪一位。
面試題45 把數組排成最小的數
from: https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/
思路:利用字符串s1+s2和s2+s1的比較來確定s1和s2哪個比較小。
面試題46 把數字翻譯成字符串
from: https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/
思路:1)動態規劃。根據num[i]和num[i−1]是否能合成一個字符來遞歸求解新的翻譯數目。2)把選擇1個還是2個數字一起來翻譯看成2種選擇,轉換爲二叉樹,使用回溯法求解。
面試題47 禮物的最大價值
from: https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/
思路:動態規劃:d[i][j]=max(d[i−1][j],d[i][j−1])+grid[i][j]
面試題48 最長不含重複字符的子字符串
from: https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/
思路:2個指針記錄滑動窗口(表示當前最長不重複字符串)的首尾,不斷移動尾指針,如果尾部值已經在滑動窗口內就移動首指針直至將其移出;使用map存儲滑動窗口內的值來加速查找;不斷根據滑動窗口大小更新max值。
面試題49 醜數
from: https://leetcode-cn.com/problems/chou-shu-lcof/
思路:u[]存儲醜數,設置3個指針分別表示*2,*3,*5來遞增的當前最小丑數的下標,則當前醜數=min(u[p2]*2, u[p3]*8, u[p5]*5),且如果當前醜數==u[px]*x時,把px++
面試題50 第一個只出現一次的字符
from: https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/
思路:使用Map記錄出現次數
面試題51 數組中的逆序對
from: https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/
思路:1)兩遍循環進行統計會超時。2)分治法,類似歸併排序的做法,在合併2個有序數組時,計算逆序對。
面試題52 兩個鏈表的第一個公共節點
from: https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/
思路:先計算2個鏈表的長度,然後以長度差設2個指針分別遍歷,相遇即所求。
面試題53 - I 在排序數組中查找數字 I
from: https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/
思路:二分查找後前後統計重複個數
面試題53 - II 0~n-1中缺失的數字
from: https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof/
思路:二分查找,判斷是否是目標的依據:該位置的值和該位置座標是否相同
面試題54 二叉搜索樹的第k大節點
from: https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/
思路:右子樹,根節點,左子樹遍歷,當得到第k個元素時終止。
面試題55 - I 二叉樹的深度
from: https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/
思路:遞歸求深度
面試題55 - II 平衡二叉樹
from: https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/
思路:遞歸求深度時順便判斷是否平衡
面試題56 - I 數組中數字出現的次數
from: https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/
思路:1)Map求解。2)位運算求解。先求出異或和,從異或和找到某位爲1的數,使用該數和數組每個數相異或來判斷屬於a或b分組,2個分組分別求異或和,得到2個解。
面試題56 - II 數組中數字出現的次數 II
from: https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/
思路:1)Map求解。2)位運算求解。從地位到高位統計該位爲1的數字的個數,如果個數不可以整除3,則所求在該位爲1。3)狀態機。
面試題57 和爲s的兩個數字
from: https://leetcode-cn.com/problems/he-wei-sde-liang-ge-shu-zi-lcof/
思路:1)Map求解。2)首位指針。當和大了移動尾指針,當和小了移動首指針,當首指針>尾指針結束。
面試題57 - II 和爲s的連續正數序列
from: https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/
思路:1)雙循環枚舉,第2個循環直接使用求和公式替代,根據求和公式反向求解可行的終點。2)滑動窗口雙指針。初始時窗口爲1-2,sum=3,當sum小於s時尾指針後移,當大於時首指針後移,當相等時記錄並首指針後移。當首指針等於尾指針時結束。
面試題58 - I 翻轉單詞順序
from: https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/
思路:按空格split成數組後逆序輸出。C等語言是對單詞和整個字符進行2次字母翻轉。
面試題58 - II 左旋轉字符串
from: https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/
思路:1)Java使用substring。2)原地翻轉。先翻轉前部分字符串,再翻轉後部分字符串,最後翻轉整個字符串。
面試題59 - I 滑動窗口的最大值
from: https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/
思路:1)每次對滑動窗口內的元素遍歷求最大值,也可以保存最大值的座標,僅當最大值不在窗口內時再重新求最大值,否則快速比較新值和最大值來更新。2)單調雙向隊列求解。隊列保存的是元素下標。進窗口元素:利用窗口從單向向後移動造成的後進元素有效期肯定大於之前元素有效期的特點,故,在當前元素大於之前元素時,把所有之前小於等於的元素彈出隊列,然後插入當前元素。出窗口元素:當前元素和隊首一致時,彈出隊首。
面試題59 - II 隊列的最大值
from: https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/
思路:藉助一個單調的雙端隊列。基於隊列性質:尾部插入一個元素時,它前面所有比它小的元素就不會再對答案產生影響。插入:從輔助隊列移去比當前元素小或相等的元素,然後插入當前元素。彈出:當彈出元素和輔助隊列頭部元素一樣時,將輔助隊列的隊首出列。
面試題60 n個骰子的點數
from: https://leetcode-cn.com/problems/nge-tou-zi-de-dian-shu-lcof/
思路:動態規劃。dp[i][j] ,表示投擲完 i 枚骰子後,總點數爲 j 的排列情況總數。它等於投擲完 n-1 枚骰子後,對應 j-1, j-2, j-3, … , j-6 出現的次數之和(第n次分別投1,2,…6)。最後除以排列情況總數6^n即爲所求概率。
面試題61 撲克牌中的順子
from: https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/
思路:排序,然後遍歷,遇到0增加skip計數,否則驗證是否n[i]==n[i+1],並更新skip=skip-(n[i+1]-n[i]-1),驗證skip是否小於0。排序部分可以使用計數排序來高效實現。
面試題62 圓圈中最後剩下的數字
from: https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/
思路:1)使用鏈表模擬。2)遞歸。f(n,m)表示n個值按m循環刪除的結果,刪除掉1個後,設其位置k,則從k+1映射爲0,對剩餘的元素重新編碼並開始刪除,得到f(n,m)=(f(n-1,m)+k+1)%n,將k=(m-1)%n代入簡化後可得f(n,m)=(f(n-1,m)+m)%n,即爲遞歸公式。3)動態規劃。由前遞歸公式可知,設f[n]表示n個值按m循環刪除,則f[n]=(f[n-1]+m)%n
面試題63 股票的最大利潤
from: https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof/
思路:在每天都買入,然後在之後的最大值賣出,並更新最大利潤。可以使用最小值來剪枝,緩存最大值和其座標來複用。
面試題64 求1+2+…+n
from: https://leetcode-cn.com/problems/qiu-12n-lcof/
思路:使用遞歸代替循環,&&代替if條件語句
面試題65 不用加減乘除做加法
from: https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/
思路:利用二進制可推導 a+b 等價於(a^b)+((a&b)<<1),遞歸求解
面試題66 構建乘積數組
from: https://leetcode-cn.com/problems/gou-jian-cheng-ji-shu-zu-lcof/
思路:1)構建數組 L 和 R,L[i] 表示 a[i] 左邊的乘積,而 R[i] 表示 a[i] 右邊的乘積。正向遍歷一遍構造L,反向遍歷一遍構造R,再正向遍歷一遍通過L[i]*R[i]來獲得所求。2)優化:R可以省去,在反向遍歷時在L上直接計算R[i]並更新L[i]*R[i]結果
面試題67 把字符串轉換成整數
from: https://leetcode-cn.com/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof/
思路:處理前導空格,符號,數字累加值,數字結束處理,溢出處理。
面試題68 - I 二叉搜索樹的最近公共祖先
from: https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/
思路:遞歸求解。根據二叉搜索樹特性,如果2個節點都小於/大於當前節點的話就在左子樹/右子樹尋找,否則返回當前節點。
面試題68 - II 二叉樹的最近公共祖先
from: https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/