大二学生,暑假无事,记录LeetCode上的经典算法题以供日后复习
题目来源:力扣(LeetCode)
数组 & 链表
1. 反转链表
- 题解:大神的代码
- 我的Java代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode curr = head;
ListNode prev = null;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextNode;
}
return prev;
}
}
2. 两两交换链表中的节点
- 题解:大神的代码
- 我的Java代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode prev = new ListNode(0);
prev.next = head;
ListNode temp = prev;
while (temp.next != null && temp.next.next != null) {
ListNode left = temp.next;
ListNode right = left.next;
temp.next = right;
left.next = right.next;
right.next = left;
temp = left;
}
return prev.next;
}
}
3. 环形链表
- 题解:大神的代码
- 我的Java代码:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast = head, slow = head;
while (fast != null && slow != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) return true;
}
return false;
}
}
4. 环形链表 II
- 题解:大神的代码
- 我的Java代码:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
HashSet<ListNode> hashSet = new HashSet<>();
ListNode curr = head;
while (curr != null) {
if (hashSet.contains(curr)) return curr;
hashSet.add(curr);
curr = curr.next;
}
return null;
}
}
5. K 个一组翻转链表
- 题解:大神的代码
- 我的Java代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
int i = k;
ListNode curr = head;
ListNode[] stack = new ListNode[k];
while (k > 0) {
stack[i - k] = curr;
if (curr != null) curr = curr.next;
else return head;
k--;
}
while (k < i - 1) {
k++;
stack[i - k].next = stack[i - k - 1];
}
stack[0].next = reverseKGroup(curr, k + 1);
return stack[i - 1];
}
}
栈 & 队列
6. 比较含退格的字符串
- 我的Java代码:
class Solution {
public boolean backspaceCompare(String S, String T) {
Stack<Character> s = new Stack<>();
Stack<Character> t = new Stack<>();
for (int i = 0; i < S.length(); i++) {
if (S.charAt(i) != '#') s.push(S.charAt(i));
else if (!s.isEmpty()) s.pop();
}
for (int i = 0; i < T.length(); i++) {
if (T.charAt(i) != '#') t.push(T.charAt(i));
else if (!t.isEmpty()) t.pop();
}
if (s.size() != t.size()) return false;
for (int i = 0; i < s.size(); i++)
if (s.pop() != t.pop()) return false;
return true;
}
}
7. 有效的括号
- 题解:大神的代码
- 我的Java代码:
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
HashMap<Character, Character> hm = new HashMap<>();
hm.put(')', '(');
hm.put(']', '[');
hm.put('}', '{');
int n = s.length();
for (int i = 0; i < n; i++) {
if (!hm.containsKey(s.charAt(i)))
stack.push(s.charAt(i));
else if (stack.isEmpty() || stack.pop() != hm.get(s.charAt(i)))
return false;
}
return stack.isEmpty();
}
}
8. 用栈实现队列
- 题解:大神的代码
- 我的Java代码:
class MyQueue {
Stack<Integer> inputStack;
Stack<Integer> outputStack;
/**
* Initialize your data structure here.
*/
public MyQueue() {
inputStack = new Stack<>();
outputStack = new Stack<>();
}
/**
* Push element x to the back of queue.
*/
public void push(int x) {
inputStack.push(x);
}
/**
* Removes the element from in front of queue and returns that element.
*/
public int pop() {
convert();
return outputStack.pop();
}
/**
* Get the front element.
*/
public int peek() {
convert();
return outputStack.peek();
}
/**
* Returns whether the queue is empty.
*/
public boolean empty() {
return inputStack.isEmpty() && outputStack.isEmpty();
}
public void convert() {
if (outputStack.isEmpty())
while (!inputStack.isEmpty())
outputStack.push(inputStack.pop());
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
9. 用队列实现栈
- 题解:大神的代码
- 我的Java代码:
import java.util.concurrent.LinkedBlockingQueue;
class MyStack {
Queue<Integer> queue;
/**
* Initialize your data structure here.
*/
public MyStack() {
queue = new LinkedBlockingQueue<>();
}
/**
* Push element x onto stack.
*/
public void push(int x) {
queue.add(x);
int n = queue.size();
while (n > 1) {
queue.add(queue.remove());
n--;
}
}
/**
* Removes the element on top of the stack and returns that element.
*/
public int pop() {
return queue.remove();
}
/**
* Get the top element.
*/
public int top() {
return queue.peek();
}
/**
* Returns whether the stack is empty.
*/
public boolean empty() {
return queue.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
优先队列
10. 数据流中的第K大元素
- 我的Java代码:
class KthLargest {
PriorityQueue<Integer> q;
int k;
public KthLargest(int k, int[] nums) {
this.k = k;
q = new PriorityQueue<>(k);
for (int n : nums)
add(n);
}
public int add(int val) {
if (q.size() < k)
q.offer(val);
else if (q.peek() < val) {
q.poll();
q.offer(val);
}
return q.peek();
}
}
/**
* Your KthLargest object will be instantiated and called as such:
* KthLargest obj = new KthLargest(k, nums);
* int param_1 = obj.add(val);
*/
11. 滑动窗口最大值
- 题解:大神的代码
- 我的Java代码:
class Solution {
ArrayDeque<Integer> deq = new ArrayDeque<Integer>();
int[] nums;
public void clean_deque(int i, int k) {
// remove indexes of elements not from sliding window
if (!deq.isEmpty() && deq.getFirst() == i - k)
deq.removeFirst();
// remove from deq indexes of all elements
// which are smaller than current element nums[i]
while (!deq.isEmpty() && nums[i] > nums[deq.getLast()])
deq.removeLast();
}
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
if (n * k == 0) return new int[0];
if (k == 1) return nums;
// init deque and output
this.nums = nums;
int max_idx = 0;
for (int i = 0; i < k; i++) {
clean_deque(i, k);
deq.addLast(i);
// compute max in nums[:k]
if (nums[i] > nums[max_idx]) max_idx = i;
}
int[] output = new int[n - k + 1];
output[0] = nums[max_idx];
// build output
for (int i = k; i < n; i++) {
clean_deque(i, k);
deq.addLast(i);
output[i - k + 1] = nums[deq.getFirst()];
}
return output;
}
}
映射 & 集合
12. 有效的字母异位词
- 题解:大神的代码
- 我的Java代码:
class Solution {
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) {
return false;
}
int[] counter = new int[26];
for (int i = 0; i < s.length(); i++) {
counter[s.charAt(i) - 'a']++;
counter[t.charAt(i) - 'a']--;
}
for (int count : counter) {
if (count != 0) {
return false;
}
}
return true;
}
}
13. 两数之和
- 题解:大神的代码
- 我的Java代码:
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int needNum = target - nums[i];
if (map.containsKey(needNum))
return new int[]{map.get(needNum), i};
map.put(nums[i], i);
}
throw new IllegalArgumentException("no solution");
}
}
14. 三数之和
- 题解:大神的代码
- 我的Java代码:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int len = nums.length;
List<List<Integer>> ans = new ArrayList<>();
if (nums == null || len < 3) return ans;
Arrays.sort(nums);// sort the array
for (int i = 0; i < len; i++) {
// if the current number is greater than 0, the sum of the three must be greater than 0, so end the loop
if (nums[i] > 0) break;
if (i > 0 && nums[i] == nums[i - 1]) continue;// get rid of duplicate
int left = i + 1;
int right = len - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
ans.add(Arrays.asList(nums[i], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) left++;// get rid of duplicate
while (left < right && nums[right] == nums[right - 1]) right--;// get rid of duplicate
left++;
right--;
} else if (sum < 0) left++;
else right--;
}
}
return ans;
}
}
15. 四数之和
- 我的Java代码:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new LinkedList<>();
int len = nums.length;
if (nums == null || len < 4) return ans;
Arrays.sort(nums);
for (int i = 0; i < len - 3; i++) {
if (nums[i] > 0 && nums[i] > target) break;
for (int j = i + 1; j < len - 2; j++) {
int left = j + 1;
int right = len - 1;
while (left < right) {
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum == target) {
if (!ans.contains(Arrays.asList(nums[i], nums[j], nums[left], nums[right])))
ans.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
} else if (sum < target) left++;
else right--;
}
}
}
return ans;
}
}
树 & 二叉树 & 二叉搜索树
16. 验证二叉搜索树
- 题解:大神的代码