minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Existem construtores em estruturas C++.
#include pode aparecer no meio de um arquivo de programa.
Os nomes formais dos parâmetros podem ser omitidos nas declarações de funções, mas não nas definições.
Uma estrutura de dados não vazia se atender às duas condições a seguir:
É chamada de estrutura linear e é chamada de tabela linear em estruturas de dados.
O nó da lista duplamente vinculada possui dois campos de ponteiro e é uma estrutura linear.
Os ponteiros de todos os nós na lista vinculada circular não são nulos e também são estruturas lineares.
Os métodos para construir uma tabela hash incluem: método de endereço direto, método de divisão e método de resto.
Os métodos de resolução de conflitos incluem:
Dados dois inteiros à esquerda e à direita, representando o intervalo [esquerda, direita], retorne o resultado do AND bit a bit de todos os números neste intervalo.
Para uma série de bits, desde que haja um bit com valor zero, o resultado da operação AND bit a bit desta série é zero.
No exemplo acima, podemos descobrir queO resultado da execução de uma operação AND bit a bit em todos os números é o prefixo comum de todas as strings binárias correspondentes, com os bits restantes preenchidos com zeros.
Dado um array inteiro nums, cada elemento aparece três vezes, exceto um elemento que aparece apenas uma vez. Encontre e retorne o elemento que aparece apenas uma vez.
Projete um algoritmo com complexidade de tempo linear e use espaço constante para resolver o problema.
Determine cada bit binário por vez
Como os elementos da matriz estão no intervalo int, você pode calcular se cada bit binário da resposta é 0 ou 1 por vez.
Especificamente, considere o i-ésimo dígito binário da resposta (i é numerado a partir de 0), que pode ser 0 ou 1.
O i-ésimo dígito da resposta é o restante da soma dos i-ésimos dígitos binários de todos os elementos da matriz dividido por 3.
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ret = 0;
for(int i=0; i<32; i++){
int sum = 0;
for(int num : nums){
sum += ((num >> i) & 1);
}
ret += ((sum%3) << i);
}
return ret;
}
};
Potência rápida + recursão
A essência do algoritmo de potência rápida é o algoritmo de dividir e conquistar.
Começando em x, eleve ao quadrado diretamente o resultado anterior de cada vez. Calcule 5 vezes para obter x64.
class Solution {
public:
double quickMul(double x, long long N){
if(N == 0){
return 1.0;
}
double y = quickMul(x, N/2);
return N%2 == 0 ? y * y : y * y * x;
}
double myPow(double x, int n) {
long long N = n;
return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
}
};
Dado um número inteiro n, retorne n! O número de zeros à direita no resultado.
O número de zeros finais em n é para encontrar o número de fatores 10, e 10=2x5, então é convertido em encontrar o menor valor do número de fatores primos 2 e o número de fatores primos 5 em n!.
Como o número de fatores primos 5 não será maior que o número de fatores primos 2, apenas o número de fatores primos 5 é considerado.
O número de fatores primos 5 em n é igual à soma do número de fatores primos 5 de cada número.
class Solution {
public:
int trailingZeroes(int n) {
int res = 0;
for(int i=5; i<=n; i += 5){
for(int j=i; j%5 == 0; j/=5){
res++;
}
}
return res;
}
};
ponteiro de velocidade
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head == nullptr || head->next == nullptr){
return false;
}
ListNode* slow = head->next;
ListNode* fast = head->next->next;
while(fast != nullptr){
if(slow == fast){
return true;
}
if(fast->next == nullptr){
return false;
}
slow = slow->next;
fast = fast->next->next;
}
return false;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
if(list1 == nullptr){
return list2;
}
if(list2 == nullptr){
return list1;
}
ListNode* newHead;
if(list1->val <= list2->val){
newHead = list1;
list1 = list1->next;
}else{
newHead = list2;
list2 = list2->next;
}
ListNode* p = newHead;
while(list1 && list2){
if(list1->val <= list2->val){
p->next = list1;
p = p->next;
list1 = list1->next;
}else{
p->next = list2;
p = p->next;
list2 = list2->next;
}
}
while(list1){
p->next = list1;
p = p->next;
list1 = list1->next;
}
while(list2){
p->next = list2;
p = p->next;
list2 = list2->next;
}
return newHead;
}
};
Uma árvore é simétrica se suas subárvores esquerda e direita são imagens espelhadas uma da outra.
travessia em largura
A pesquisa começa no nó raiz, percorre todos os nós da mesma camada em cada rodada, calcula o número de nós na camada e a soma do número de nós na camada e, em seguida, calcula o valor médio da camada.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
vector<double> average;
queue<TreeNode *> que;
que.push(root);
while(!que.empty()){
double sum = 0;
int size = que.size();
for(int i=0; i<size; i++){
TreeNode* node = que.front();
que.pop();
sum += node->val;
TreeNode* left = node->left;
TreeNode* right = node->right;
if(left){
que.push(left);
}
if(right){
que.push(right);
}
}
average.push_back(sum / size);
}
return average;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode* > que;
if(!root){
return res;
}
que.push(root);
while(!que.empty()){
vector<int> temp;
int size = que.size();
for(int i=0; i<size; i++){
TreeNode* node = que.front();
que.pop();
temp.push_back(node->val);
TreeNode* left = node->left;
TreeNode* right = node->right;
if(left){
que.push(left);
}
if(right){
que.push(right);
}
}
res.push_back(temp);
}
return res;
}
};
Um array ordenado nums, exclui os elementos repetidos no lugar, de modo que os elementos que aparecem mais de duas vezes aparecem apenas duas vezes e retornam o novo comprimento do array após a exclusão.
A matriz de entrada deve ser modificada no local e feita usando espaço extra O(1).
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int left = 0;
int right = 0;
int n = nums.size();
int count = 0;
int sum = 0;
while (right < n) {
if (nums[left] == nums[right]) {
count++;
right++;
} else {
if (count > 1) {
nums[++left] = nums[left];
sum += 2;
} else {
sum += 1;
}
nums[++left] = nums[right++];
count = 1;
}
}
if (count > 1) {
nums[++left] = nums[left];
sum += 2;
} else {
sum += 1;
}
return sum;
}
};
Dado um array inteiro nums, gire os elementos no array k posições para a direita.
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k = k % n;
reverse(nums.begin(), nums.end());
reverse(nums.begin(), nums.begin()+k);
reverse(nums.begin()+k, nums.end());
}
};
class Solution {
public:
int maxProfit(vector<int>& prices) {
int result = 0;
int price = prices[0];
for(int i=1; i<prices.size(); i++){
if(prices[i] > price){
result = max(result, prices[i] - price);
}else{
price = prices[i];
}
}
return result;
}
};
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
vector<vector<int>> dp(n,vector<int>(2)); //dp[i][0]第i天没有股票
dp[0][0] = 0;
dp[0][1] = -prices[0];
for(int i=1; i<n; i++){
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]);
dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]);
}
return dp[n-1][0];
}
};
Dado um array inteiro não negativo nums, inicialmente localizado no primeiro índice do array, cada elemento do array representa o comprimento máximo que pode ser saltado.
Determine se ele pode pular para o último índice.
ambicioso
Para qualquer posição y na matriz, desde que haja uma posição x que possa ser alcançada por si só, e x + nums[x] ≥ y, então y também pode ser alcançado.
Para cada posição alcançável x, torna as posições consecutivas x+1, x+2, ..., x+nums[x] alcançáveis.
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
int rightmost = 0;
for(int i=0; i<n; i++){
if(i <= rightmost){
rightmost = max(rightmost, i+nums[i]);
if(rightmost >= n-1){
return true;
}
}
}
return false;
}
};
Dada uma string s, organize-a em forma de z de cima para baixo e da esquerda para a direita de acordo com o número fornecido de linhas numRows.
Simular usando matrizes 2D
Seja n o comprimento da string s, r = numRows Para r=1 (apenas uma linha) ou r >= n (apenas uma coluna), a resposta é igual a s e pode ser retornada diretamente.
Em outros casos, considere criar uma matriz bidimensional, depois preencher a string s em zigue-zague na matriz e, finalmente, digitalizar os caracteres não vazios na matriz linha por linha para formar a resposta.
De acordo com o significado da pergunta, quando preenchermos os caracteres na matriz, preencheremos r caracteres para baixo, depois r-2 caracteres para cima à direita e, finalmente, retornaremos à primeira linha, de modo que o período de transformação em forma de Z t = r + r - 2 = 2r - 2. Cada ciclo ocupará 1+r-2 = r-1 colunas na matriz.
Existem n/t períodos vezes o número de colunas, que é igual ao número de colunas da matriz.
Crie uma matriz com r linhas e c colunas, depois itere pelas strings e preencha-as em zigue-zague.
class Solution {
public:
string convert(string s, int numRows) {
int n = s.length(), r = numRows;
if(r == 1 || r >= n){
return s;
}
//变换周期
int t = 2*r - 2;
int c = (n + t -1) / t * (r - 1);
//创建二维字符串
vector<string> mat(r, string(c, 0));
for(int i = 0, x = 0, y =0; i<n; i++){
mat[x][y] = s[i];
if(i % t < r - 1){
++x; //向下移动
}else{
--x;
++y; //向右上移动
}
}
string ans;
for(auto &row : mat){
for(char ch : row){
if(ch){
ans += ch;
}
}
}
return ans;
}
};
class Solution {
public:
vector<string> splitString(string s){
istringstream iss(s);
vector<string> res;
string word;
while(iss >> word){
res.push_back(word);
}
return res;
}
string reverseWords(string s) {
vector<string> words = splitString(s);
string res;
for(int i=words.size()-1; i>=0; i--){
res += words[i] + " ";
}
res.pop_back();
return res;
}
};