[Preguntas candentes de leetcode 100] Registro de preguntas (5-8)
5. La subcadena palíndromo más larga.
Dada una cadena s
, encuéntrela s
en 最长的回文子串
.
Respuestas a preguntas
La idea es la programación dinámica.
Definición de estado: dp[i][j]
Indica si la cadena de i
a j
es una cadena palíndromo
Transferencia de estado:
s[i] == s[j]
dividida en dos tipos, uno con una longitud menor o igual a 3 dp[i][j]==True
, en otros casos dp[i][j] = dp[i+1][j-1]
;
s[i] != s[j]
entonces dp[i][j] = False
;
respuesta de Python
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
# 初始化dp数组
dp = [[False]*(n) for _ in range(n)]
# 边界条件 单个字符是属于回文字符串的
for i in range(n): dp[i][i] = True
# 定义一下最长长度和初始位置
maxlen, idx = 1, 0
# 按照长度来遍历
for lens in range(2, n + 1):
for st in range(0, n - lens + 1):
end = st + lens - 1
if s[st] == s[end]: # 字符相等的时候,看长度, 分两种情况
if lens <= 3:
dp[st][end] = True
else:
dp[st][end] = dp[st+1][end-1]
else: # 字符不相等的时候,必然不是
dp[st][end] = False
# 更新一下最优状态
if dp[st][end] and lens > maxlen:
maxlen = lens
idx = st
return s[idx:idx+maxlen]
respuesta cpp
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
if (n < 2) {
return s;
}
int maxLen = 1;
int begin = 0;
vector<vector<bool>> dp(n, vector<bool>(n));
for (int i = 0; i < n; i ++) dp[i][i] = true;
for (int l = 2; l <= n; l ++)
{
for (int i = 0; i < n; i ++)
{
int j = i + l - 1;
if (j >= n) break;
if (s[i] == s[j])
{
if (l <= 3) dp[i][j] = true;
else dp[i][j] = dp[i+1][j-1];
}
else
{
dp[i][j] = false;
}
// 更新最优状态
if (dp[i][j] && l > maxLen)
{
maxLen = l;
begin = i;
}
}
}
return s.substr(begin, maxLen);
}
};
2. Suma dos números
Se le proporcionan dos listas enlazadas no vacías, que representan dos números enteros no negativos. Cada uno de sus dígitos se almacena en orden inverso y cada nodo solo puede almacenar un dígito.
Agregue dos números y devuelva una lista vinculada que represente la suma en la misma forma.
Puedes asumir que, excepto el número 0, ninguno de los números comenzará con 0.
Respuestas a preguntas
Simplemente simule directamente. Cuando use C ++, preste atención a si el objeto devuelto es un puntero o un objeto. Si es un puntero, úselo en lugar de un ->
objeto .
.
respuesta de Python
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
adds = 0 # 进位
head = curr = ListNode(0)
while l1 or l2 or adds:
val = 0
if l1:
val += l1.val
l1 = l1.next
if l2:
val += l2.val
l2 = l2.next
val, adds = (val + adds) % 10, (val + adds) // 10
node = ListNode(val)
curr.next = node
curr = curr.next
return head.next
respuesta cpp
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int adds = 0;
ListNode *head = nullptr;
ListNode *curr = nullptr;
head = curr = new ListNode(0);
while (l1 || l2 || adds)
{
int val = 0;
if(l1)
{
val += l1->val;
l1 = l1->next;
}
if(l2)
{
val += l2->val;
l2 = l2->next;
}
curr->next = new ListNode((val + adds) % 10);
adds = (val + adds) / 10;
curr = curr->next;
}
return head->next;
}
};
3. La subcadena más larga sin caracteres repetidos.
Dada una cadena s
, busque 不含有重复字符
el .最长子串
长度
Respuestas a preguntas
Puntero doble plus set
Deslizando la ventana de izquierda a derecha. Si encuentra set
un elemento que no está allí, el puntero derecho continúa moviéndose hacia la derecha hasta que ya no se satisface. Actualice la distancia más larga, luego agregue y s[r]
elimine s[l]
. También lo registré aquí final_l
, que es equivalente a si se requiere la distancia más larga, si la subsecuencia no se repite, envíela directamente.s[final_l:final_l+res]
respuesta de Python
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
l, r = 0, 0
final_l = 0
res = 0
dic = set()
while r < len(s):
while r < len(s) and s[r] not in dic:
dic.add(s[r])
r += 1
if r - l > res:
res = r - l
final_l = l
dic.remove(s[l])
l += 1
return res
respuesta cpp
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int l = 0, r = 0, res = 0, final_l;
unordered_set<char> dic;
while (r < s.size())
{
while (r < s.size() and dic.find(s[r]) == dic.end())
{
dic.insert(s[r]);
r ++;
}
if (r - l > res)
{
res = r - l;
final_l = l;
}
dic.erase(s[l]);
l ++;
}
return res;
}
};
4. Encuentra la mediana de dos matrices positivas.
Dados dos arreglos ordenados positivamente (de pequeño a grande) y de tamaños m
y respectivamente . Busque y devuelva estas dos matrices de orden positivo .n
nums1
nums2
中位数
La complejidad temporal del algoritmo debe ser O(log (m+n))
.
Respuestas a preguntas
二分查找
Específicamente, es encontrar una división de dos matrices y transformarla en un problema de encontrar los primeros k números pequeños. Al dividir, es principalmente para hacer que los valores de los elementos a la izquierda y derecha de la línea divisoria satisfagan la relación de orden de intersección y luego analice algunas condiciones de contorno. Para más detalles, consulte el análisis del sitio web oficial.
respuesta de Python
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
if len(nums1) > len(nums2):
return self.findMedianSortedArrays(nums2, nums1)
infinty = 2**40
m, n = len(nums1), len(nums2)
left, right = 0, m
# median1:前一部分的最大值
# median2:后一部分的最小值
median1, median2 = 0, 0
while left <= right:
# 前一部分包含 nums1[0 .. i-1] 和 nums2[0 .. j-1]
# // 后一部分包含 nums1[i .. m-1] 和 nums2[j .. n-1]
i = (left + right) // 2
j = (m + n + 1) // 2 - i
# nums_im1, nums_i, nums_jm1, nums_j 分别表示 nums1[i-1], nums1[i], nums2[j-1], nums2[j]
nums_im1 = (-infinty if i == 0 else nums1[i - 1])
nums_i = (infinty if i == m else nums1[i])
nums_jm1 = (-infinty if j == 0 else nums2[j - 1])
nums_j = (infinty if j == n else nums2[j])
if nums_im1 <= nums_j:
median1, median2 = max(nums_im1, nums_jm1), min(nums_i, nums_j)
left = i + 1
else:
right = i - 1
return (median1 + median2) / 2 if (m + n) % 2 == 0 else median1
respuesta cpp
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
if (nums1.size() > nums2.size()) {
return findMedianSortedArrays(nums2, nums1);
}
int m = nums1.size();
int n = nums2.size();
int left = 0, right = m;
// median1:前一部分的最大值
// median2:后一部分的最小值
int median1 = 0, median2 = 0;
while (left <= right) {
// 前一部分包含 nums1[0 .. i-1] 和 nums2[0 .. j-1]
// 后一部分包含 nums1[i .. m-1] 和 nums2[j .. n-1]
int i = (left + right) / 2;
int j = (m + n + 1) / 2 - i;
// nums_im1, nums_i, nums_jm1, nums_j 分别表示 nums1[i-1], nums1[i], nums2[j-1], nums2[j]
int nums_im1 = (i == 0 ? INT_MIN : nums1[i - 1]);
int nums_i = (i == m ? INT_MAX : nums1[i]);
int nums_jm1 = (j == 0 ? INT_MIN : nums2[j - 1]);
int nums_j = (j == n ? INT_MAX : nums2[j]);
if (nums_im1 <= nums_j) {
median1 = max(nums_im1, nums_jm1);
median2 = min(nums_i, nums_j);
left = i + 1;
} else {
right = i - 1;
}
}
return (m + n) % 2 == 0 ? (median1 + median2) / 2.0 : median1;
}
};