剑指 Offer 51-60

剑指 Offer 52. 两个链表的第一个公共节点

难度简单83收藏分享切换为英文关注反馈

输入两个链表,找出它们的第一个公共节点。

如下面的两个链表

在节点 c1 开始相交。

 

示例 1:

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        //让双指针浪漫相遇。
        //如果是NULL就转到头。
        ListNode* hA = headA; ListNode* hB = headB;
        while(hA != hB) {
            hA = hA == NULL ? headA : hA->next;
            hB = hB == NULL ? headB : hB->next;
        }
        return hA;
    }
};

剑指 Offer 53 - I. 在排序数组中查找数字 I

难度简单54收藏分享切换为英文关注反馈

统计一个数字在排序数组中出现的次数。

 

示例 1:

输入: nums = [5,7,7,8,8,10], target = 8
输出: 2

示例 2:

输入: nums = [5,7,7,8,8,10], target = 6
输出: 0

class Solution {
    public:
    int search(vector& nums, int target) {
        return helper(nums, target) - helper(nums, target - 1);
    }
    int helper(vector& nums, int tar) {
        int i = 0, j = nums.size() - 1;
        while(i <= j) {
            int m = (i + j) / 2;
            if(nums[m] <= tar) i = m + 1;
            else j = m - 1;
        }
        return i;
    }
};

剑指 Offer 53 - II. 0~n-1中缺失的数字

难度简单51收藏分享切换为英文关注反馈

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

 

示例 1:

输入: [0,1,3]
输出: 2

示例 2:

