剑指offer(1-20)_leetcode

1. 剑指 Offer 03. 数组中重复的数字

class Solution {
    
    
public:
    int findRepeatNumber(vector<int>& nums) {
    
    
        //先排序  for循环
        sort(nums.begin(), nums.end());
        for (int i = 1; i < nums.size(); ++i) {
    
    
            if (nums[i - 1] == nums[i]) {
    
    
                return nums[i];
            }
        }
        return -1;
    }
};

class Solution {
    
    
public:
    int findRepeatNumber(vector<int>& nums) {
    
    
        //使用set
        set<int> s;
        for (int i = 0; i < nums.size(); ++i) {
    
    
            if (s.find(nums[i]) == s.end()) {
    
    
                s.insert(nums[i]);
            } else {
    
    
                return nums[i];
            }
        }
        return -1; 
    }
};

class Solution {
    
    
public:
    int findRepeatNumber(vector<int>& nums) {
    
    
        for (int i = 0; i < nums.size(); ++i) {
    
    
            while (nums[i] != i) {
    
    
                if (nums[i] == nums[nums[i]]) {
    
    
                    return nums[i];
                } else {
    
    
                    swap(nums[i], nums[nums[i]]);
                }
            }
        }
        return -1;
    }
};

2. 剑指 Offer 04. 二维数组中的查找

class Solution {
    
    
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
    
    
        if (matrix.empty() || matrix[0].empty()) return false;
        //从矩阵的右上角开始
        int i = 0, j = matrix[0].size() - 1;
        while(i <= matrix.size() - 1 && j >= 0) {
    
    
            if (target == matrix[i][j]) {
    
    
                return true;
            } else if (target > matrix[i][j]) {
    
    
                ++i;
            } else {
    
    
                --j;
            }
        }
        return false;
    }
};

3. 剑指 Offer 05. 替换空格

//从后往前遍历进行填充
class Solution {
    
    
public:
    string replaceSpace(string s) {
    
    
        if (s.empty()) return s;
        int count = 0;
        int len = s.size();
        for (auto i : s) {
    
    
            if (i == ' ') {
    
    
                count++;
            }
        }
        s.resize(len + count*2);
        for (int i = len - 1, j = s.size() - 1; i < j ; i--, j--) {
    
    
            if (s[i] != ' ') {
    
    
                s[j] = s[i];

            } else {
    
    
                s[j - 2] = '%';
                s[j - 1] = '2';
                s[j] = '0';
                j -= 2;
            }
        }
        return s;
    }
};

4. 剑指 Offer 06. 从尾到头打印链表

//使用栈
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    vector<int> reversePrint(ListNode* head) {
    
    
        stack<int> st;
        ListNode *p = head;
        while (p) {
    
    
            st.push(p->val);
            p = p->next;
        }
        vector<int> res;
        while (!st.empty()) {
    
    
            res.push_back(st.top());
            st.pop();
        }
        return res;
    }
};

//vector逆序构造
class Solution {
    
    
public:
    vector<int> reversePrint(ListNode* head) {
    
    
        vector<int> res;
        ListNode *p = head;
        while(p) {
    
    
            res.push_back(p->val);
            p = p->next;
        }
        return vector<int>(res.rbegin(), res.rend());
    }
};

//递归/**
 * Definition for singly-linked list.
 * struct ListNode {
    
    
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {
    
    }
 * };
 */
class Solution {
    
    
public:
    vector<int> reversePrint(ListNode* head) {
    
    
        vector<int> res;
        ListNode *p = head;
        rev(p, res);
        return res;
    }
    void rev(ListNode *p, vector<int>& res) {
    
    
        if (p) {
    
    
            if (p->next) {
    
    
                rev(p->next, res);
            }
            res.push_back(p->val);
        }
    }

};

5. 剑指 Offer 07. 重建二叉树

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    
    
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    
    
        int n = preorder.size();
        return dfs(preorder, inorder, 0, n - 1, 0, n - 1);
    }
    TreeNode* dfs(vector<int>& preorder, vector<int>& inorder, 
                int preleft, int preright, int inleft, int inright)
    {
    
    
        if (preleft > preright) return nullptr;
        TreeNode* root = new TreeNode(preorder[preleft]);
        int k =  inleft;
        for (; k <= inright; ++k) {
    
    
            if (inorder[k] == preorder[preleft]) {
    
    
                break;
            }
        }
        root->left = dfs(preorder, inorder, preleft + 1, preleft + k - inleft, inleft, k - 1);
        root->right = dfs(preorder, inorder, preleft + k - inleft + 1, preright, k + 1, inright);
        return root;
    }
     
};

6. 剑指 Offer 09 用两个栈实现队列

class CQueue {
    
    
public:
    stack<int> st1;
    stack<int> st2;
    CQueue() {
    
    

    }
    
    void appendTail(int value) {
    
    
        st1.push(value);
    }
    
