Skip to content

Commit 3eafc4a

Browse files
committed
HOT100-简单题3道
1 parent 35069e4 commit 3eafc4a

File tree

4 files changed

+344
-0
lines changed

4 files changed

+344
-0
lines changed

leetcode_Java/DoneTitle.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@
1616
145. 二叉树的后序遍历
1717
155. 最小栈
1818
160. 相交链表
19+
169. 多数元素
20+
206. 反转链表
1921
226. 翻转二叉树
22+
234. 回文链表
2023
589. N叉树的前序遍历

leetcode_Java/Solution0169.java

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// 多数元素
2+
3+
4+
/*
5+
排序:先排序,不管元素个数是奇数还是偶数,众数元素一定在中间位置
6+
*/
7+
class Solution {
8+
public int majorityElement(int[] nums) {
9+
Arrays.sort(nums);
10+
return nums[nums.length/2];
11+
}
12+
}
13+
14+
15+
/*
16+
哈希表:使用哈希表存放每个元素的出现次数,遍历哈希表获取出现次数最多的元素
17+
*/
18+
class Solution {
19+
public int majorityElement(int[] nums) {
20+
HashMap<Integer, Integer> map = new HashMap<>();
21+
for (int num : nums) {
22+
int count = map.getOrDefault(num, 0);
23+
map.put(num, ++count);
24+
}
25+
int res = nums[0];
26+
int maxCount = 0;
27+
for (int num : map.keySet()) {
28+
if (map.get(num) > maxCount) {
29+
maxCount = map.get(num);
30+
res = num;
31+
}
32+
}
33+
return res;
34+
}
35+
}
36+
37+
38+
/*
39+
投票:
40+
res表示临时众数,count表示该临时众数拥有的票数
41+
遍历数组,票数为0时,替换上一届的临时众数,将当前元素设为临时众数
42+
计算票数,如果当前元素与临时众数一样,则投赞成票,否则投反对票
43+
由于实际众数人多力量大,最后赞成票最多
44+
*/
45+
class Solution {
46+
public int majorityElement(int[] nums) {
47+
int res = nums[0];
48+
int count = 0;
49+
for (int num : nums) {
50+
if (count == 0) {
51+
res = num;
52+
}
53+
count += num == res ? 1 : -1;
54+
}
55+
return res;
56+
}
57+
}
58+
59+
60+
/*
61+
计数:遍历数组元素,统计该元素出现次数,如果大于一半数组长度,则为众数
62+
*/
63+
class Solution {
64+
public int majorityElement(int[] nums) {
65+
int maxCount = nums.length / 2;
66+
int res = nums[0];
67+
for (int num : nums) {
68+
if (count(nums, num) > maxCount) {
69+
res = num;
70+
break;
71+
}
72+
}
73+
return res;
74+
}
75+
76+
private int count(int[] nums, int num) {
77+
int count = 0;
78+
for (int i = 0; i < nums.length; i++) {
79+
if (nums[i] == num) {
80+
count++;
81+
}
82+
}
83+
return count;
84+
}
85+
}
86+
87+
88+
/*
89+
分治:数组对半拆分成多部分,两两统计比较谁出现次数更多,最后得到出现次数最多的众数
90+
*/
91+
class Solution {
92+
public int majorityElement(int[] nums) {
93+
return majorityElementRec(nums, 0, nums.length - 1);
94+
}
95+
96+
private int majorityElementRec(int[] nums, int low, int high) {
97+
if (low == high) {
98+
return nums[low];
99+
}
100+
int mid = (high - low) / 2 + low;
101+
int left = majorityElementRec(nums, low, mid);
102+
int right = majorityElementRec(nums, mid + 1, high);
103+
if (left == right) {
104+
return left;
105+
}
106+
int leftCount = countInRange(nums, left, low, high);
107+
int rightCount = countInRange(nums, right, low, high);
108+
return leftCount > rightCount ? left : right;
109+
}
110+
111+
private int countInRange(int[] nums, int num, int low, int high) {
112+
int count = 0;
113+
for (int i = low; i <= high; i++) {
114+
if (nums[i] == num) {
115+
count++;
116+
}
117+
}
118+
return count;
119+
}
120+
121+
}

