2019 iOS面試題大全---全方面剖析面試
2018 iOS面試題---算法相關
1、七種常見的數組排序算法整理(C語言版本)
2、2019 算法面試相關(leetcode)--數組和鏈表
3、2019 算法面試相關(leetcode)--字符串
4、2019 算法面試相關(leetcode)--棧和隊列
5、2019 算法面試相關(leetcode)--優先隊列
6、2019 算法面試相關(leetcode)--哈希表
7、2019 算法面試相關(leetcode)--樹、二叉樹、二叉搜索樹
8、2019 算法面試相關(leetcode)--遞歸與分治
9、2019 算法面試相關(leetcode)--貪心算法
10、2019 算法面試相關(leetcode)--動態規劃(Dynamic Programming)
11、2019 算法面試相關(leetcode)--動態規劃之背包問題
棧和隊列都是比較常用的數據結構。棧的應用非常的廣泛,比如說,遞歸函數的實現就是借助于棧保存相關的數據。操作系統中每個線程也會使用棧來保存函數調用涉及到的一些參數和其他變量等。棧最大的一個特點就是先進后出(FILO—First-In/Last-Out)。
隊列和棧不同的是,隊列是一種先進先出(FIFO—first in first out)的數據結構。
棧的相關方法:
入棧,s.push(x)
出棧,s.pop()
訪問棧頂,s.top()
判斷棧空,s.empty()
訪問棧中的元素個數,s.size()-
隊列的方法與棧大同小異,列舉如下:
入隊,q.push(x)
出隊,q.pop()
訪問隊首元素,q.front()、訪問隊尾元素,q.back()
判斷隊列空,q.empty()
訪問隊列中的元素個數,q.size()
棧的應用場景:
棧最大的特點是先進后出,要合理利用這一點,也就是在循環過程中,遇到暫時用不到的元素或數據,就先入棧,等合適時機再一一出棧。
1.逆序輸出
2.語法檢查,符號成對出現
3.數制轉換
4.二叉樹的一些操作
等等
一、 有效的括號
給定一個只包括 '(',')','{','}','[',']' 的字符串,判斷字符串是否有效。
有效字符串需滿足:
左括號必須用相同類型的右括號閉合。
左括號必須以正確的順序閉合。
注意空字符串可被認為是有效字符串。
示例 1:
輸入: "()"
輸出: true
示例 2:
輸入: "()[]{}"
輸出: true
示例 3:
輸入: "(]"
輸出: false
示例 4:
輸入: "([)]"
輸出: false
示例 5:
輸入: "{[]}"
輸出: true
這里不用考慮括號的優先級,即'([])'也是有效的
這里就可以用棧的思想:遍歷字符串,如果是左括號就入棧,如果是右括號,就判斷是否和棧頂的左括號是同類型,是就出棧,否則就返回false,循環結束后再去判斷棧是否是空的,空的就返回true,否則返回false
var isValid = function(s) {
let stack = []
for (let i = 0; i < s.length; i++) {
if(s[i]=="("){
stack.push(")");
}else if(s[i]=="["){
stack.push("]");
}else if(s[i]=="{"){
stack.push("}")
}else if(stack.pop()!=s[i]){
return false;
}
}
return !stack.length
};
這里的if else有點多,感覺不夠優雅,可以用哈希表來優化下
var isValid = function(s) {
let stack = []
let dic = {'(':')','[':']','{':'}'}
for (let i = 0; i < s.length; i++) {
if(s[i] in dic) stack.push(s[i])
else if(dic[stack.pop()] != s[i]) return false
}
return !stack.length
};
- 二、 每日溫度
根據每日 氣溫 列表,請重新生成一個列表,對應位置的輸入是你需要再等待多久溫度才會升高的天數。如果之后都不會升高,請輸入 0 來代替。
例如,給定一個列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的輸出應該是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:氣溫 列表長度的范圍是 [1, 30000]。每個氣溫的值的都是 [30, 100] 范圍內的整數。
比較容易想到的就是暴力循環
var dailyTemperatures = function(T) {
let res = []
for(let i = 0; i < T.length; i++){
let num = 0
for(let j = i + 1; j < T.length; j++){
if(T[j] > T[i]){
num = j - i
break
}
}
res.push(num)
}
return res
};
但這種時間復雜度是o(n^2),leetcode上用js跑大概1000ms的樣子,并不理想
這里我們可以用棧的思想,遍歷數組,將索引入棧,遍歷棧,如果元素比棧頂索引對應元素的大,則就可以直接出棧,否則就繼續遍歷數組
var dailyTemperatures = function(T) {
let res = Array(T.length).fill(0)
let stack = []
for(let i = 0; i < T.length; i++){
if(stack.length){
while(stack.length && T[stack[stack.length - 1]] < T[i]){
res[stack[stack.length - 1]] = i - stack.pop()
}
}
stack.push(i)
}
return res
};
這樣就大大縮短了時間,leetcode上用js跑大概100多ms
三、字符串解碼
給定一個經過編碼的字符串,返回它解碼后的字符串。
編碼規則為: k[encoded_string],表示其中方括號內部的 encoded_string 正好重復 k 次。注意 k 保證為正整數。
你可以認為輸入字符串總是有效的;輸入字符串中沒有額外的空格,且輸入的方括號總是符合格式要求的。
此外,你可以認為原始數據不包含數字,所有的數字只表示重復的次數 k ,例如不會出現像 3a 或 2[4] 的輸入。
示例:
s = "3[a]2[bc]", 返回 "aaabcbc".
s = "3[a2[c]]", 返回 "accaccacc".
s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".
從題目上,很容易可以看出用棧來解題比較合適
遍歷字符串,在沒有遇到']'前就先入棧,遇到']'后,反向遍歷棧,直到找到'[',將'[]'之間的字符串提取出來,在繼續遍歷棧,提取出'['前的數字nums,注意該數字nums可能是多位數,提取完后,將提取出來的字符串入棧nums次,繼續向后遍歷。
遍歷結束后,將棧轉成字符串返回即可
var decodeString = function(s) {
let res = []
for (const char of s) {
if(char == ']'){
let chars = [];let nums = []
while(res[res.length - 1] != '['){
chars.push(res.pop())
}
res.pop()
chars = chars.reverse().join('')
while(!isNaN(res[res.length - 1])) {
nums.push(res.pop());
}
nums = parseInt(nums.reverse().join(''))
for(let i = 0; i < nums; i++){
res.push(chars)
}
}
else res.push(char)
}
return res.join('')
};