LeetCode高频面试题记录(三)

字符串相加 简单
这道题简单,思路也简单,但要写出简洁的代码还是不容易,记住下面模板

class Solution {
public:
    string addStrings(string num1, string num2) {
        if (num1.empty()) return num2;
        if (num2.empty()) return num1;
        int ln1 = num1.length() - 1;
        int ln2 = num2.length() - 1;
        int carry = 0;
        //定义一个空字符串,一边后面插入数字字符
        string c = "";
        while(carry == 1 || ln1 >= 0 || ln2 >= 0){
            //一定要把num1和num2分开考虑,防止出现因两数的位数不同而出现错误
            int x = ln1 < 0 ? 0 : num1[ln1--] - '0';
            int y = ln2 < 0 ? 0 : num2[ln2--] - '0'; 
            c.insert(c.begin(),(x+y+carry) % 10 +'0');
            //carry表示进位
            carry = (x+y+carry)/10;
        }
        return c;
    }
};

两数相加 中等
我们用同样的模板来做链表,确实很优秀的一个模板

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    	if (l1 == NULL) return l2;
    	if (l2 == NULL) return l1;
        ListNode* res = new ListNode(-1); ListNode* root = res;
        int carry = 0;
        while (carry == 1 || l1 != NULL || l2 != NULL){
            int x = l1==NULL ? 0 : l1->val;
            int y = l2==NULL ? 0 : l2->val;
            ListNode* node = new ListNode((x+y+carry) % 10);
            res->next = node; res = res->next;
            carry = (x+y+carry) / 10;
            if (l1 != NULL) l1 = l1->next; 
            if (l2 != NULL) l2 = l2->next; 
        }
        return root->next;
    }
};

二叉树的完全性检验 中等

class Solution {
public:
    bool isCompleteTree(TreeNode* root) {
        if (root == NULL) return true;
        queue<TreeNode*> q; q.push(root);
        bool hit_final_parent = false;
        while (!q.empty()) {
            auto node = q.front();
            q.pop();
            if (node->left != NULL) {
                if (hit_final_parent) return false;
                q.push(node->left);
            } 
            else 
                hit_final_parent = true;
            if (node->right != NULL) {
                if (hit_final_parent) return false;
                q.push(node->right);
            } 
            else
                hit_final_parent = true;
        }
        return true;
    }
};

前 K 个高频元素 中等

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        if (nums.empty()) return {};
        unordered_map<int, int> map;
        for (int num:nums) map[num]++;
        using Pair = pair<int, int>;
        auto mycmp = [](const Pair a, const Pair b){return a.second < b.second;};
        priority_queue<Pair, vector<Pair>, decltype(mycmp)> que(mycmp);
        for (auto i=map.begin(); i!=map.end(); i++)
            que.push(pair<int, int>(i->first, i->second));
        vector<int> res;
        while (k-- && !que.empty()){
            res.push_back(que.top().first);
            que.pop();
        }
        return res;
    }
};

手动构建堆,应该构建最小堆,可以自己思考思考

class Solution {
    using Pair = pair<int, int>;
    void heap(vector<Pair>& nums, int p){
        for (int parent=p; parent*2+1<nums.size();){
            int child = parent*2+1;
            if (child+1<nums.size() && nums[child].second > nums[child+1].second)
                child++;
            if (nums[parent].second < nums[child].second)
                break;
            swap(nums[parent], nums[child]);
            parent = child;
        }
    }
    void createHeap(vector<Pair>& nums){
        for (int i=nums.size()/2; i>=0; i--)
            heap(nums, i);
    }
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        if (nums.empty()) return {};
        unordered_map<int, int> map;
        for (int num:nums) map[num]++;
        vector<Pair> vec;
        for (auto i=map.begin(); i!=map.end(); i++)
            vec.push_back(pair<int, int>(i->first, i->second));
        vector<Pair> temp(vec.begin(), vec.begin()+k);
        createHeap(temp);
        for (int i=k; i<vec.size(); i++){
            if (temp[0].second < vec[i].second){//这里应该是构建最小堆
                temp[0].first = vec[i].first;
                temp[0].second = vec[i].second;
                heap(temp, 0);
            }
        }
        vector<int> res;
        while (!temp.empty()){
            res.push_back(temp[0].first);
            temp.erase(temp.begin());
            heap(temp, 0);
        }
        return res;
    }
};

对称二叉树 简单