leetcode_Java/Solution0206.java

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// 反转链表
2+
3+
4+
/**
5+
* Definition for singly-linked list.
6+
* public class ListNode {
7+
* int val;
8+
* ListNode next;
9+
* ListNode() {}
10+
* ListNode(int val) { this.val = val; }
11+
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
12+
* }
13+
*/
14+
15+
16+
/*
17+
迭代:使用三个指针分别指向前一个、当前、下一个结点 来定位位置,从头到尾改变链表节点连接的指针方向
18+
*/
19+
class Solution {
20+
public ListNode reverseList(ListNode head) {
21+
ListNode before = null, after;
22+
while (head != null) {
23+
after = head.next;
24+
head.next = before;
25+
before = head;
26+
head = after;
27+
}
28+
return before;
29+
}
30+
}
31+
32+
33+
/*
34+
递归:
35+
1、终止条件:节点为空 或 节点的下一节点为空
36+
2、方法功能:改变指针方向,返回新的头节点
37+
3、递归思路:
38+
1)递归传入下一个节点,目的是为了到达最后一个节点,从尾到头改变链表节点连接的指针方向
39+
2)原先 A → B,改变指针方向,变成 A ← B。 即使B指向A,断开A指向B
40+
3)继续向上一层传递头节点,用于最终返回结果
41+
*/
42+
class Solution {
43+
public ListNode reverseList(ListNode head) {
44+
if (head == null || head.next == null) {
45+
return head;
46+
}
47+
ListNode root = reverseList(head.next);
48+
head.next.next = head;
49+
head.next = null;
50+
return root;
51+
}
52+
}
53+
54+
55+
/*
56+
创建新链表:
57+
1、不改变原链表指针方向,遍历链表节点时,根据节点值创建新的节点,并赋值下一个节点的引用
58+
2、root表示新链表的头指针,新节点创建完成后,root指针指向新节点,继续创建和连接节点
59+
*/
60+
class Solution {
61+
public ListNode reverseList(ListNode head) {
62+
ListNode root = null;
63+
for (; head != null; head = head.next) {
64+
root = new ListNode(head.val, root);
65+
}
66+
return root;
67+
}
68+
}
69+
70+
71+
/*
72+
逻辑同上,使用while替换for
73+
*/
74+
class Solution {
75+
public ListNode reverseList(ListNode head) {
76+
ListNode root = null;
77+
while (head != null) {
78+
root = new ListNode(head.val, root);
79+
head = head.next;
80+
}
81+
return root;
82+
}
83+
}
84+
85+
86+
/*
87+
栈:根据栈后进先出的特点,使用栈存放链表节点,弹出节点时改变节点的下一节点引用
88+
*/
89+
class Solution {
90+
public ListNode reverseList(ListNode head) {
91+
Stack<ListNode> stack = new Stack<>();
92+
ListNode root = new ListNode(0);
93+
ListNode temp = root;
94+
while (head != null) {
95+
stack.push(head);
96+
head = head.next;
97+
}
98+
while (!stack.isEmpty()) {
99+
temp.next = stack.pop();
100+
temp = temp.next;
101+
}
102+
temp.next = null;
103+
return root.next;
104+
}
105+
}
106+
107+
108+
/*
109+
插入:遍历节点,将节点拿出来重新构造新的链表,每次节点都插入到新链表的头部,最终实现反转链表
110+
*/
111+
class Solution {
112+
public ListNode reverseList(ListNode head) {
113+
ListNode root = new ListNode(0);
114+
ListNode temp = head;
115+
while (head != null) {
116+
head = head.next;
117+
temp.next = root.next;
118+
root.next = temp;
119+
temp = head;
120+
}
121+
return root.next;
122+
}
123+
}

leetcode_Java/Solution0234.java

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// 回文链表
2+
3+
4+
/**
5+
* Definition for singly-linked list.
6+
* public class ListNode {
7+
* int val;
8+
* ListNode next;
9+
* ListNode() {}
10+
* ListNode(int val) { this.val = val; }
11+
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
12+
* }
13+
*/
14+
15+
16+
/*
17+
节点值存入列表,双指针从首尾到中间移动判断元素是否对称一样
18+
*/
19+
class Solution {
20+
public boolean isPalindrome(ListNode head) {
21+
List<Integer> list = new ArrayList<>();
22+
while (head != null) {
23+
list.add(head.val);
24+
head = head.next;
25+
}
26+
int l = 0, r = list.size() - 1;
27+
while (l < r) {
28+
if (list.get(l++) != list.get(r--)) {
29+
return false;
30+
}
31+
}
32+
return true;
33+
}
34+
}
35+
36+
37+
/*
38+
递归:
39+
1、通过递归实现在链表上双指针判断首尾元素是否一样
40+
2、使用成员变量作为头部指针,该指针不受递归影响,每次判断完向后移动一步
41+
3、通过递归直接到达链表尾部指针,此时通过首尾指针判断元素是否一样,下一层递归结束后返回上一层,相当于尾部指针往前移动一步
42+
*/
43+
class Solution {
44+
private ListNode left;
45+
46+
public boolean isPalindrome(ListNode head) {
47+
left = head;
48+
return recursivelyCheck(head);
49+
}
50+
51+
private boolean recursivelyCheck(ListNode right) {
52+
if (right == null) {
53+
return true;
54+
}
55+
if (!recursivelyCheck(right.next)) {
56+
return false;
57+
}
58+
if (right.val != left.val) {
59+
return false;
60+
}
61+
left = left.next;
62+
return true;
63+
}
64+
}
65+
66+
67+
/*
68+
快指针走到末尾,慢指针刚好到中间,其中慢指针将前半部分反转,然后从中间到首尾比较
69+
原始:1 → 2 → 3 → 4 → 3 → 2 → 1
70+
反转:1 ← 2 ← 3 ← 4 → 3 → 2 → 1
71+
*/
72+
class Solution {
73+
public boolean isPalindrome(ListNode head) {
74+
if (head == null || head.next == null) {
75+
return true;
76+
}
77+
ListNode slow = head, fast = head, pre = null, temp;
78+
while (fast != null && fast.next != null) {
79+
fast = fast.next.next;
80+
temp = slow.next;
81+
slow.next = pre;
82+
pre = slow;
83+
slow = temp;
84+
}
85+
if (fast != null) {
86+
slow = slow.next;
87+
}
88+
while (pre != null && slow != null) {
89+
if (pre.val != slow.val) {
90+
return false;
91+
}
92+
pre = pre.next;
93+
slow = slow.next;
94+
}
95+
return true;
96+
}
97+
}

0 commit comments

Comments
 (0)