0%

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.demo.s20;

import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/**
* 有效的括号
* 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
*
* 有效字符串需满足:
*
* 左括号必须用相同类型的右括号闭合。
* 左括号必须以正确的顺序闭合。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/valid-parentheses
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public boolean isValid(String s) {
//根据入参判断 不能为奇数
if(s.length() % 2 != 0) {
return false;
}
//符号对
Map<Character, Character> pairs = new HashMap();
pairs.put('(', ')');
pairs.put('[', ']');
pairs.put('{', '}');
//字符串转字符数组
char[] charr =s.toCharArray();
//放入栈中判断
Deque<Character> stack = new LinkedList();
for(int i = 0; i< charr.length ; i++) {
//如果为左侧符号, 符号对key中一定存在,则压栈
if(pairs.containsKey(charr[i])) {
stack.push(pairs.get(charr[i]));
//如果符号对key中不存在,栈中有元素,且栈顶符号等于当前符号,则弹栈
} else if(stack.size()!=0 && stack.peek() == charr[i]){
stack.pop();
continue;
} else {
return false;
}

}
return stack.size() == 0;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.demo.s2;

/**
* 给你两个非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
*
* 请你将两个数相加,并以相同形式返回一个表示和的链表。
*
* 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/add-two-numbers
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
/**
* Definition for singly-linked list.
*/
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//新建结果链表
ListNode head = new ListNode();
//记录当前节点 方便后面移动
ListNode cur = head;
//相加 > 10 进一位 进位的值
int carray = 0;
//判断结束条件
while(l1 != null || l2 != null || carray!=0) {
// 对应位相加的和
int sum = 0;
//l1各位已经加完了, l2 还没有结束
if(l1 == null && l2 != null) {
sum = l2.val;
l2 = l2.next;
//l2各位已经加完了, l1 还没有结束
} else if(l2 == null && l1 != null) {
sum = l1.val;
l1 = l1.next;
//l1 l2 对应位置有值则相加
} else if(l2 != null && l1 != null){
sum = l1.val + l2.val;
l1 = l1.next;
l2 = l2.next;
}
//接到结果链表链表后面
cur.next = new ListNode((sum + carray) % 10);
//需要进一位的保存在变量carray
carray = (sum + carray) / 10;
cur = cur.next;
}
return head.next;
}
public static void main(String[] args) {

}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.demo.s199;


import java.util.*;

/**
* 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
*
*
*/

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;
}
}

public class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> ret = new ArrayList<>();
if(root == null) {
return ret;
}

int max_dep = -1;
//右分支视图按层输出
Map<Integer,Integer> rightViewAtDepth = new HashMap<Integer, Integer>();
//节点压栈
Stack<TreeNode> nodeStack = new Stack<>();
nodeStack.push(root);
//深度压栈
Stack<Integer> depthStack = new Stack<>();
depthStack.push(0);
while(nodeStack.size() != 0 ) {
//节点弹栈
TreeNode node = nodeStack.pop();
//深度弹栈
Integer dep = depthStack.pop();
if(node != null) {
//最大深度
max_dep = Math.max(dep, max_dep);
//右视图未遍历到该层,第一次遍历到的一定是右节点
if(!rightViewAtDepth.containsKey(dep)) {
//存入视图
rightViewAtDepth.put(dep, node.val);
}
//左节点压栈
nodeStack.push(node.left);
//右节点压栈
nodeStack.push(node.right);
//层数存入深度栈
depthStack.push(dep + 1);
//层数存入深度栈
depthStack.push(dep + 1);
}
}

//遍历深度
for(int i = 0 ;i <= max_dep; i++) {
Integer val = rightViewAtDepth.get(i);
ret.add(val);
}
return ret;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.demo.s19;

/**
* 删除链表的倒数第 N 个结点
* 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
*/
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dum = new ListNode(0, head);
int cnt = 0;
while(head != null) {
cnt++;
head = head.next;
}

