数据库LeetCode每日练习

Posted 小杰312

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库LeetCode每日练习相关的知识,希望对你有一定的参考价值。

目录

前言

题目1: 合并两个表

顺便回顾一下几种连接

总结:

题目2:超过经理收入的员工

题目三:查找重复的电子邮件

总结


 

前言

mysql必知必会,详尽入门,一文帮你学会SQL必知必会_小杰312的博客-CSDN博客MYSQL基操一网打尽,详尽入门,一文帮你学会SQL必知必会https://blog.csdn.net/weixin_53695360/article/details/123770512?spm=1001.2014.3001.5502

  • 上面这个是一些基础的mysql入门必知必会,可以帮助sql语法不熟悉的友友快速回顾和入门各种操作
  • 这个系列是小杰针对mysql的每日练习,如果您觉得对您有所帮助,麻烦关注小杰,让我们一起练习sql题目,熟练各种查询表合并操作        ---  为将来的面试打基础

题目1: 合并两个表

175. 组合两个表

  • 题目要求: 

    编写一个SQL查询来报告 Person 表中每个人的姓、名、城市和状态。如果 personId 的地址不在 Address 表中,则报告为空  null 。

    以 任意顺序 返回结果表。

  • 题目分析: 因为如果personId 的地址不存在 Address表中报告为 null 但是还是需要输出personId 表信息, 故而是一种外连接的方式: 

 

select 
    FirstName, LastName, city, state
from 
    person p left outer join address a
    on p.personid = a.personid

顺便回顾一下几种连接

  • inner join : 内连接  2表值都存在

  • outer join : 附表中值可能存在null的情况

总结:

  1. A inner join B : 取交集
  2. A left join B : 取A全部,B没有对应的值,则为null
  3. A right join B : 取B全部,A没有对应的值,则为null
  4. A full outer B : 取并集, 彼此没有对应的值为 null

 

筛选条件   写在 on 后面

题目2:超过经理收入的员工

181. 超过经理收入的员工

  •  题目要求

编写一个SQL查询来查找收入比经理高的员工。

  • 题目分析:要求查找收入高于经理的员工,这个是很明显的自连接问题,我们需要对比的信息是处在同一个表的,这种关系我们可以理解为自连接的题目
  • 自联结:自联结字面的意思就是,自己和自己联结。此时联结所用到的表只有一张,此时我们可以把自联结想象成两张一模一样的表在进行联结。
  • 这种题目常常是两条连接的信息处在同一张表中。员工经理都处在employee表中, 明显自连接题目

 

# 形式1
select 
    a.name as Employee
from 
    Employee a inner join Employee b
    on a.managerid = b.id
where 
    a.salary > b.salary; 
# 形式2

/*
select 
    a.name as Employee
from 
    Employee a inner join Employee b
    on a.managerid = b.id &&  a.salary > b.salary;
*/ 

# 形式3

/*
select 
    a.name as Employee
from 
    Employee a, Employee b
where
    a.managerid = b.id && a.salary > b.salary;
*/ 

题目三:查找重复的电子邮件

182. 查找重复的电子邮箱

 

 

  • 要求: 查找表中所有重复的电子邮件
  • 思路: 竟然是重复的电子邮件,说明按照email分组之后会进行去重count,我们将count(email) > 1 的结果保留就是ans了 

 

select 
    email
from
    person
group by
    email
having 
    count(email) > 1;

总结

  • 今日份的题目主要是回顾了几种表连接方式,表连接如何理解使用集合的交并这些来理解,内连接交集,全外连接并集,左外右外连接:左右表全部信息,没有关联的写null
  • 表自连接查询,相同的一张表可以自己跟自己形成自连接进行查询
  • 还有分组查询   请注意一个优先顺序:     where > group by > having > order by 

 

leetcode习题练习-每日更新

leetcode 20. 有效的括号

给定一个只包括 '(',')','','','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

        1.左括号必须用相同类型的右括号闭合。
        2.左括号必须以正确的顺序闭合。
        3.每个右括号都有一个对应的相同类型的左括号。

示例 1:

输入:s = "()"
输出:true
示例 2:

输入:s = "()[]"
输出:true
示例 3:

输入:s = "(]"
输出:false

提示:

1 <= s.length <= 104
s 仅由括号 '()[]' 组成

class Solution 
    public boolean isValid(String s) 
       int n = s.length();
       if (n % 2 == 1) 
           return false;
       
       Map<Character, Character> map = new HashMap<Character, Character>();
       map.put(')', '(');
       map.put(']', '[');
       map.put('', '');
       Deque<Character> stack = new LinkedList<Character>();
       for (int i = 0; i < n; i++) 
           char ch = s.charAt(i);
           if (map.containsKey(ch)) 
               if (stack.isEmpty() || stack.peek() != map.get(ch)) 
                 return false;
               
               stack.pop();
            else 
               stack.push(ch);
           
       
       return stack.isEmpty();
    



232. 用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:

你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
 
 

示例 1:

输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
 

提示:

1 <= x <= 9
最多调用 100 次 push、pop、peek 和 empty
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)
 

进阶:

你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。

class MyQueue 
    Deque<Integer> inPutStack;
    Deque<Integer> outPutStack;

    public MyQueue() 
        inPutStack = new ArrayDeque<Integer>();
        outPutStack = new ArrayDeque<Integer>();
    
    
    public void push(int x) 
        inPutStack.push(x);
    
    
    public int pop() 
        if (outPutStack.isEmpty()) 
            inToOut();
        
        return outPutStack.pop();
    
    
    public int peek() 
        if (outPutStack.isEmpty()) 
            inToOut();
        
        return outPutStack.peek();
    
    
    public boolean empty() 
        return inPutStack.isEmpty() && outPutStack.isEmpty();
    

    private void inToOut() 
        while(!inPutStack.isEmpty()) 
            outPutStack.push(inPutStack.pop());
        
    

