τα στοιχεία επικοινωνίας μου
Ταχυδρομείο[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Υπάρχουν κατασκευαστές σε δομές C++.
Το #include μπορεί να εμφανιστεί στη μέση ενός αρχείου προγράμματος.
Τα επίσημα ονόματα παραμέτρων μπορούν να παραληφθούν στις δηλώσεις συναρτήσεων, αλλά όχι στους ορισμούς.
Μια μη κενή δομή δεδομένων εάν πληροί τις ακόλουθες δύο προϋποθέσεις:
Ονομάζεται γραμμική δομή και ονομάζεται γραμμικός πίνακας στις δομές δεδομένων.
Ο διπλά συνδεδεμένος κόμβος λίστας έχει δύο πεδία δείκτη και είναι μια γραμμική δομή.
Οι δείκτες όλων των κόμβων στην κυκλική συνδεδεμένη λίστα δεν είναι μηδενικοί και είναι επίσης γραμμικές δομές.
Οι μέθοδοι για την κατασκευή ενός πίνακα κατακερματισμού περιλαμβάνουν: μέθοδο άμεσης διεύθυνσης, διαίρεση και μέθοδο υπολειπόμενου.
Οι μέθοδοι επίλυσης συγκρούσεων περιλαμβάνουν:
Δίνοντας δύο ακέραιους αριθμούς αριστερά και δεξιά, που αντιπροσωπεύουν το διάστημα [αριστερά, δεξιά], επιστρέψτε το αποτέλεσμα του bitwise AND όλων των αριθμών σε αυτό το διάστημα.
Για μια σειρά από bit, εφόσον υπάρχει ένα bit με μηδενική τιμή, το αποτέλεσμα της λειτουργίας bitwise AND αυτής της σειράς είναι μηδέν.
Στο παραπάνω παράδειγμα, μπορούμε να το βρούμεΤο αποτέλεσμα της εκτέλεσης μιας λειτουργίας bitwise AND σε όλους τους αριθμούς είναι το κοινό πρόθεμα όλων των αντίστοιχων δυαδικών συμβολοσειρών, με τα υπόλοιπα bit να συμπληρώνονται με μηδενικά.
Με δεδομένο έναν ακέραιο πίνακα, κάθε στοιχείο εμφανίζεται τρεις φορές εκτός από ένα στοιχείο που εμφανίζεται μόνο μία φορά.
Σχεδιάστε έναν αλγόριθμο με γραμμική χρονική πολυπλοκότητα και χρησιμοποιήστε σταθερό χώρο για να λύσετε το πρόβλημα.
Προσδιορίστε κάθε δυαδικό bit με τη σειρά
Δεδομένου ότι τα στοιχεία του πίνακα βρίσκονται στην περιοχή int, μπορείτε να υπολογίσετε εάν κάθε δυαδικό bit της απάντησης είναι 0 ή 1 με τη σειρά του.
Συγκεκριμένα, θεωρήστε το i-ο δυαδικό ψηφίο της απάντησης (το i αριθμείται ξεκινώντας από το 0), το οποίο μπορεί να είναι 0 ή 1.
Το i-ο ψηφίο της απάντησης είναι το υπόλοιπο του αθροίσματος των i-ου δυαδικών ψηφίων όλων των στοιχείων του πίνακα διαιρούμενο με το 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;
}
};
Γρήγορη ισχύς + αναδρομή
Η ουσία του αλγορίθμου γρήγορης ισχύος είναι ο αλγόριθμος διαίρει και βασίλευε.
Ξεκινώντας από το x, κάθε φορά στο τετράγωνο του προηγούμενου αποτελέσματος. Υπολογίστε 5 φορές για να πάρετε 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);
}
};
Δίνεται ένας ακέραιος αριθμός n, επιστρέφετε n Ο αριθμός των μηδενικών που ακολουθούν στο αποτέλεσμα.
Ο αριθμός των μηδενικών της ουράς σε n είναι να βρούμε τον αριθμό των παραγόντων 10, και 10=2x5, οπότε μετατρέπεται σε εύρεση της μικρότερης τιμής του αριθμού των πρώτων παραγόντων 2 και του αριθμού των πρώτων παραγόντων 5 στο n!.
Δεδομένου ότι ο αριθμός των πρώτων παραγόντων 5 δεν θα είναι μεγαλύτερος από τον αριθμό των πρώτων παραγόντων 2, λαμβάνεται υπόψη μόνο ο αριθμός των πρώτων παραγόντων 5.
Ο αριθμός των πρώτων παραγόντων 5 στο n είναι ίσος με το άθροισμα των πρώτων παραγόντων 5 κάθε αριθμού.
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;
}
};
δείκτη ταχύτητας
/**
* 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;
}
};
Ένα δέντρο είναι συμμετρικό αν το αριστερό και το δεξί του υποδέντρο είναι κατοπτρικά είδωλα το ένα του άλλου.
πλάτος-πρώτη διάβαση
Η αναζήτηση ξεκινά από τον ριζικό κόμβο, διασχίζει όλους τους κόμβους στο ίδιο επίπεδο σε κάθε γύρο, υπολογίζει τον αριθμό των κόμβων στο επίπεδο και το άθροισμα του αριθμού των κόμβων στο επίπεδο και στη συνέχεια υπολογίζει τη μέση τιμή του επιπέδου.
/**
* 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;
}
};
Ένας διατεταγμένος πίνακας αριθμεί, διαγράφει επαναλαμβανόμενα στοιχεία στη θέση του, έτσι ώστε τα στοιχεία που εμφανίζονται περισσότερες από δύο φορές να εμφανίζονται μόνο δύο φορές και επιστρέφει το νέο μήκος του πίνακα μετά τη διαγραφή.
Ο πίνακας εισόδου πρέπει να τροποποιηθεί επιτόπου και να γίνει χρησιμοποιώντας επιπλέον χώρο 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;
}
};
Δεδομένου ενός ακέραιου πίνακα αριθμών, περιστρέψτε τα στοιχεία στις θέσεις k του πίνακα προς τα δεξιά.
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];
}
};
Δεδομένου ενός μη αρνητικού ακέραιου πίνακα αριθμών, που αρχικά βρίσκεται στον πρώτο δείκτη του πίνακα, κάθε στοιχείο του πίνακα αντιπροσωπεύει το μέγιστο μήκος που μπορεί να μεταπηδήσει.
Προσδιορίστε εάν μπορεί να μεταβεί στον τελευταίο δείκτη.
άπληστος
Για οποιαδήποτε θέση y στον πίνακα, εφόσον υπάρχει μια θέση x που μπορεί να επιτευχθεί από μόνη της, και x + nums[x] ≥ y, τότε μπορεί να επιτευχθεί και το y.
Για κάθε προσβάσιμη θέση x, καθιστά προσβάσιμες τις διαδοχικές θέσεις x+1, x+2, ..., x+nums[x].
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;
}
};
Δίνεται μια συμβολοσειρά s, τακτοποιήστε την σε σχήμα z από πάνω προς τα κάτω και από αριστερά προς τα δεξιά σύμφωνα με τον δεδομένο αριθμό σειρών numRows.
Προσομοίωση χρησιμοποιώντας 2D πίνακες
Έστω n το μήκος της συμβολοσειράς s, r = numRows Για r=1 (μόνο μία γραμμή) ή r >= n (μόνο μία στήλη), η απάντηση είναι ίδια με το s και μπορεί να επιστραφεί απευθείας.
Σε άλλες περιπτώσεις, σκεφτείτε να δημιουργήσετε μια δισδιάστατη μήτρα, στη συνέχεια να συμπληρώσετε τη συμβολοσειρά s σε ένα μοτίβο ζιγκ-ζαγκ στη μήτρα και, τέλος, να σαρώσετε τους μη κενούς χαρακτήρες στη μήτρα γραμμή προς γραμμή για να σχηματίσετε την απάντηση.
Σύμφωνα με το νόημα της ερώτησης, όταν συμπληρώνουμε χαρακτήρες στη μήτρα, θα συμπληρώσουμε χαρακτήρες r προς τα κάτω, μετά r-2 χαρακτήρες προς τα πάνω προς τα δεξιά και τέλος θα επιστρέψουμε στην πρώτη σειρά, άρα η περίοδος μετασχηματισμού σε σχήμα Ζ t = r + r - 2 = 2r - 2. Κάθε κύκλος θα καταλαμβάνει 1+r-2 = r-1 στήλες στον πίνακα.
Υπάρχουν n/t περίοδοι επί του αριθμού των στηλών, ο οποίος είναι ίσος με τον αριθμό των στηλών του πίνακα.
Δημιουργήστε μια μήτρα με r σειρές και c στήλες, στη συνέχεια επαναλάβετε τις συμβολοσειρές και γεμίστε τις σε ζιγκ-ζαγκ μοτίβο.
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;
}
};