leetcode腾讯精选练习(50 题)(持续更新)

1.除自身以外数组的乘积

给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。

示例:

输入: [1,2,3,4]
输出: [24,12,8,6]
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。

题解:记录前缀积和后缀积。

参考代码:

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums)
    {
        int siz=nums.size();
        vector<int> pre(siz+1),nxt(siz+2),ans(siz);
        pre[0]=1;nxt[siz+1]=1;
        for(int i=0;i<siz;++i)
            pre[i+1]=pre[i]*nums[i];
        for(int i=siz-1;i>=0;--i)
            nxt[i+1]=nxt[i+2]*nums[i];

        for(int i=1;i<=siz;++i)
            ans[i-1]=pre[i-1]*nxt[i+1];

        return ans;
    }
};

C++

2.格雷编码

格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。

给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。格雷编码序列必须以 0 开头。

示例 1:

输入: 2
输出: [0,1,3,2]
解释:
00 - 0
01 - 1
11 - 3
10 - 2

对于给定的 n,其格雷编码序列并不唯一。
例如,[0,2,3,1] 也是一个有效的格雷编码序列。

00 - 0
10 - 2
11 - 3
01 - 1
示例 2:

输入: 0
输出: [0]
解释: 我们定义格雷编码序列必须以 0 开头。
  给定编码总位数为 n 的格雷编码序列,其长度为 2n。当 n = 0 时,长度为 20 = 1。
  因此,当 n = 0 时,其格雷编码序列为 [0]。

题解:

对于每一层都是上一层倒着加上2^(i-1)次方。

参考代码:

class Solution {
public:
    int qpow(int n,int m)
    {
        int res=1;
        while(m)
        {
            if(m&1) res=res*n;
            n=n*n; m>>=1;
        }
        return res;
    }
    vector<int> grayCode(int n)
    {
        vector<int> ans;
        if(n==0)
        {
            ans.push_back(0);
            return ans;
        }
        ans.push_back(0);
        ans.push_back(1);

        for(int i=2;i<=n;++i)
        {
            vector<int> res=ans;
            int num=qpow(2,i-1),siz=ans.size();
            for(int j=siz-1;j>=0;--j)
                ans.push_back(res[j]+num);
        }

        return ans;
    }
};

C++

3.二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]

示例 1:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
示例 2:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

说明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉树中。

题解:

  递归。

  两个节点要么是父子关系,要么在一个root下,我们们判断root是否为p或q,是的话,就返回root.

然后递归左右子树,如果left!=null&&right!=null则返回root.

如果left==null,则返回右子树的递归结果,否则返回左子树的递归结果。

参考代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)
    {
        if(root==null) return root;
        if(root==p||root==q) return root;
        TreeNode left=lowestCommonAncestor(root.left,p,q);
        TreeNode right=lowestCommonAncestor(root.right,p,q);

        if(left!=null && right!=null) return root;
        if(left==null) return right;
        else return left;
    }
}

Java

Java

4.二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

说明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉搜索树中。

题解:

可以用上一题的解法。但是根据二叉搜索树的特点,左子树的值都比我小,右子树都比我大。

递归,3行代码解决问题。

参考代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root.val>p.val && root.val>q.val) return lowestCommonAncestor(root.left, p, q);
        if(root.val<p.val && root.val<q.val) return lowestCommonAncestor(root.right,p,q);
        return root;
    }

}

Java

5.二叉树中的最大路径和

给定一个非空二叉树,返回其最大路径和。

本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。

示例 1:

输入: [1,2,3]

1
/ \
2 3

输出: 6
示例 2:

输入: [-10,9,20,null,null,15,7]

-10
   / \
  9  20
    /  \
   15   7

输出: 42

题解:

类似树形DP,记录每个节点的左右子树到节点的一条链的最大值,和当前子树任意两点间的最大值即可(注意边界条件)。

参考代码:

