HIGH高頻H2(11-20)
HIGH.11 合併兩個排序的連結串列
輸入兩個遞增排序的連結串列,合併這兩個連結串列並使新連結串列中的節點仍然是遞增排序的。
示例1:
輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4
限制:0 <= 連結串列長度 <= 1000
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
迭代
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(-1), pre = dummyHead;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
pre.next = l1;
pre = pre.next;
l1 = l1.next;
} else {
pre.next = l2;
pre = pre.next;
l2 = l2.next;
}
}
if (l1 != null) {
pre.next = l1;
}
if (l2 != null) {
pre.next = l2;
}
return dummyHead.next;
}
}
遞迴
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
if (l1.val <= l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
HIGH.12 合併K 個排序連結串列
給你一個連結串列陣列,每個連結串列都已經按升序排列。
請你將所有連結串列合併到一個升序連結串列中,返回合併後的連結串列。
示例 1:
輸入:lists = [[1,4,5],[1,3,4],[2,6]]
輸出:[1,1,2,3,4,4,5,6]
解釋:連結串列陣列如下:
[
1->4->5,
1->3->4,
2->6
]
將它們合併到一個有序連結串列中得到。
1->1->2->3->4->4->5->6
示例 2:輸入:lists = []
輸出:[]
示例 3:輸入:lists = [[]]
輸出:[]來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/merge-k-sorted-lists
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
思路巨簡單,難得一次都不用除錯!!!迴圈直接搞定,什麼分治大法我不懂!
用容量為K的最小堆優先佇列,把連結串列的頭結點都放進去,然後出隊當前優先佇列中最小的,掛上連結串列,,然後讓出隊的那個節點的下一個入隊,再出隊當前優先佇列中最小的,直到優先佇列為空。
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0) {
return null;
}
ListNode dummyHead = new ListNode(0);
ListNode curr = dummyHead;
PriorityQueue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>() {
@Override
public int compare(ListNode o1, ListNode o2) {
return o1.val - o2.val;
}
});
for (ListNode list : lists) {
if (list == null) {
continue;
}
pq.add(list);
}
while (!pq.isEmpty()) {
ListNode nextNode = pq.poll();
curr.next = nextNode;
curr = curr.next;
if (nextNode.next != null) {
pq.add(nextNode.next);
}
}
return dummyHead.next;
}
}
HIGH.13 買賣股票的最佳時機
給定一個陣列,它的第 i 個元素是一支給定股票第 i 天的價格。
如果你最多隻允許完成一筆交易(即買入和賣出一支股票一次),設計一個演算法來計算你所能獲取的最大利潤。
注意:你不能在買入股票前賣出股票。
示例 1:
輸入: [7,1,5,3,6,4]
輸出: 5
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5 。
注意利潤不能是 7-1 = 6, 因為賣出價格需要大於買入價格;同時,你不能在買入前賣出股票。
示例 2:輸入: [7,6,4,3,1]
輸出: 0
解釋: 在這種情況下, 沒有交易完成, 所以最大利潤為 0。來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
思路還是挺清晰的,還是DP思想:
記錄【今天之前買入的最小值】
計算【今天之前最小值買入,今天賣出的獲利】,也即【今天賣出的最大獲利】
比較【每天的最大獲利】,取最大值即可
class Solution {
public int maxProfit(int[] prices) {
if(prices.length <= 1)
return 0;
int min = prices[0], max = 0;
for(int i = 1; i < prices.length; i++) {
max = Math.max(max, prices[i] - min);
min = Math.min(min, prices[i]);
}
return max;
}
}
HIGH.14 買賣股票的最佳時機II
給定一個陣列,它的第 i 個元素是一支給定股票第 i 天的價格。
設計一個演算法來計算你所能獲取的最大利潤。你可以儘可能地完成更多的交易(多次買賣一支股票)。
注意:你不能同時參與多筆交易(你必須在再次購買前出售掉之前的股票)。
示例 1:
輸入: [7,1,5,3,6,4]
輸出: 7
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 3 天(股票價格 = 5)的時候賣出, 這筆交易所能獲得利潤 = 5-1 = 4 。
隨後,在第 4 天(股票價格 = 3)的時候買入,在第 5 天(股票價格 = 6)的時候賣出, 這筆交易所能獲得利潤 = 6-3 = 3 。
示例 2:輸入: [1,2,3,4,5]
輸出: 4
解釋: 在第 1 天(股票價格 = 1)的時候買入,在第 5 天 (股票價格 = 5)的時候賣出, 這筆交易所能獲得利潤 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接連購買股票,之後再將它們賣出。
因為這樣屬於同時參與了多筆交易,你必須在再次購買前出售掉之前的股票。
示例 3:輸入: [7,6,4,3,1]
輸出: 0
解釋: 在這種情況下, 沒有交易完成, 所以最大利潤為 0。來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
演算法題(×) 腦筋急轉彎題( √ )
掃描一遍 只要後一天比前一天大 就把這兩天的差值加一下
class Solution {
public int maxProfit(int[] prices) {
int ans=0;
for(int i=1;i<=prices.length-1;i++)
{
if(prices[i]>prices[i-1])
{
ans+=prices[i]-prices[i-1];
}
}
return ans;
}
}
HIGH.15 最大子序和
給定一個整數陣列 nums ,找到一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。
示例:
輸入: [-2,1,-3,4,-1,2,1,-5,4]
輸出: 6
解釋: 連續子陣列 [4,-1,2,1] 的和最大,為 6。
進階:如果你已經實現複雜度為 O(n) 的解法,嘗試使用更為精妙的分治法求解。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/maximum-subarray
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
class Solution {
public int maxSubArray(int[] nums) {
int res = nums[0];
int sum = 0;
for (int num : nums) {
if (sum > 0)
sum += num;
else
sum = num;
res = Math.max(res, sum);
}
return res;
}
}
HIGH.16 最小棧
設計一個支援 push ,pop ,top 操作,並能在常數時間內檢索到最小元素的棧。
push(x) —— 將元素 x 推入棧中。
pop() —— 刪除棧頂的元素。
top() —— 獲取棧頂元素。
getMin() —— 檢索棧中的最小元素。
示例:
輸入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]輸出:
[null,null,null,null,-3,null,0,-2]解釋:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
提示:
pop、top 和 getMin 操作總是在 非空棧 上呼叫。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/min-stack
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
class MinStack {
private Node head;
public void push(int x) {
if(head == null)
head = new Node(x, x);
else
head = new Node(x, Math.min(x, head.min), head);
}
public void pop() {
head = head.next;
}
public int top() {
return head.val;
}
public int getMin() {
return head.min;
}
private class Node {
int val;
int min;
Node next;
private Node(int val, int min) {
this(val, min, null);
}
private Node(int val, int min, Node next) {
this.val = val;
this.min = min;
this.next = next;
}
}
}
HIGH.17 LRU 快取機制
運用你所掌握的資料結構,設計和實現一個 LRU (最近最少使用) 快取機制 。
實現 LRUCache 類:LRUCache(int capacity) 以正整數作為容量 capacity 初始化 LRU 快取
int get(int key) 如果關鍵字 key 存在於快取中,則返回關鍵字的值,否則返回 -1 。
void put(int key, int value) 如果關鍵字已經存在,則變更其資料值;如果關鍵字不存在,則插入該組「關鍵字-值」。當快取容量達到上限時,它應該在寫入新資料之前刪除最久未使用的資料值,從而為新的資料值留出空間。
進階:你是否可以在 O(1) 時間複雜度內完成這兩種操作?
示例:
輸入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
輸出
[null, null, null, 1, null, -1, null, -1, 3, 4]解釋
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 快取是 {1=1}
lRUCache.put(2, 2); // 快取是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 該操作會使得關鍵字 2 作廢,快取是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 該操作會使得關鍵字 1 作廢,快取是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4
提示:
1 <= capacity <= 3000
0 <= key <= 3000
0 <= value <= 104
最多呼叫 3 * 104 次 get 和 put來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/lru-cache
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
class LRUCache {
private int cap;
private Map<Integer, Integer> map = new LinkedHashMap<>(); // 保持插入順序
public LRUCache(int capacity) {
this.cap = capacity;
}
public int get(int key) {
if (map.keySet().contains(key)) {
int value = map.get(key);
map.remove(key);
// 保證每次查詢後,都在末尾
map.put(key, value);
return value;
}
return -1;
}
public void put(int key, int value) {
if (map.keySet().contains(key)) {
map.remove(key);
} else if (map.size() == cap) {
Iterator<Map.E***y<Integer, Integer>> iterator = map.e***ySet().iterator();
iterator.next();
iterator.remove();
// int firstKey = map.e***ySet().iterator().next().getValue();
// map.remove(firstKey);
}
map.put(key, value);
}
}
HIGH.18 尋找兩個有序陣列的中位數
給定兩個大小為 m 和 n 的正序(從小到大)陣列 nums1 和 nums2。請你找出並返回這兩個正序陣列的中位數。
進階:你能設計一個時間複雜度為 O(log (m+n)) 的演算法解決此問題嗎?
示例 1:
輸入:nums1 = [1,3], nums2 = [2]
輸出:2.00000
解釋:合併陣列 = [1,2,3] ,中位數 2
示例 2:輸入:nums1 = [1,2], nums2 = [3,4]
輸出:2.50000
解釋:合併陣列 = [1,2,3,4] ,中位數 (2 + 3) / 2 = 2.5
示例 3:輸入:nums1 = [0,0], nums2 = [0,0]
輸出:0.00000
示例 4:輸入:nums1 = [], nums2 = [1]
輸出:1.00000
示例 5:輸入:nums1 = [2], nums2 = []
輸出:2.00000
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
這道題讓我們求兩個有序陣列的中位數,而且限制了時間複雜度為O(log (m+n)),看到這個時間複雜度,自然而然的想到了應該使用二分查詢法來求解。那麼回顧一下中位數的定義,如果某個有序陣列長度是奇數,那麼其中位數就是最中間那個,如果是偶數,那麼就是最中間兩個數字的平均值。這裡對於兩個有序陣列也是一樣的,假設兩個有序陣列的長度分別為m和n,由於兩個陣列長度之和 m+n 的奇偶不確定,因此需要分情況來討論,對於奇數的情況,直接找到最中間的數即可,偶數的話需要求最中間兩個數的平均值。為了簡化程式碼,不分情況討論,我們使用一個小trick,我們分別找第 (m+n+1) / 2 個,和 (m+n+2) / 2 個,然後求其平均值即可,這對奇偶數均適用。加入 m+n 為奇數的話,那麼其實 (m+n+1) / 2 和 (m+n+2) / 2 的值相等,相當於兩個相同的數字相加再除以2,還是其本身。
這裡我們需要定義一個函式來在兩個有序陣列中找到第K個元素,下面重點來看如何實現找到第K個元素。首先,為了避免產生新的陣列從而增加時間複雜度,我們使用兩個變數i和j分別來標記陣列nums1和nums2的起始位置。然後來處理一些邊界問題,比如當某一個陣列的起始位置大於等於其陣列長度時,說明其所有數字均已經被淘汰了,相當於一個空陣列了,那麼實際上就變成了在另一個陣列中找數字,直接就可以找出來了。還有就是如果K=1的話,那麼我們只要比較nums1和nums2的起始位置i和j上的數字就可以了。難點就在於一般的情況怎麼處理?因為我們需要在兩個有序陣列中找到第K個元素,為了加快搜尋的速度,我們要使用二分法,對K二分,意思是我們需要分別在nums1和nums2中查詢第K/2個元素,注意這裡由於兩個陣列的長度不定,所以有可能某個陣列沒有第K/2個數字,所以我們需要先檢查一下,陣列中到底存不存在第K/2個數字,如果存在就取出來,否則就賦值上一個整型最大值。如果某個陣列沒有第K/2個數字,那麼我們就淘汰另一個數字的前K/2個數字即可。有沒有可能兩個陣列都不存在第K/2個數字呢,這道題裡是不可能的,因為我們的K不是任意給的,而是給的m+n的中間值,所以必定至少會有一個陣列是存在第K/2個數字的。最後就是二分法的核心啦,比較這兩個陣列的第K/2小的數字midVal1和midVal2的大小,如果第一個陣列的第K/2個數字小的話,那麼說明我們要找的數字肯定不在nums1中的前K/2個數字,所以我們可以將其淘汰,將nums1的起始位置向後移動K/2個,並且此時的K也自減去K/2,呼叫遞迴。反之,我們淘汰nums2中的前K/2個數字,並將nums2的起始位置向後移動K/2個,並且此時的K也自減去K/2,呼叫遞迴即可。
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int left = (m + n + 1) / 2;
int right = (m + n + 2) / 2;
return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;
}
//i: nums1的起始位置 j: nums2的起始位置
public int findKth(int[] nums1, int i, int[] nums2, int j, int k){
if( i >= nums1.length) return nums2[j + k - 1];//nums1為空陣列
if( j >= nums2.length) return nums1[i + k - 1];//nums2為空陣列
if(k == 1){
return Math.min(nums1[i], nums2[j]);
}
int midVal1 = (i + k / 2 - 1 < nums1.length) ? nums1[i + k / 2 - 1] : Integer.MAX_VALUE;
int midVal2 = (j + k / 2 - 1 < nums2.length) ? nums2[j + k / 2 - 1] : Integer.MAX_VALUE;
if(midVal1 < midVal2){
return findKth(nums1, i + k / 2, nums2, j , k - k / 2);
}else{
return findKth(nums1, i, nums2, j + k / 2 , k - k / 2);
}
}
}
HIGH.19 最長迴文子串
給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為 1000。
示例 1:
輸入: "babad"
輸出: "bab"
注意: "aba" 也是一個有效答案。
示例 2:輸入: "cbbd"
輸出: "bb"來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/longest-palindromic-substring
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() == 0) {
return "";
}
// 儲存起始位置,測試了用陣列似乎能比全域性變數稍快一點
int[] range = new int[2];
char[] str = s.toCharArray();
for (int i = 0; i < s.length(); i++) {
// 把迴文看成中間的部分全是同一字元,左右部分相對稱
// 找到下一個與當前字元不同的字元
i = findLongest(str, i, range);
}
return s.substring(range[0], range[1] + 1);
}
public static int findLongest(char[] str, int low, int[] range) {
// 查詢中間部分
int high = low;
while (high < str.length - 1 && str[high + 1] == str[low]) {
high++;
}
// 定位中間部分的最後一個字元
int ans = high;
// 從中間向左右擴散
while (low > 0 && high < str.length - 1 && str[low - 1] == str[high + 1]) {
low--;
high++;
}
// 記錄最大長度
if (high - low > range[1] - range[0]) {
range[0] = low;
range[1] = high;
}
return ans;
}
}
HIGH.20 合併兩個有序陣列
給你兩個有序整數陣列 nums1 和 nums2,請你將 nums2 合併到 nums1 中,使 nums1 成為一個有序陣列。
說明:
初始化 nums1 和 nums2 的元素數量分別為 m 和 n 。
你可以假設 nums1 有足夠的空間(空間大小大於或等於 m + n)來儲存 nums2 中的元素。
示例:
輸入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3輸出:[1,2,2,3,5,6]
提示:
-10^9 <= nums1[i], nums2[i] <= 10^9
nums1.length == m + n
nums2.length == n來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/merge-sorted-array
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int p = m-- + n-- - 1;
while (m >= 0 && n >= 0) {
nums1[p--] = nums1[m] > nums2[n] ? nums1[m--] : nums2[n--];
}
while (n >= 0) {
nums1[p--] = nums2[n--];
}
}
}
相關文章
- HIGH高頻H1(1-10)
- 【leetcode】高頻題目整理_樹結構篇( High Frequency Problems, Tree )LeetCode
- HDFS High Availability(HA)高可用配置AI
- BUUCTF-Misc(11-20)
- 高頻面試題面試題
- Redis高頻40問Redis
- 黑猴子的家:Hadoop NameNode 高可用 (High Availability) 實現解析HadoopAI
- MySQL高頻面試題MySql面試題
- Python學習100例之11-20Python
- Java高頻面試題---RabbitMQJava面試題MQ
- Java高頻面試題---MySQLJava面試題MySql
- Java集合高頻面試題Java面試題
- 小電容為什麼可以通高頻阻低頻?
- H2 Database入門Database
- 前端高頻面試題JavaScript篇前端面試題JavaScript
- 二叉樹高頻題(下)二叉樹
- Selenium 高頻面試題及答案面試題
- 常見Kotlin高頻問題解惑Kotlin
- 347. 前 K 個高頻元素
- 描述高頻題之佇列&棧佇列
- Performance and High-Availability OptionsORMAI
- High Availability (HA) in SQL ServerAISQLServer
- 如何設定h2 console
- SpringBoot整合系列-整合H2Spring Boot
- Ooracle 高水位線(high water mask)在不同段管理模式下的推進Oracle模式
- Leetcode——347. 前K個高頻元素LeetCode
- 高頻寫入redis場景優化Redis優化
- 2024高頻前端面試題合集(一)前端面試題
- Linux檔案操作高頻使用命令Linux
- 閉包的使用-高頻事件優化事件優化
- Python語言高頻重點彙總Python
- MySQL 高頻面試題,都在這了MySql面試題
- 深度學習高頻手撕程式碼深度學習
- java框架面試高頻問題(SpringMVC)Java框架面試SpringMVC
- Java高頻面試題(2023最新整理)Java面試題
- JavaScript高頻面試試題2——2020.12.04JavaScript面試
- H2資料庫文件索引資料庫索引
- 前端高頻筆試題之HTML/CSS部分前端筆試HTMLCSS