知名互聯(lián)網(wǎng)公司校招中常見的算法題(1-5)
題目一:最長回文子串
回文串是指正著讀和反著讀都一樣的字符串。給定一個(gè)字符串,求出它的最長回文子串。
解決思路:
我們可以用動(dòng)態(tài)規(guī)劃來解決這個(gè)問題。我們先定義狀態(tài):dpi 表示從i到j(luò)是否為回文串。則有以下狀態(tài)轉(zhuǎn)移方程:
dp[i][j] = true (i == j)
dp[i][j] = (s[i] == s[j]) (j = i + 1)
dp[i][j] = (s[i] == s[j]) && dp[i + 1][j - 1] (j > i + 1)
在這個(gè)狀態(tài)轉(zhuǎn)移方程中,如果 s[i] == s[j],那么 dpi 的值就取決于 dpi + 1 是否為 true。同時(shí),如果 i 和 j 之間只有一個(gè)字符,那么它們必定是回文串。
最后,我們可以遍歷 dp 數(shù)組,找出其中值為 true 的最長子串。
代碼實(shí)現(xiàn):
public String longestPalindrome(String s) {
? int n = s.length();
? boolean[][] dp = new boolean[n][n];
? String res = "";
? for (int i = n - 1; i >= 0; i--) {
? ? ? for (int j = i; j < n; j++) {
? ? ? ? ? dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i < 2 || dp[i + 1][j - 1]);
? ? ? ? ? if (dp[i][j] && j - i + 1 > res.length()) {
? ? ? ? ? ? ? res = s.substring(i, j + 1);
? ? ? ? ? }
? ? ? }
? }
? return res;
}
題目二:兩數(shù)之和
給定一個(gè)整數(shù)數(shù)組 nums 和一個(gè)目標(biāo)值 target,請?jiān)谠摂?shù)組中找出和為目標(biāo)值的兩個(gè)整數(shù),并返回它們的下標(biāo)。
解決思路:
我們可以用哈希表來解決這個(gè)問題。遍歷一遍數(shù)組,用哈希表來記錄每個(gè)數(shù)字出現(xiàn)的位置。對于每個(gè)數(shù)字 nums[i],我們可以檢查哈希表中是否存在 target - nums[i],如果存在,那么就找到了這兩個(gè)數(shù)。
代碼實(shí)現(xiàn):
public int[] twoSum(int[] nums, int target) {
? Map<Integer, Integer> map = new HashMap<>();
? for (int i = 0; i < nums.length; i++) {
? ? ? int complement = target - nums[i];
? ? ? if (map.containsKey(complement)) {
? ? ? }
? ? ? map.put(nums[i], i);
? }
? return null;
}
題目三:反轉(zhuǎn)鏈表
給定一個(gè)鏈表,反轉(zhuǎn)鏈表的每個(gè)節(jié)點(diǎn)。
解決思路:
我們可以用迭代的方法來解決這個(gè)問題。遍歷一遍鏈表,用一個(gè) prev 指針記錄前一個(gè)節(jié)點(diǎn),用一個(gè) cur 指針記錄當(dāng)前節(jié)點(diǎn),用一個(gè) next 指針記錄下一個(gè)節(jié)點(diǎn)。然后每次將當(dāng)前節(jié)點(diǎn)的 next 指向前指向 prev,然后將 prev 指向當(dāng)前節(jié)點(diǎn),將當(dāng)前節(jié)點(diǎn)指向 next,直到遍歷完整個(gè)鏈表。
代碼實(shí)現(xiàn):
public ListNode reverseList(ListNode head) {
? ListNode prev = null;
? ListNode cur = head;
? while (cur != null) {
? ? ? ListNode next = cur.next;
? ? ? cur.next = prev;
? ? ? prev = cur;
? ? ? cur = next;
? }
? return prev;
}
題目四:二叉樹的最大深度
給定一個(gè)二叉樹,找出其最大深度。
解決思路:
我們可以用遞歸的方法來解決這個(gè)問題。二叉樹的最大深度等于左子樹的最大深度和右子樹的最大深度中的較大值加1。我們可以用遞歸函數(shù) maxDepth(root) 來計(jì)算以 root 為根節(jié)點(diǎn)的樹的最大深度。
代碼實(shí)現(xiàn):
public?int?maxDepth(TreeNode?root) {
? ?if?(root?==?null) {
? ? ? ?return?0;
? }
? ?int?leftDepth?=?maxDepth(root.left);
? ?int?rightDepth?=?maxDepth(root.right);
? ?return?Math.max(leftDepth,?rightDepth)?+?1;
}
題目五:字符串轉(zhuǎn)整數(shù)
將一個(gè)字符串轉(zhuǎn)換成整數(shù),如果不能轉(zhuǎn)換則返回 0。
解決思路:
我們可以用模擬的方法來解決這個(gè)問題。先去掉字符串前面的空格,然后判斷第一個(gè)字符是否是正號(hào)或負(fù)號(hào)。然后從第一個(gè)非空字符開始遍歷字符串,直到遇到非數(shù)字字符為止。在遍歷的過程中,我們可以用一個(gè)變量來記錄轉(zhuǎn)換后的結(jié)果。如果結(jié)果超過了整數(shù)的范圍,則返回最大值或最小值。
代碼實(shí)現(xiàn):
public int myAtoi(String s) {
? int n = s.length();
? int i = 0;
? int sign = 1;
? int res = 0;
?
? while (i < n && s.charAt(i) == ' ') {
? ? ? i++;
? }
? if (i < n && (s.charAt(i) == '+' || s.charAt(i) == '-')) {
? ? ? sign = s.charAt(i) == '+' ? 1 : -1;
? ? ? i++;
? }
? while (i < n && Character.isDigit(s.charAt(i))) {
? ? ? int digit = s.charAt(i) - '0';
? ? ? if (res > (Integer.MAX_VALUE - digit) / 10) {
? ? ? ? ? return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
? ? ? }
? ? ? res = res * 10 + digit;
? ? ? i++;
? }
? return sign * res;
}
以上是關(guān)于常見算法題的解決思路、代碼實(shí)現(xiàn)以及實(shí)際案例的詳細(xì)講解。對于互聯(lián)網(wǎng)公司的校招來說,掌握這些算法題可以幫助我們更好地應(yīng)對面試。當(dāng)然,還需要多多練習(xí),才能真正掌握這些算法。