1. 组合两个表

image-20200724091409976
解题思路

因为表 Address 中的 personId 是表 Person 的外关键字,所以我们可以连接这两个表来获取一个人的地址信息。

考虑到可能不是每个人都有地址信息,我们应该使用 outer join 而不是默认的 inner join。

作者:LeetCode
链接:https://leetcode-cn.com/problems/combine-two-tables/solution/zu-he-liang-ge-biao-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

1
2
3
4
select p.FirstName, p.LastName, a.City, a. State
from Person p
left join Address a
on p.PersonId = a.PersonId;
image-20200724091642420

2. 第二高的薪水

image-20200724092500972
解题方法一:使用子查询和 LIMIT 子句

将不同的薪资按降序排序,然后使用 LIMIT 子句获得第二高的薪资。

然而,如果没有这样的第二最高工资,这个解决方案将被判断为 “错误答案”,因为本表可能只有一项记录。为了克服这个问题,我们可以将其作为临时表。

如果查询结果为 null,原本将返回空数据,建立临时表后变为:select null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT
(SELECT DISTINCT
Salary
FROM
Employee
ORDER BY Salary DESC
LIMIT 1 OFFSET 1)
AS SecondHighestSalary
;

#作者:LeetCode
#链接:https://leetcode-cn.com/problems/second-highest-salary/solution/di-er-gao-de-xin-shui-by-leetcode/
#来源:力扣(LeetCode)
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

解题方法二:使用 IFNULLLIMIT 子句

解决 “NULL” 问题的另一种方法是使用 “IFNULL” 函数,如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
IFNULL(
(SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT 1 OFFSET 1),
NULL)
AS SecondHighestSalary

#作者:LeetCode
#链接:https://leetcode-cn.com/problems/second-highest-salary/solution/di-er-gao-de-xin-shui-by-leetcode/
#来源:力扣(LeetCode)
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3. 两数之和 II - 输入有序数组

image-20200724101739403
解法一:二分查找

在本题中,我们可以先固定一个值 num,然后再使用二分查找找 target - num

充分利用了题目中所给的数组是有序数组的条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public int[] twoSum(int[] numbers, int target) {
for (int i = 0; i < numbers.length; i++) {
// 固定一个值 num
int num = numbers[i];
int left = i + 1, right = numbers.length - 1;
// 二分查找 target - num
while (left <= right) {
int mid = left + (right - left) / 2;
if (numbers[mid] == target - num) {
return new int[]{i + 1, mid + 1};
} else if (numbers[mid] < target - num) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return null;
}
}
  • 时间复杂度:O (n logn)
  • 空间复杂度:O (1)
解法二:Map

我们可以把数组的元素存储到Map中,然后再查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {    
public int[] twoSum(int[] num, int target) {
Map<Integer, Integer> map = new HashMap<>(num.length);
for (int i = 0; i < num.length; i++) {
if (map.get(target - num[i]) != null) {
return new int[]{map.get(target - num[i]) + 1, i + 1};
}
map.put(num[i], i);
}
return null;
}
}

/*
作者:sdwwld
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/solution/javashuang-zhi-zhen-qiu-jie-by-sdwwld/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/
  • 时间复杂度:O (n)
  • 空间复杂度:O (n)
解法三:双指针法(最优解)

使用两个指针分别指向数组的头尾,将指针指向的值的和 sumtarget 作比较:

  • sum < targetleft++
  • sum = target:return new int[]{left + 1. right + 1}
  • sum > targetright++

充分利用了题目中所给的数组是有序数组的条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public int[] twoSum(int[] numbers, int target) {
if (numbers == null) return null;
int i = 0, j = numbers.length - 1;
while (i < j) {
int sum = numbers[i] + numbers[j];
if (sum == target) {
return new int[]{i + 1, j + 1};
} else if (sum < target) {
i++;
} else {
j--;
}
}
return null;
}

/*
作者:CyC2018
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/solution/shuang-zhi-zhen-on-shi-jian-fu-za-du-by-cyc2018/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/
  • 时间复杂度:O (n)
  • 空间复杂度:O (1)