class Solution {
    bool symmetric(TreeNode* l, TreeNode* r){
        if (l == NULL && r == NULL) return true;
        if (l == NULL || r == NULL) return false;
        if (l->val != r->val) return false;
        return symmetric(l->left, r->right) && symmetric(l->right, r->left);
    }
public:
    bool isSymmetric(TreeNode* root) {
        if (root == NULL) return true;
        return symmetric(root->left, root->right);
    }
};

相同的树 简单
树的模板,也是非常经典的模板

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if (p == NULL && q == NULL) return true;
        if (p == NULL || q == NULL) return false;
        if (p->val != q->val) return false;
        return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }
};

x的平方根 简单
二分法,细节真的是魔鬼
https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-suan-fa-xi-jie-xiang-jie-by-labula/
通过这个网址学习学习二分法

class Solution {
public:
    int mySqrt(int x) {
        int l = 0, r = x, ans = -1;
        while (l <= r) {
            int mid =(r + l) / 2;
            if ((long long)mid * mid <= x) {
                ans = mid;
                l = mid + 1;
            }
            else {
                r = mid - 1;
            }
        }
        return ans;
    }
};

旋转数组的最小数字 简单

class Solution {
public:
    int minArray(vector<int>& numbers) {
        if (numbers.empty()) return -1;
        int left=0, right=numbers.size()-1;//[3,4,5,1,2,2,2,2,2]
        while (left < right){
            int mid = (left + right) / 2;
            if (numbers[mid] > numbers[right])
                left = mid + 1;
            else if (numbers[mid] < numbers[right])
                right = mid;
            else if (numbers[mid] == numbers[right])
                right--;
        }
        return numbers[left];
    }
};

重排链表 中等
链表的题理清思路,在草稿纸上写写就会很清楚了

class Solution {
public:
    void reorderList(ListNode* head) {
        if (head == nullptr || head->next == nullptr) return;
        ListNode* root = head; ListNode* fast = head;
        while (fast != nullptr && fast->next != nullptr){
            fast = fast->next->next;
            head = head->next;
        }
        ListNode* temp = head->next;//从中间拆分成两个链表
        if (temp == nullptr) {head = root; return;}
        head->next = nullptr;
        stack<ListNode*> stk;//用栈来做
        while (temp != nullptr){
            stk.push(temp);
            temp = temp->next;
        }
        head = root; ListNode* cur = root; int i=1;
        while (!stk.empty()){//开始重排
            if (i % 2 == 1) {
                root = root->next;
                cur->next = stk.top();
                stk.pop();
                cur = cur->next;
                
            }
            else{
                cur->next = root;
                cur = cur->next;
            }
            i++;
        }
        cur->next = root;
    }
};

字符串转换整数 (atoi) 中等
思路理清楚就不难

class Solution {
public:
    int myAtoi(string str) {//思路理清楚,一步一步来
        if (str.empty()) return 0;
        while (*str.begin() == ' ') str = str.substr(1);//先去除空格
        int flag = 1;
        if (*str.begin() == '-') {flag = -1; str = str.substr(1);}//判断符号
        else if (*str.begin() == '+') str = str.substr(1);
        if (!isdigit(*str.begin())) return 0;//判断是否数字
        long long res = 0;
        for (int i=0; i<str.length(); i++){
            if (!isdigit(str[i])) break;//判断是否数字
            res += str[i]-'0';
            if (res >= INT_MAX && flag == 1) return INT_MAX;//判断边界
            if (res-1 >= INT_MAX && flag == -1) return INT_MIN;
            res *= 10;
        }
        return res*flag/10;
    }
};

旋转链表 中等

class Solution {
    ListNode* rotate(ListNode* head){
        if (head == NULL || head->next == NULL) return head;
        ListNode* root = head;
        while (root->next->next != NULL){
            root = root->next;
        }
        root->next->next = head;
        head = root->next;
        root->next = NULL;
        return head;
    }
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if (head == NULL || head->next == NULL) return head;
        ListNode* root = head; int n=0;
        while (root != NULL) {n++; root=root->next;}
        for (int i=0; i<k%n; i++){//这里要取模
            head = rotate(head);
        }
        return head;
    }
};

剑指 Offer 35. 复杂链表的复制

class Solution {
public:
    Node* copyRandomList(Node* head) {
        if (head == NULL) return head;
        unordered_map<Node*, Node*> map;
        Node* root = head;
        while (head != NULL){
            map[head] = new Node(head->val);
            head = head->next;
        }
        head = root;
        while (head != NULL){
            map[head]->next = map[head->next];
            map[head]->random = map[head->random];
            head = head->next;
        }
        return map[root];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

华为云计算搬砖工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值