head = dum;
for(int i = 1; i< cnt-n + 1; i++) {
head = head.next;
}
head.next = head.next.next;
return dum.next;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.demo.s18;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* 四数之和
* 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
*
* 0 <= a, b, c, d < n
* a、b、c 和 d 互不相同
* nums[a] + nums[b] + nums[c] + nums[d] == target
* 你可以按 任意顺序 返回答案 。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/4sum
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> quadruplets = new ArrayList<List<Integer>>();
if (nums == null || nums.length < 4) {
return quadruplets;
}
Arrays.sort(nums);
int length = nums.length;
for (int i = 0; i < length - 3; i++) {
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
if (nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
break;
}
if (nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
continue;
}
for (int j = i + 1; j < length - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
break;
}
if (nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {
continue;
}
int left = j + 1, right = length - 1;
while (left < right) {
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum == target) {
quadruplets.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
left++;
while (left < right && nums[right] == nums[right - 1]) {
right--;
}
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
}
return quadruplets;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.demo.s17;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 电话号码的字母组合
* 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
*
* 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/letter-combinations-of-a-phone-number
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public List<String> letterCombinations(String digits) {

List<String> combinations = new ArrayList<String>();
if (digits.length() == 0) {
return combinations;
}
Map<Character, String> phoneMap = new HashMap<Character, String>() {{
put('2', "abc");
put('3', "def");
put('4', "ghi");
put('5', "jkl");
put('6', "mno");
put('7', "pqrs");
put('8', "tuv");
put('9', "wxyz");
}};
backtrack(combinations, phoneMap, digits, 0, new StringBuffer());
return combinations;
}

public void backtrack(List<String> combinations, Map<Character, String> phoneMap, String digits, int index, StringBuffer combination) {
if (index == digits.length()) {
combinations.add(combination.toString());
} else {
char digit = digits.charAt(index);
String letters = phoneMap.get(digit);
int lettersCount = letters.length();
for (int i = 0; i < lettersCount; i++) {
combination.append(letters.charAt(i));
backtrack(combinations, phoneMap, digits, index + 1, combination);
combination.deleteCharAt(index);
}
}
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.demo.s169;

import java.util.HashMap;
import java.util.Map;

/**
* 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
*
* 你可以假设数组是非空的,并且给定的数组总是存在多数元素。
*
*  
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/majority-element
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
private Map<Integer, Integer> countNums(int[] nums) {
Map<Integer, Integer> counts = new HashMap<Integer, Integer>();
for (int num : nums) {
if (!counts.containsKey(num)) {
counts.put(num, 1);
} else {
counts.put(num, counts.get(num) + 1);
}
}
return counts;
}

public int majorityElement(int[] nums) {
Map<Integer, Integer> counts = countNums(nums);

Map.Entry<Integer, Integer> majorityEntry = null;
for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {
if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) {
majorityEntry = entry;
}
}

return majorityEntry.getKey();
}

}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.demo.s165;

/**
* 给你两个版本号 version1 和 version2 ,请你比较它们。
*
* 版本号由一个或多个修订号组成,各修订号由一个 '.' 连接。每个修订号由 多位数字 组成,可能包含 前导零 。每个版本号至少包含一个字符。修订号从左到右编号,下标从 0 开始,最左边的修订号下标为 0 ,下一个修订号下标为 1 ,以此类推。例如,2.5.33 和 0.1 都是有效的版本号。
*
* 比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较 忽略任何前导零后的整数值 。也就是说,修订号 1 和修订号 001 相等 。如果版本号没有指定某个下标处的修订号,则该修订号视为 0 。例如,版本 1.0 小于版本 1.1 ,因为它们下标为 0 的修订号相同,而下标为 1 的修订号分别为 0 和 1 ,0 < 1 。
*
* 返回规则如下:
*
* 如果 version1 > version2 返回 1,
* 如果 version1 < version2 返回 -1,
* 除此之外返回 0。
*  
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/compare-version-numbers
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public int compareVersion(String version1, String version2) {
String[] v1 = version1.split("\\.");
String[] v2 = version2.split("\\.");

for (int i = 0; i < v1.length||i<v2.length; ++i) {
int x = 0, y = 0;
if (i < v1.length) {
x = Integer.parseInt(v1[i]);
}
if (i < v2.length) {
y = Integer.parseInt(v2[i]);
}
if (x > y) {
return 1;
}
if (x < y) {
return -1;
}
}
return 0;
}


}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.demo.s160;

/**
* Definition for singly-linked list.

*/
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}

public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode pA = headA, pB = headB;
while (pA != pB) {
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.demo.s16;

import java.util.Arrays;

/**
* 最接近的三数之和
* 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
*
* 返回这三个数的和。
*
* 假定每组输入只存在恰好一个解。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/3sum-closest
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int n = nums.length;
int best = 10000000;

// 枚举 a
for (int i = 0; i < n; ++i) {
// 保证和上一次枚举的元素不相等
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
// 使用双指针枚举 b 和 c
int j = i + 1, k = n - 1;
while (j < k) {
int sum = nums[i] + nums[j] + nums[k];
// 如果和为 target 直接返回答案
if (sum == target) {
return target;
}
// 根据差值的绝对值来更新答案
if (Math.abs(sum - target) < Math.abs(best - target)) {
best = sum;
}
if (sum > target) {
// 如果和大于 target,移动 c 对应的指针
int k0 = k - 1;
// 移动到下一个不相等的元素
while (j < k0 && nums[k0] == nums[k]) {
--k0;
}
k = k0;
} else {
// 如果和小于 target,移动 b 对应的指针
int j0 = j + 1;
// 移动到下一个不相等的元素
while (j0 < k && nums[j0] == nums[j]) {
++j0;
}
j = j0;
}
}
}
return best;


}
}