1.刪除鏈表中的節點 *簡單
題目:請編寫一個函數,使其可以刪除某個鏈表中給定的(非末尾)節點,你將只被給定要求被刪除的節點。
題目沒有描述清楚。函數入參是鏈表中你要刪除的節點。
這題很簡單,把next的val值和next屬性都覆蓋當前的節點就行了
/**
* @param {ListNode} node
* @return {void} Do not return anything, modify node in-place instead.
*/
var deleteNode = function(node) {
node.val = node.next.val;
node.next = node.next.next;
};
2.有效的字母異位詞 *簡單
題目:
給定兩個字符串 s 和 t ,編寫一個函數來判斷 t 是否是 s 的字母異位詞。
這裏解釋一下,字母異位詞,是指兩個單詞包含的字符完全一樣,只是順序不一樣。
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isAnagram = function(s, t) {
const l1 = s.length;
const l2 = t.length;
if (l1 !== l2) return false;
for (let i = 0; i < l2; i++) {
s=s.replace(t[i], "");
}
return !s.length;
};
用sort取個巧
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isAnagram = function(s, t) {
const l1 = s.length;
const l2 = t.length;
if (l1 !== l2) return false;
const a1 = [...s].sort().join("");
const a2 = [...t].sort().join("");
return a1 === a2;
};
用map記錄的方式
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isAnagram = function(s, t) {
if (s.length !== t.length) {
return false;
}
var m = new Array(26).fill(0);
for (let i = 0; i < s.length; i++) {
m[s[i].charCodeAt() - 97]++;
}
for (let i = 0; i < t.length; i++) {
m[t[i].charCodeAt() - 97]--;
if (m[t[i].charCodeAt() - 97] < 0) {
return false;
}
}
return true;
};
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isAnagram = function(s, t) {
if (s.length !== t.length) {
return false;
}
const map = {};
for (let i = 0; i < s.length; i++) {
if (map[s[i]]) {
map[s[i]]++;
} else {
map[s[i]] = 1;
}
}
for (let i = 0; i < t.length; i++) {
if (!map[t[i]]) return false;
map[t[i]]--;
if (map[t[i]] < 0) return false;
}
return true;
};
3.整數轉羅馬數字 *中等
題目:
羅馬數字包含以下七種字符: I
, V
, X
, L
,C
,D
和 M
。
字符 數值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000
例如, 羅馬數字 2 寫做 II
,即爲兩個並列的 1。12 寫做 XII
,即爲 X
+ II
。 27 寫做 XXVII
, 即爲 XX
+ V
+ II
。
通常情況下,羅馬數字中小的數字在大的數字的右邊。但也存在特例,例如 4 不寫做 IIII
,而是 IV
。數字 1 在數字 5 的左邊,所表示的數等於大數 5 減小數 1 得到的數值 4 。同樣地,數字 9 表示爲 IX
。這個特殊的規則只適用於以下六種情況:
I
可以放在V
(5) 和X
(10) 的左邊,來表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左邊,來表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左邊,來表示 400 和 900。
給定一個整數,將其轉爲羅馬數字。輸入確保在 1 到 3999 的範圍內。
思路:這個和之前的一道題,羅馬數字轉整數,相當於一個互逆的過程
我們可以觀察發現,對於某一位上的數字,如果小於4,是不需要轉換的,如果是大於4,則分乘5還是乘10.
如此一來,我們從末尾往前遍歷,依次處理遇到的每一個數字,拼接即可。
/**
* @param {number} num
* @return {string}
*/
var intToRoman = function(num) {
const map = {
1: "I",
5: "V",
10: "X",
50: "L",
100: "C",
500: "D",
1000: "M",
};
num = `${num}`;
const l = num.length;
let res = "";
for (let i = 0; i < l; i++) {
const unit = Math.pow(10, i);
if (num[l - 1 - i] < 4) {
res = new Array(+num[l - 1 - i]).fill(map[unit]).join("") + res;
} else if (num[l - 1 - i] < 9) {
const basic = map[unit * 5];
const x = +num[l - 1 - i] - 5;
const temp = new Array(Math.abs(x)).fill(map[unit]).join("");
res =( x > 0 ? `${basic}${temp}` : `${temp}${basic}`) + res;
} else {
res = `${map[unit]}${map[10 * unit]}${res}`;
}
}
return res;
};
換一種思路,我們把每種單位和對應的羅馬字符都羅列,然後用給定的數字減去我們能找到,小於該數字的最大單位,最終直到0
/**
* @param {number} num
* @return {string}
*/
var intToRoman = function(num) {
const key = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
const value = [
"M",
"CM",
"D",
"CD",
"C",
"XC",
"L",
"XL",
"X",
"IX",
"V",
"IV",
"I",
];
let res = "";
for (let i = 0, l = key.length; i < l; i++) {
while (num >= key[i]) {
res += value[i];
num -= key[i];
}
}
return res;
};
4.三數之和 *中等
題目:
給你一個包含 n 個整數的數組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?請你找出所有滿足條件且不重複的三元組。
注意:答案中不可以包含重複的三元組。
思路:實話說,這題我自己沒想出來,是看的別人的解法的。
基礎思想還是依次遍歷,不同的是,爲了去除重複情況,我們需要先排序,排序之後,每次固定一數,然後剩下兩個數,用兩個指針表示,兩個指針一頭一尾,類似盛水容器,如果三數相加大於0,則尾部(即最大的值)往左移動,總和肯定減小(這裏要注意相同的數),如果小於0,則頭部往右移動,總和肯定增大(也要注意相同的數),直到兩個指針相遇。
又因爲三數相加等於0,所以最小值和最大值肯定是在0的左右兩側,所以用頭和尾的乘積是否小於0判斷是否要跳過這輪循環
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
nums.sort((a,b)=>a-b);
const l = nums.length;
const res = [];
if (nums[0] * nums[l - 1] > 0) return res;
for (let i = 0; i < l - 2;) {
if (nums[i] > 0) break;
let start = i + 1;
let end = l - 1;
do {
if (start >= end || nums[i] * nums[end] > 0) break;
let result = nums[i] + nums[start] + nums[end];
if (result === 0) {
res.push([nums[i], nums[start], nums[end]]);
}
if (result < 0) {
while (start < end && nums[start] === nums[++start]) {}
} else {
while (start < end && nums[end] === nums[--end]) {}
}
} while (start < end);
while (nums[i] === nums[++i]) {}
}
return res;
};
5.最接近的三數之和 *中等
題目:
給定一個包括 n 個整數的數組 nums 和 一個目標值 target。找出 nums 中的三個整數,使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。
和上一題很類似,每次比較和目標值的差的絕對值即可
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var threeSumClosest = function(nums, target) {
nums.sort((a, b) => a - b);
const l = nums.length;
let res=nums[0]+nums[1]+nums[2];
for (let i = 0; i < l - 2; ) {
let start = i + 1;
let end = l - 1;
do {
let result = nums[i] + nums[start] + nums[end];
if (Math.abs(result-target)<Math.abs(res-target)) {
res=result
}
if (start >= end ) break;
if (result < target) {
while (start < end && nums[start] === nums[++start]) {}
} else {
while (start < end && nums[end] === nums[--end]) {}
}
} while (start < end);
while (nums[i] === nums[++i]) {}
}
retu
6.電話號碼的字母組合 *中等
題目:
給定一個僅包含數字 2-9
的字符串,返回所有它能表示的字母組合。
給出數字到字母的映射如下(與電話按鍵相同)。注意 1 不對應任何字母。
思路:其實就是一個排列組合,每個數字對應幾種可能的字符,一次把每種可能拼接
/**
* @param {string} digits
* @return {string[]}
*/
const map = {
2: "abc",
3: "def",
4: "ghi",
5: "jkl",
6: "mno",
7: "pqrs",
8: "tuv",
9: "wxyz",
};
var letterCombinations = function (digits) {
if(!digits.length)return []
const res = [""];
return letterCombinationsAA(digits, res);
};
var letterCombinationsAA = function (digits, res) {
if (!digits.length) return res;
const l = res.length;
for (let i = 0; i < l; i++) {
const item = res.shift();
for (const s of map[digits[0]]) {
res.push(`${item}${s}`);
}
}
return letterCombinationsAA(digits.substring(1), res);
};
用迭代和遞歸是類似的
/**
* @param {string} digits
* @return {string[]}
*/
const map = {
2: "abc",
3: "def",
4: "ghi",
5: "jkl",
6: "mno",
7: "pqrs",
8: "tuv",
9: "wxyz",
};
var letterCombinations = function (digits) {
const l = digits.length;
if (!l) return [];
const res = [""];
for (let i = 0; i < l; i++) {
const jl = res.length;
for (let j = 0; j < jl; j++) {
const item = res.shift();
for (const s of map[digits[i]]) {
res.push(`${item}${s}`);
}
}
}
return res;
};