225. 用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
 

注意:

你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
 

示例:

输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]

解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

提示:

1 <= x <= 9
最多调用100 次 push、pop、top 和 empty
每次调用 pop 和 top 都保证栈不为空

class MyStack 
    Queue<Integer> queueOne;
    Queue<Integer> queueTwo;

    public MyStack() 
        queueOne = new LinkedList<Integer>();
        queueTwo = new LinkedList<Integer>();
    
    
    public void push(int x) 
        queueTwo.offer(x);
        while(!queueOne.isEmpty()) 
            queueTwo.offer(queueOne.poll());
        
        Queue<Integer> temp = queueOne;
        queueOne = queueTwo;
        queueTwo = temp;
    
    
    public int pop() 
        return queueOne.poll();
    
    
    public int top() 
        return queueOne.peek();
    
    
    public boolean empty() 
        return queueOne.isEmpty();
    



703. 数据流中的第 K 大元素

设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。

请实现 KthLargest 类:

KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
 

示例:

输入:
["KthLargest", "add", "add", "add", "add", "add"]
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
输出:
[null, 4, 5, 5, 8, 8]

解释:
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3);   // return 4
kthLargest.add(5);   // return 5
kthLargest.add(10);  // return 5
kthLargest.add(9);   // return 8
kthLargest.add(4);   // return 8

提示:
1 <= k <= 104
0 <= nums.length <= 104
-104 <= nums[i] <= 104
-104 <= val <= 104
最多调用 add 方法 104 次
题目数据保证,在查找第 k 大元素时,数组中至少有 k 个元素
 

class KthLargest 
    PriorityQueue<Integer> pq;
    int k;

    public KthLargest(int k, int[] nums) 
        this.k = k;
        pq = new PriorityQueue<Integer>();
        for (int x : nums) 
            add(x);
        
    
    
    public int add(int val) 
        pq.offer(val);
        if (pq.size() > k) 
            pq.poll();
        
        return pq.peek();
    

242. 有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

示例 1:

输入: s = "anagram", t = "nagaram"
输出: true
示例 2:

输入: s = "rat", t = "car"
输出: false
 

提示:

  • 1 <= s.length, t.length <= 5 * 104
  • s 和 t 仅包含小写字母
class Solution 
    public boolean isAnagram(String s, String t) 
        if (s.length() != t.length()) 
            return false;
        
        int[] table = new int[26];
        for (int i = 0; i < s.length(); i++) 
            table[s.charAt(i) - 'a']++;
        
        for (int i = 0; i < t.length(); i++) 
            table[t.charAt(i) - 'a']--;
            if (table[t.charAt(i) - 'a'] < 0) 
                return false;
            
        
        return true;
    



1. 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案

class Solution 
    public int[] twoSum(int[] nums, int target) 
        Map<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; i++) 
            if (hashMap.containsKey(target - nums[i])) 
                return new int[] hashMap.get(target - nums[i]), i;
            
            hashMap.put(nums[i], i);
        
        return new int[0];
    



98. 验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

 

提示:

  • 树中节点数目范围在[1, 104] 内
  • -231 <= Node.val <= 231 - 1
/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public boolean isValidBST(TreeNode root) 
        Deque<TreeNode> linkedList = new LinkedList<TreeNode>();
        double inorderValue = -Double.MAX_VALUE;
        while(!linkedList.isEmpty() || root != null) 
            while(root != null) 
                linkedList.push(root);
                root = root.left;
            
            root = linkedList.pop();
            if (root.val <= inorderValue) 
                return false;
            
            inorderValue = root.val;
            root = root.right;
        
        return true;
    



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

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

百度百科中最近公共祖先的定义为:“对于有根树 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 为不同节点且均存在于给定的二叉搜索树中。
class Solution 
    public TreeNode lowestCommonAncestor(TreeNode cur, TreeNode p, TreeNode q) 
        if (cur == null || cur == p || cur == q) 
            return cur;
        
        TreeNode left = lowestCommonAncestor(cur.left, p, q);
        TreeNode right = lowestCommonAncestor(cur.right, p, q);
        if (left == null) 
            return right;
        
        if (right == null) 
            return left;
        
        return cur;
    

102. 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:

输入:root = [1]
输出:[[1]]
示例 3:

输入:root = []
输出:[]

方法一:广度优先搜索

class Solution 
    public List<List<Integer>> levelOrder(TreeNode root) 
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if (root == null) 
            return result;
        
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while(!queue.isEmpty()) 
            List<Integer> level = new ArrayList<Integer>();
            int currrentLevelSize = queue.size();
            for (int i = 1; i <= currrentLevelSize; i++) 
                TreeNode node = queue.poll();
                level.add(node.val);
                if (node.left != null) 
                    queue.offer(node.left);
                
                if (node.right != null) 
                    queue.offer(node.right);
                
            
            result.add(level);
        
        return result;
    



104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

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

 

 

class Solution 
    public int maxDepth(TreeNode root) 
        if (root == null) 
            return 0;
         else 
            int leftHeight = maxDepth(root.left);
            int rightHeight = maxDepth(root.right);
            return Math.max(leftHeight, rightHeight) + 1;
        
    


以上是关于数据库LeetCode每日练习的主要内容,如果未能解决你的问题,请参考以下文章

leetcode习题练习-每日更新

LeetCode每日一题:240搜索二维矩阵II

LeetCode 每日一题「罗马数字转整数」

算法练习80.字符串轮转——奇淫技巧

每日算法/刷穿 LeetCode13. 罗马数字转整数(简单)

每日算法/刷穿 LeetCode12. 整数转罗马数字(中等)