今天把之前刷过的leetcode高频前10的题目复习了一遍,刷题就像做数学题一样,每道题目多刷几遍,孰能生巧。
//top1 T1两数之和
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>(16);
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(target - nums[i])) {
return new int[]{map.get(target - nums[i]), i};
}
map.put(nums[i], i);
}
return null;
}
/**
* top2 T2两数相加
*/
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head = new ListNode(0);
ListNode cur = head;
int ans = 0;
while (l1 != null || l2 != null) {
int l1Val = l1 != null ? l1.val : 0;
int l2Val = l2 != null ? l2.val : 0;
int sum = l1Val + l2Val + ans;
ans = sum / 10;
cur.next = new ListNode(sum % 10);
cur = cur.next;
l1 = l1 != null ? l1.next : null;
l2 = l2 != null ? l2.next : null;
}
if (ans != 0) {
cur.next = new ListNode(ans);
}
return head.next;
}
//top3 T5最长回文字串(中心扩展算法)
public String longestPalindrome(String s) {
int left = 0;
int right = 0;
for (int i = 0; i < s.length(); i++) {
int max1 = getMaxLen(s, i, i);
int max2 = getMaxLen(s, i, i + 1);
int max = Math.max(max1, max2);
if (max > (right - left + 1)) {
left = i - (max - 1) / 2;
right = i + max / 2;
}
}
return s.substring(left, right + 1);
}
public int getMaxLen(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return right - left - 1;
}
/**
* top4 T3无重复字符的最长子串(不熟)
*/
public int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet<>(16);
int right = 0;
int maxLen = 0;
for (int i = 0; i < s.length(); i++) {
if (i != 0) {
set.remove(s.charAt(i - 1));
}
while (right < s.length() && !set.contains(s.charAt(right))) {
set.add(s.charAt(right));
right++;
}
maxLen = Math.max(maxLen, set.size());
}
return maxLen;
}
// top5 T175 组合两个表
select FirstName, LastName, City, State from Person a left join Address b on a.PersonId = b.PersonId
// top7 T15 三数之和
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>(16);
Arrays.sort(nums);
int n = nums.length;
for (int first = 0; first < n; first++) {
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
int target = -nums[first];
int third = n - 1;
for (int second = first + 1; second < n; second++) {
if (second > first + 1 && nums[second] == nums[second-1]) {
continue;
}
while (third > second && nums[second] + nums[third] > target) {
third--;
}
if (second == third) {
break;
}
if (nums[second] + nums[third] == target) {
List<Integer> ans = new ArrayList<>(16);
ans.add(nums[first]);
ans.add(nums[second]);
ans.add(nums[third]);
result.add(ans);
}
}
}
return result;
}
三数之和这道题刚开始没有写
if (second == third) { break; }
导致输出的结果中存在nums[second]和nums[third]相同的情况,还是要考虑周到。
// top8 T176第二高的薪水
select (select distinct Salary from Employee order by Salary desc limit 1,1) as SecondHighestSalary
/**
* top9 T70 爬楼梯
*/
public int climbStairs(int n) {
int a, b = 0, c = 1;
for (int i = 1; i <= n; i++) {
a = b;
b = c;
c = a + b;
}
return b;
}
这道题看起来简单,但实际上要先理解动态规划的原理才能明白这道题,类似的动态规划题目还有斐波拉契数列等等,都是一些经常出现在面试中的题目。
/**
* top10 T206反转链表(方法1:递归)
*/
public ListNode reverseList(ListNode head) {
if (head == null) {
return null;
}
ListNode cur = reverseList(head.next);
head.next.next = head;
head.next = null;
return cur;
}
/**
* top10 T206反转链表(方法2:双指针)
*/
public ListNode reverseList1(ListNode head) {
ListNode cur = head;
ListNode pre = null;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}