/**
 * 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:
    const int INF=0x3f3f3f3f;
    pair<int,int> work(TreeNode *root)
    {
        pair<int,int> p(-INF,-INF);
        if(root==NULL) return p;
        pair<int,int> l=work(root->left);
        pair<int,int> r=work(root->right);
        p.first=max(max(l.first,r.first)+root->val,root->val);
        p.second=max(max(l.second,r.second),max(root->val,max(l.first+root->val+r.first,p.first)));
        return p;
    }
    int maxPathSum(TreeNode* root)
    {
        pair<int,int> ans=work(root);
        return ans.second;
    }
};

C++

未完待续~

原文地址:https://www.cnblogs.com/csushl/p/12074694.html

时间: 2024-08-29 22:34:38

leetcode腾讯精选练习(50 题)(持续更新)的相关文章

LeetCode 腾讯精选50题-- 买卖股票的最佳时机 II

贪心算法: 具体的解题思路如下: II 的解题思路可以分为两部分, 1. 找到数组中差值较大的两个元素,计算差值. 2. 再步骤一最大的元素的之后,继续遍历,寻找差值最大的两个元素 可以得出的是,遍历指针是一直向着数组的尾部移动的,由于要取得局部的最大差值,这一局部子数组中的元素一定是递增的,所以先找到递增结束的位置,那就是递增位置的起点,然后遍历至此轮递增结束时的位置,这样就得到了一个局部的最优解. 此思路由于指针只遍历一次,所以时间复杂度为O(N). 以下是代码: class Solutio

LeetCode 腾讯精选50题--子集

根据题意,找到几何中的所有子集,说实话子集是没有什么头绪的,因为如果采用遍历的方法,稍有遗漏不说,代码的嵌套循环层数随着数组大小的增加而增加,想了很久没有头绪后就去看了看评论,然后就被点破了解题的关键:遍历数组时,让当前这一元素构成的集合,分别去加上之前找到的所有子集,由于第一次找到的子集一定有两个,一个为空,一个带有一个元素,那么用当前元素组成的集合分别加上之前的集合,一定会有一个集合只有当前元素 如图: 由于采用遍历的方式,对于数组长度为N,指针没往前走一次,要遍历的子集数量是原来的2倍,所

腾讯 2018 秋招精选(50 题)

AC # 题名 难度   2 两数相加  中等   4 两个排序数组的中位数  困难   5 最长回文子串  中等   7 反转整数  简单   8 字符串转整数  中等   9 回文数   简单   11 盛最多水的容器  中等   14 最长公共前缀  简单   15 三数之和   中等   16 最接近的三数之和  中等   20 有效的括号  简单   21 合并两个有序链表  简单   23 合并k个有链表  困难   26 删除排序数组中的重复项   简单   33 搜索旋转排序数组

leetcode腾讯精选练习之除自身以外数组的乘积(十)

最长公共前缀 题目 给定长度为?n?的整数数组?nums,其中?n > 1,返回输出数组?output?,其中 output[i]?等于?nums?中除?nums[i]?之外其余各元素的乘积. 示例: 输入: [1,2,3,4] 输出: [24,12,8,6] 说明: 请不要使用除法,且在?O(n) 时间复杂度内完成此题. 思路 第一种思路O(n2):但是不符合题目要求 两层循环遍历,思路很简单不详细说了第一层遍历数组中中的每个数,第二层遍历求解除了本身之外的乘积. 第二种思路就是除法:也不符合

leetcode腾讯精选练习之最长公共前缀(九)

最长公共前缀 题目 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串?"". 示例?1: 输入: ["flower","flow","flight"] 输出: "fl" 示例?2: 输入: ["dog","racecar","car"] 输出: "" 解释: 输入不存在公共前缀. 说明: 所有输入

素数相关?(有关素数的题持续更新中)x

素数(大体举几个栗子): 素数相关知识: 素数概念: 最大公约数只有1和它本身的数叫做质数(素数) 素数小性质: 1.大于一的整数必有素因数. 2.设p是素数,n是任意一个整数 能够推出p|n,(p,n)=1; 3.设p是素数,a,b为整数,若p|ab,则ab中至少有一个能被p整除 4.素数有无穷多个证明: (素数与整数之间的关系:1整除2互素) 假定正整数中只有有限个素数 设p1,p2……pk为从小到大排列起来的数 且N=p1*p2*……pk 设M=N+1 如果M为素数,那么M要大于p1,p2

【Leetcode】动态规划问题详解(持续更新)

1.动态规划算法步骤(Dynamic Programming) 动态规划算法一般用来求解最优化问题,当问题有很多可行解,而题目要求寻找这些解当中的"最大值"/"最小值"时,通常可以采用DP. 动态规划算法与分治法相似,都是通过组合子问题的解来求解原问题.所不同的是,动态规划应用于子问题重叠的情况,在递归求解子问题的时候,一些子子问题可能是相同的,这种情况下,分治法会反复地计算同样的子问题,而动态规划对于相同的子问题只计算一次. 动态规划算法的设计步骤: 1.刻画最优

2019字节跳动面试时手撕代码题(持续更新~)

1. N 阶乘末尾0的个数. 输入描述: 输入为一行,n(1 ≤ n ≤ 1000) 输出描述: 输出一个整数,即题目所求解法:要判断末尾有几个0就是判断可以整除几次10.10的因子有5和2,而在0~9之间5的倍数只有一个,2的倍数相对较多,所以本题也就转换成了求N阶乘中有几个5的倍数.也就是每多出来一个5,阶乘末尾就会多出来一个0,这样n / 5就能统计完第一层5的个数,依次处理,就能统计出来所有5的个数.同一个思想两种写法. 题解: 要判断末尾有几个0就是判断可以整除几次10.10的因子有5

sql语句练习50题

sql语句练习50题 Student(Sid,Sname,Sage,Ssex) 学生表 Course(Cid,Cname,Tid) 课程表 SC(Sid,Cid,score) 成绩表 Teacher(Tid,Tname) 教师表 练习内容: 1.查询“某1”课程比“某2”课程成绩高的所有学生的学号: SELECT a.sid FROM (SELECT sid,score FROM SC WHERE cid=1) a,(SELECT sid,score FROM SC WHERE cid=3) b