知名互聯(lián)網(wǎng)公司校招中常見的算法題(6-8)
題目六:無重復(fù)字符的最長子串
給定一個字符串,找出不含有重復(fù)字符的最長子串的長度。
解決思路:
我們可以用滑動窗口來解決這個問題。我們用兩個指針 i 和 j 來表示窗口的左右邊界。每次移動右指針 j,同時用哈希表記錄每個字符出現(xiàn)的位置。如果當前字符已經(jīng)在哈希表中出現(xiàn)過了,那么就將左指針 i 移動到該字符上次出現(xiàn)的位置的下一個位置。每次更新最長子串的長度。
代碼實現(xiàn):
public int lengthOfLongestSubstring(String s) {
? int n = s.length();
? int i = 0;
? int j = 0;
? int maxLen = 0;
? Map<Character, Integer> map = new HashMap<>();
? while (j < n) {
? ? ? char c = s.charAt(j);
? ? ? if (map.containsKey(c)) {
? ? ? ? ? i = Math.max(i, map.get(c) + 1);
? ? ? }
? ? ? map.put(c, j);
? ? ? maxLen = Math.max(maxLen, j - i + 1);
? ? ? j++;
? }
? return maxLen;
}
題目七:合并兩個有序鏈表
給定兩個有序鏈表,將它們合并成一個新的有序鏈表并返回。
解決思路:
我們可以用遞歸的方法來解決這個問題。我們將兩個鏈表的頭節(jié)點進行比較,將較小的節(jié)點作為合并后鏈表的頭節(jié)點,并將該節(jié)點的 next 指向遞歸合并后的鏈表。
代碼實現(xiàn):
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;
? }
}
題目八:最小棧
設(shè)計一個支持 push、pop、top 和在常數(shù)時間內(nèi)檢索到最小元素的操作的棧。
解決思路:
我們可以用兩個棧來實現(xiàn)這個問題。一個棧用來存儲元素,另一個棧用來存儲當前棧中的最小值。
具體來說,當一個元素被壓入棧時,我們同時將該元素壓入最小棧中,如果該元素比最小棧的棧頂元素小,則將該元素也壓入最小棧中。當一個元素從棧中彈出時,我們同時將該元素從最小棧中彈出。當我們需要獲取當前棧中的最小元素時,我們只需要查看最小棧的棧頂元素即可。
代碼實現(xiàn):
class MinStack {
? Stack<Integer> stack;
? Stack<Integer> minStack;
? public MinStack() {
? stack = new Stack<>();
? minStack = new Stack<>();
}
public void push(int val) {
? stack.push(val);
? if (minStack.isEmpty() || val <= minStack.peek()) {
? ? ? minStack.push(val);
? }
}
public void pop() {
? if (stack.peek().equals(minStack.peek())) {
? ? ? minStack.pop();
? }
? stack.pop();
}
public int top() {
? return stack.peek();
}
public int getMin() {
? return minStack.peek();
}
}
以上是關(guān)于常見算法題的解決思路、代碼實現(xiàn)以及實際案例的詳細講解。對于互聯(lián)網(wǎng)公司的校招來說,掌握這些算法題可以幫助我們更好地應(yīng)對面試。當然,還需要多多練習,才能真正掌握這些算法。