    int deleteHead() {
    
    
        if (!st2.empty()) {
    
    
            int a = st2.top();
            st2.pop();
            return a;
        }
        if (st1.empty() ) {
    
    
            return -1;
        }
        while(!st1.empty()) {
    
    
            st2.push(st1.top());
            st1.pop();
        }
        int res = st2.top();
        st2.pop();
        return res;
       
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

7. 剑指 Offer 10- I 斐波那契数列

class Solution {
    
    
public:
    int fib(int n) {
    
    
        if (n == 0) return 0;
        if (n == 1) return 1;
        int a = 0, b = 1, res = 0;
        for (int i = 2; i <= n; ++i) {
    
    
            res = (a + b) % 1000000007;
            a = b;
            b= res;
        }
        return res % 1000000007;
    }
};

8. 剑指 Offer 10- II 青蛙跳台阶问题

class Solution {
    
    
public:
    int numWays(int n) {
    
    
        
        if (n <= 1) return 1;
        if (n == 2) return 2;
        int a = 1, b = 2, res = 1;
        for (int i = 3; i <= n; ++i) {
    
    
            res = (a + b) % 1000000007;
            a = b;
            b = res;
        }
        return res % 1000000007;
    }
};

9. 剑指 Offer 11 旋转数组的最小数字

//循环遍历 O(n)
class Solution {
    
    
public:
    int minArray(vector<int>& numbers) {
    
    
        int min  = numbers[0];
        for (int i = 1; i < numbers.size(); ++i) {
    
    
            if (numbers[i] < min) {
    
    
                min = numbers[i];
            }
        }
        return min;
    }
};
//二分O(logn)
class Solution {
    
    
public:
    int minArray(vector<int>& numbers) {
    
    
        int left = 0, right = numbers.size() - 1;
        while (left < right) {
    
    
            if (numbers[left] < numbers[right]) return numbers[left];
            int mid  = left + (right - left ) / 2;
            if (numbers[mid] > numbers[right]) left = mid + 1;
            else if (numbers[mid] < numbers[right]) right = mid;
            else --right;
        }
        return numbers[right];
    }
};

10. 剑指 Offer 12 矩阵中的路径

class Solution {
    
    
public:
    int rows, cols;
    bool dfs(vector<vector<char>>& board, string word, int i, int j, int k) {
    
    
        if (i >= rows || i < 0 || j >= cols || j < 0 || board[i][j] != word[k]) return false;
        if (k == word.size() - 1) return true;
        board[i][j] = '\0';
        bool res = dfs(board, word, i + 1, j , k + 1) || dfs(board, word, i - 1, j, k + 1) ||
                    dfs(board, word, i, j + 1, k + 1) || dfs(board, word, i, j - 1, k + 1);
        board[i][j] = word[k];
        return res;
    }
    bool exist(vector<vector<char>>& board, string word) {
    
    
        rows = board.size();
        cols = board[0].size();
        for (int i = 0; i < rows; i++) {
    
    
            for (int j = 0; j < cols; j++) {
    
    
                if (dfs(board, word, i, j, 0)) return true;
            }
        }
        return false;
    }
    
};

11. 剑指 Offer 13 机器人的运动范围

//深度优先遍历dfs
class Solution {
    
    
public:
    int movingCount(int m, int n, int k) {
    
    
        if (m <= 0 || n <= 0 || k < 0) {
    
    
            return 0;
        }

        vector<vector<bool>> visited(m, vector<bool>(n, 0));
        int count = dfs(0, 0, visited, m, n, k);
        return count;
    }
private:
    int dfs(int i, int j, vector<vector<bool>>& visited, int m, int n, int k) {
    
    
        int cnt = 0;
        if (check(i, j, visited, m, n, k)) {
    
    
            visited[i][j] = true;
            cnt = 1 + dfs(i - 1, j, visited, m, n, k) + dfs(i + 1, j, visited, m, n, k)
                    + dfs(i, j - 1, visited, m, n, k) + dfs(i, j + 1, visited, m, n, k);
        }
        return cnt;
    }
    bool check(int i, int j, vector<vector<bool>>& visited, int m, int n, int k) {
    
    
        int zongsum = getsum(i) + getsum(j);
        if (i >= 0 && i < m && j >= 0 && j < n && zongsum <= k && !visited[i][j])
            return true;
        return false;
    }
    int getsum(int num) {
    
    
        int sum = 0;
        while (num != 0) {
    
    
            sum += num % 10;
            num = num / 10;
        }
        return sum;
    }
};

//广度优先遍历bfs

12. 剑指 Offer 14- I 剪绳子

class Solution {
    
    
public:
    int cuttingRope(int n) {
    
    
        //动态规划
        //dp[i] 为最大乘积
        vector<int> dp(n + 1);
        dp[2] = 1;

        //从前往后遍历
        for (int i = 3; i <= n; i++) {
    
    
            for (int j = 1; j <  i - 1; j++) {
    
    
                dp[i] = max(dp[i], max((i - j) * j, dp[i - j]* j));
            }
        }
        return dp[n];
    }
};

13. 剑指 Offer 14- II 剪绳子 II

class Solution {
    
    
public:
    int cuttingRope(int n) {
    
    
        if (n <= 3) return n - 1;
        if (n == 4) return 4;
        long  res = 1;
        while (n > 4) {
    
    
            res *= 3;
            res %= 1000000007;
            n -= 3;
        }
        return res * n % 1000000007;
    }
};

14. 剑指 Offer 15 二进制中1的个数

class Solution {
    
    
public:
    int hammingWeight(uint32_t n) {
    
    
        int count = 0;
        while (n) {
    
    
            n = n &(n - 1);
            count++;
        }
        return count;
    }
};

class Solution {
    
    
public:
    int hammingWeight(uint32_t n) {
    
    
        int count  = 0;
        unsigned int flag = 1;
        while (flag) {
    
    
            if (n & flag) {
    
    
                count++;
            }
            flag = flag  << 1;
        }
        return count;
    }
};

15. 剑指 Offer 16 数值的整数次方

class Solution {
    
    
public:
    double myPow(double x, int n) {
    
    
        long long b = n;
        double res = 1.0;
        
        while (b) {
    
    
            if (b < 0) {
    
    
                x = 1 / x;
                b = -b;
            }
            if (b & 1 == 1) {
    
    
                res = res * x;
            }
            x = x * x;
            b >>= 1; 
        }
        return res;
    }
};

16. 剑指 Offer 17 打印从1到最大的n位数

class Solution {
    
    
public:
    vector<int> nums;
    string s;
    vector<int> printNumbers(int n) {
    
    
        s.resize(n, '0');
        dfs(n, 0);
        return nums;
    }

    void dfs(int end, int index) {
    
    
        if (index == end) {
    
    
            save();
            return;
        }
        for (int i = 0; i <= 9; i++) {
    
    
            s[index] = i + '0';
            dfs(end, index + 1);
        }
    }
    void save() {
    
    
        int ptr = 0;
        while (ptr < s.size() && s[ptr] == '0') ptr++;
        if (ptr  != s.size()) {
    
    
            nums.emplace_back(stoi(s.substr(ptr)));
        }
    }
};

17. 剑指 Offer 18 删除链表的节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* deleteNode(ListNode* head, int val) {
    
    
        if (val == head->val) return head->next;
        ListNode* res = head;
        while (head->next->val != val) {
    
    
            head = head->next;
        }
        head->next = head->next->next;
        return res;
    }
};

18. 剑指 Offer 19 正则表达式匹配

class Solution {
    
    
public:
    bool isMatch(string s, string p) {
    
    
        int n = s.size(), m = p.size();
        int dp[n + 5][m + 5];
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1;
        for (int i = 0; i <= n; i++) {
    
    
            for (int j = 1; j <= m; j++) {
    
    
                if (p[j - 1] != '*') {
    
    
                    if (i >= 1 && (s[i - 1] == p[j - 1] || p[j - 1] == '.')) {
    
    
                        dp[i][j] = dp[i - 1][j - 1];
                    }
                } else {
    
    
                    if (j >= 2) dp[i][j] = dp[i][j - 2];
                    if (i >= 1 && j >= 2 && (s[i - 1] == p[j - 2] || p[j - 2] == '.')) {
    
    
                        dp[i][j] |= dp[i - 1][j];
                    }
                }
            }
        }
        return dp[n][m];
    }
};

19. 剑指 Offer 20 表示数值的字符串

class Solution {
    
    
private:
    bool scanInteger(const string s, int& index) {
    
    
        if (s[index] == '+' || s[index] == '-')
            ++index;
        return scanUnsignedInteger(s, index);
    }
    bool scanUnsignedInteger(const string s, int& index) {
    
    
        int befor = index;
        while (index != s.size() && s[index] >= '0' && s[index] <= '9')
            index++;
        return index > befor;
    }
public:
    bool isNumber(string s) {
    
    
        if (s.size() == 0)
            return false;
        int index = 0;

        while (s[index] == ' ')
            ++index;
        bool numeric = scanInteger(s, index);

        if (s[index] == '.') {
    
    
            ++index;
            numeric = scanUnsignedInteger(s, index) || numeric;
        }
        if (s[index] == 'e' || s[index] == 'E') {
    
    
            ++index;
            numeric = numeric && scanInteger(s, index);
        }
        while (s[index] == ' ')
            ++index;
        cout << s.size() << " " << index;
        return numeric && index == s.size();
    }
};

20. 剑指 Offer 21 调整数组顺序使奇数位于偶数前面

class Solution {
    
    
public:
    vector<int> exchange(vector<int>& nums) {
    
    
        int left = 0;
        int right = nums.size() - 1;
        while (left < right) {
    
    
            while (left < right && nums[left] % 2 != 0) {
    
    
                left++;
            }
            while (left <right && nums[right] % 2 == 0) {
    
    
                right--;
            }
            swap(nums[left], nums[right]);
        }
        return nums;
    }
};



class Solution {
    
    
public:
    vector<int> exchange(vector<int>& nums) {
    
    
        if (nums.empty()) return nums;
        vector<int> res;
        for (auto num : nums) {
    
    
            if (num % 2 != 0) {
    
    
                res.push_back(num);
            }
        }
        for (auto num : nums) {
    
    
            if (num % 2 == 0) {
    
    
                res.push_back(num);
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_44847326/article/details/124559594