输入: [0,1,2,3,4,5,6,7,9]
输出: 8
class Solution {
public:
    int missingNumber(vector& nums) {
        // if (nums[0]==1) return 0;
        // for (int i = 0;i

请注意:排序数组用二分!面试的时候用二分!做题随便

剑指 Offer 51-60_第1张图片

剑指 Offer 51-60_第2张图片

    int missingNumber(vector& nums) {
        int i=0;
        int j=nums.size()-1;
        while(i<=j){
            int m=(i+j)/2;
            if(nums[m]==m) i=m+1;
            else j=m-1;
        }
        return i;
    }

 

剑指 Offer 54. 二叉搜索树的第k大节点

难度简单50收藏分享切换为英文关注反馈

给定一棵二叉搜索树,请找出其中第k大的节点。

 

示例 1:

输入: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
输出: 4

示例 2:

输入: root = [5,3,6,2,4,null,null,1], k = 3
       5
      / \
     3   6
    / \
   2   4
  /
 1
输出: 4
/**
 * 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:
    int ans=0;int cnt=0;
    void Kth(TreeNode* root,int k){
        if(root==NULL) return;
        Kth(root->right,k);
        cnt++;
        if(cnt==k) ans=root->val;
        Kth(root->left,k);
    }
    int kthLargest(TreeNode* root, int k) {
        Kth(root,k);
        return ans;
    }
};

剑指 Offer 55 - I. 二叉树的深度

难度简单37收藏分享切换为英文关注反馈

输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。

例如:

给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3 。

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(!root)
            return 0;
        return max(maxDepth(root->left),maxDepth(root->right))+1;

    }
};

剑指 Offer 55 - II. 平衡二叉树

难度简单50收藏分享切换为英文关注反馈

输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

 

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回 true

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

       1
      / \
     2   2
    / \
   3   3
  / \
 4   4

返回 false


class Solution {
public:
    unordered_map depth;
    bool ans=true;
    int getTheDepth(TreeNode* root){
        if(root==NULL) depth[root]=0;
        else depth[root]=max(getTheDepth(root->left),getTheDepth(root->right))+1;
        return depth[root];
    }
    void allisBalanced(TreeNode* root){
        if(root==NULL||ans==false) return;
        // cout<left]<<" "<right]<left]-depth[root->right])>1){
            ans=false;return;
        }
        allisBalanced(root->left);
        allisBalanced(root->right);
    }
    bool isBalanced(TreeNode* root) {
        getTheDepth(root);
        allisBalanced(root);
        return ans;
    }
};

class Solution {
public:
    int getTheDepth(TreeNode* root){
        if(root==NULL) return 0;
       return max(getTheDepth(root->left),getTheDepth(root->right))+1;
    }
    bool isBalanced(TreeNode* root) {
        if(root==NULL) return true;
        return abs(getTheDepth(root->left)-getTheDepth(root->right))<=1&&isBalanced(root->left)&&isBalanced(root->right);
    }

剑指 Offer 56 - I. 数组中数字出现的次数

难度中等193收藏分享切换为英文关注反馈

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

 

示例 1:

输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]

示例 2:

输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]

剑指 Offer 51-60_第3张图片

 

 


class Solution {
public:
    vector singleNumbers(vector& nums) {
        int ret = 0;
        for (int n : nums)
            ret ^= n;
        int div = 1;
        while ((div & ret) == 0)
            div <<= 1;
        int a = 0, b = 0;
        for (int n : nums)
            if (div & n)
                a ^= n;
            else
                b ^= n;
        return vector{a, b};
    }
};

剑指 Offer 56 - II. 数组中数字出现的次数 II

难度中等60收藏分享切换为英文关注反馈

在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

 

示例 1:

输入:nums = [3,4,3,3]
输出:4

示例 2:

输入:nums = [9,1,7,9,7,9,7]
输出:1
  •  
  • 异或运算:x ^ 0 = x​ , x ^ 1 = ~x
  • 与运算:x & 0 = 0x & 1 = x
  •  

 

无语,我不会,跳过了....

剑指 Offer 57. 和为s的两个数字

难度简单33收藏分享切换为英文关注反馈

输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。

 

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]

示例 2:

输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]

注意排序了

class Solution {
public:
    vector twoSum(vector& nums, int target) {
        // unordered_map mp;
        // vector ans;
        // for(int i=0;i

 

剑指 Offer 57 - II. 和为s的连续正数序列

难度简单136收藏分享切换为英文关注反馈

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。

序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

 

示例 1:

输入:target = 9
输出:[[2,3,4],[4,5]]

示例 2:

输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]

这为什么是简单

剑指 Offer 51-60_第4张图片

但是这个时间费时长???

class Solution {
public:
    vector> findContinuousSequence(int target) {
        int left=0,right=0;
        int sum=0;
        vector> ans;
        vector tmp;
        while(right<=target/2){
            right++;
            tmp.push_back(right);sum+=right;
            while(sum>=target){
                if(sum==target) ans.push_back(tmp);
                left++;
                tmp.erase(tmp.begin());
                sum-=left;
            }
        }
        return ans;
    }
};

剑指 Offer 58 - I. 翻转单词顺序

难度简单33收藏分享切换为英文关注反馈

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。

 

示例 1:

输入: "the sky is blue"
输出: "blue is sky the"

示例 2:

输入: "  hello world!  "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

示例 3:

输入: "a good   example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

应该说可以简化的比如...?结尾加个空格啥的

class Solution {
public:
    string reverseWords(string s) {
        if(s.size()==0) return s;
        vector v;
        string ans;
        //如何用空格来切割。
        string temp;s+=" ";
        for(int i=0;i=0;i--){
            if(i==v.size()-1) ans+=v[i];
            else{
                ans+=" ";
                ans+=v[i];
            }
        }
        return ans;
    }
};
class Solution {
public:
    string reverseWords(string s) {
        int i = 0, n = s.size();
        string tmp, ans;
        while (i < n) {
            while (i < n && s[i] == ' ') ++i; //跳过空格,让i指针指向单词第一位
            if (i == n) break;

            tmp = "";
            while (i < n && s[i] != ' ') tmp += s[i++]; //记录单词
            ans = tmp + " " + ans;
        }
        if(!ans.empty()) ans.pop_back();
        return ans;
    }
};

作者:Gary_coding
链接:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/solution/c-zhong-gui-zhong-ju-de-8msjie-fa-mo-ni-shi-jian-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 58 - II. 左旋转字符串

难度简单48收藏分享切换为英文关注反馈

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

 

示例 1:

输入: s = "abcdefg", k = 2
输出: "cdefgab"

示例 2:

输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
//天秀操作
class Solution {
public:
    string reverseLeftWords(string s, int n) {
        return (s+s).substr(n,s.size());
    }
};

剑指 Offer 59 - I. 滑动窗口的最大值

难度简单85收藏分享切换为英文关注反馈

给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7] 
解释: 

  滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

 

提示:

你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。

啊这

class Solution {
public:
    class MonotonicQueue{
        deque data;
        //必须写public
        public:
        void push(int n){
            while(!data.empty()&&data.back() maxSlidingWindow(vector& nums, int k) {
        MonotonicQueue window;
        vector ans;
        // if(nums.size()==0||k==0) return NULL;
        for(int i=0;i

剑指 Offer 59 - II. 队列的最大值

难度中等132收藏分享切换为英文关注反馈

请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_valuepush_backpop_front均摊时间复杂度都是O(1)。

若队列为空,pop_frontmax_value 需要返回 -1

示例 1:

输入: 
["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
[[],[1],[2],[],[],[]]
输出: [null,null,null,2,1,2]

示例 2:

输入: 
["MaxQueue","pop_front","max_value"]
[[],[],[]]
输出: [null,-1,-1]

为了解决上述问题,我们只需记住当前最大值出队后,队列里的下一个最大值即可。
具体方法是使用一个双端队列 deque,在每次入队时,如果 deque队尾元素小于即将入队的元素 value,则将小于 value的元素全部出队后,再将 value入队;否则直接入队。

class MaxQueue {
    queue q;
    deque d;
public:
    MaxQueue() {
    }
    
    int max_value() {
        if (d.empty())
            return -1;
        return d.front();
    }
    
    void push_back(int value) {
        while (!d.empty() && d.back() < value) {
            d.pop_back();
        }
        d.push_back(value);
        q.push(value);
    }
    
    int pop_front() {
        if (q.empty())
            return -1;
        int ans = q.front();
        if (ans == d.front()) {
            d.pop_front();
        }
        q.pop();
        return ans;
    }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/solution/mian-shi-ti-59-ii-dui-lie-de-zui-da-zhi-by-leetcod/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 60. n个骰子的点数

难度简单90收藏分享切换为英文关注反馈

把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。

 

你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。

 

示例 1:

输入: 1
输出: [0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]

示例 2:

输入: 2
输出: [0.02778,0.05556,0.08333,0.11111,0.13889,0.16667,0.13889,0.11111,0.08333,0.05556,0.02778]

for (第n枚骰子的点数 i = 1; i <= 6; i ++) {

        dp[n][j] += dp[n-1][j - i]

}

class Solution {
public:
    vector twoSum(int n) {
        //n <= 11
        vector>dp(n + 1, vector(6*n + 1, 0));
        vector ans;
        for(int i = 1; i <= n; i ++){
            for(int j = i; j <= 6*i; j ++){
                if(i == 1) {
                    dp[i][j] = 1;
                    continue;
                }
                for(int k = 1; k <= 6; k ++){
                    if(j - k >= i - 1) dp[i][j] += dp[i - 1][j - k];
                }
            }
        }
        for(int i = n; i <= 6*n; i ++){
            ans.push_back(dp[n][i] * pow(1.0/6, n));
        }
        return ans;
    }
};

 

你可能感兴趣的:(LeetCode面试题)