学习精要:路线-思想-组件
算法思想:容器-算法-容器
public class ListToString {public static void main(String[] args) {List integers = new ArrayList<>();String str="";for(int item=0;itemstr+=integers.get(item);}}
}
public class floatToString {public static void main(String[] args) {String str="123456";for(int i=0;iint num = str.charAt(i)-'0';}}
}
class Solution {public int search(int[] nums, int target) {int left = 0, right = nums.length - 1;while (left <= right) {int mid = (right - left) / 2 + left;int num = nums[mid];if (num == target) {return mid;} else if (num > target) {right = mid - 1;} else {left = mid + 1;}}return -1;}
}
class Solution {public int removeElement(int[] nums, int val) {int n = nums.length;int left = 0;for (int right = 0; right < n; right++) {if (nums[right] != val) {nums[left] = nums[right];left++;}}return left;}
}
class Solution {public int[] sortedSquares(int[] nums) {int[] ans = new int[nums.length];for (int i = 0; i < nums.length; ++i) {ans[i] = nums[i] * nums[i];}Arrays.sort(ans);return ans;}
}
class Solution {public int[][] generateMatrix(int n) {int maxNum = n * n;int curNum = 1;int[][] matrix = new int[n][n];int row = 0, column = 0;int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 右下左上int directionIndex = 0;while (curNum <= maxNum) {matrix[row][column] = curNum;curNum++;int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];if (nextRow < 0 || nextRow >= n || nextColumn < 0 || nextColumn >= n || matrix[nextRow][nextColumn] != 0) {directionIndex = (directionIndex + 1) % 4; // 顺时针旋转至下一个方向}row = row + directions[directionIndex][0];column = column + directions[directionIndex][1];}return matrix;}
}
class Solution {public ListNode removeElements(ListNode head, int val) {if (head == null) {return head;}head.next = removeElements(head.next, val);return head.val == val ? head.next : head;}
}
//时间复杂度:o(n),空间复杂度O(n)
设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。
在链表类中实现这些功能:
get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末 尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
//单链表
class ListNode {int val;ListNode next;public ListNode(int val) {this.val = val;}
}class MyLinkedList {int size;ListNode head;public MyLinkedList() {size = 0;head = new ListNode(0);}public int get(int index) {if (index < 0 || index >= size) {return -1;}ListNode cur = head;for (int i = 0; i <= index; i++) {cur = cur.next;}return cur.val;}public void addAtHead(int val) {addAtIndex(0, val);}public void addAtTail(int val) {addAtIndex(size, val);}public void addAtIndex(int index, int val) {if (index > size) {return;}index = Math.max(0, index);size++;ListNode pred = head;for (int i = 0; i < index; i++) {pred = pred.next;}ListNode toAdd = new ListNode(val);toAdd.next = pred.next;pred.next = toAdd;}public void deleteAtIndex(int index) {if (index < 0 || index >= size) {return;}size--;ListNode pred = head;for (int i = 0; i < index; i++) {pred = pred.next;}pred.next = pred.next.next;}
}
class MyLinkedList {int size;ListNode head;ListNode tail;public MyLinkedList() {size = 0;head = new ListNode(0);tail = new ListNode(0);head.next = tail;tail.prev = head;}public int get(int index) {if (index < 0 || index >= size) {return -1;}ListNode curr;if (index + 1 < size - index) {curr = head;for (int i = 0; i <= index; i++) {curr = curr.next;}} else {curr = tail;for (int i = 0; i < size - index; i++) {curr = curr.prev;}}return curr.val;}public void addAtHead(int val) {addAtIndex(0, val);}public void addAtTail(int val) {addAtIndex(size, val);}public void addAtIndex(int index, int val) {if (index > size) {return;}index = Math.max(0, index);ListNode pred, succ;if (index < size - index) {pred = head;for (int i = 0; i < index; i++) {pred = pred.next;}succ = pred.next;} else {succ = tail;for (int i = 0; i < size - index; i++) {succ = succ.prev;}pred = succ.prev;}size++;ListNode toAdd = new ListNode(val);toAdd.prev = pred;toAdd.next = succ;pred.next = toAdd;succ.prev = toAdd;}public void deleteAtIndex(int index) {if (index < 0 || index >= size) {return;}ListNode pred, succ;if (index < size - index) {pred = head;for (int i = 0; i < index; i++) {pred = pred.next;}succ = pred.next.next;} else {succ = tail;for (int i = 0; i < size - index - 1; i++) {succ = succ.prev;}pred = succ.prev.prev;}size--;pred.next = succ;succ.prev = pred;}
}class ListNode {int val;ListNode next;ListNode prev;public ListNode(int val) {this.val = val;}
}
class Solution {public ListNode swapPairs(ListNode head) {if (head == null || head.next == null) {return head;}ListNode newHead = head.next;head.next = swapPairs(newHead.next);newHead.next = head;return newHead;}
}
class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0, head);int length = getLength(head);ListNode cur = dummy;for (int i = 1; i < length - n + 1; ++i) {cur = cur.next;}cur.next = cur.next.next;ListNode ans = dummy.next;return ans;}public int getLength(ListNode head) {int length = 0;while (head != null) {++length;head = head.next;}return length;}
}
//时间复杂度:o(L),空间复杂度o(1)
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {Set visited = new HashSet();ListNode temp = headA;while (temp != null) {visited.add(temp);temp = temp.next;}temp = headB;while (temp != null) {if (visited.contains(temp)) {return temp;}temp = temp.next;}return null;}
}
public class Solution {public ListNode detectCycle(ListNode head) {ListNode pos = head;Set visited = new HashSet();while (pos != null) {if (visited.contains(pos)) {return pos;} else {visited.add(pos);}pos = pos.next;}return null;}
}
class Solution {public boolean isAnagram(String s, String t) {if (s.length() != t.length()) {return false;}char[] str1 = s.toCharArray();char[] str2 = t.toCharArray();Arrays.sort(str1);Arrays.sort(str2);return Arrays.equals(str1, str2);}
}
class Solution {public int[] intersection(int[] nums1, int[] nums2) {Set set1= new HashSet();Set set2= new HashSet();for(int i:nums1){set1.add(i);}for(int i:nums2){if(set1.contains(i)){set2.add(i);}}return set2.stream().mapToInt(x->x).toArray(); }
}
class Solution {private int getNext(int n) {int totalSum = 0;while (n > 0) {int d = n % 10;n = n / 10;totalSum += d * d;}return totalSum;}public boolean isHappy(int n) {Set seen = new HashSet<>();while (n != 1 && !seen.contains(n)) {seen.add(n);n = getNext(n);}return n == 1;}
}
class Solution {public int[] twoSum(int[] nums, int target) {Map hashtable = new HashMap();for (int i = 0; i < nums.length; ++i) {if (hashtable.containsKey(target - nums[i])) {return new int[]{hashtable.get(target - nums[i]), i};}hashtable.put(nums[i], i);}return new int[0];}
}
class Solution {public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {Map countAB = new HashMap();for (int u : A) {for (int v : B) {countAB.put(u + v, countAB.getOrDefault(u + v, 0) + 1);}}int ans = 0;for (int u : C) {for (int v : D) {if (countAB.containsKey(-u - v)) {ans += countAB.get(-u - v);}}}return ans;}
}
class Solution {public boolean canConstruct(String ransomNote, String magazine) {if (ransomNote.length() > magazine.length()) {return false;}int[] cnt = new int[26];for (char c : magazine.toCharArray()) {cnt[c - 'a']++;}for (char c : ransomNote.toCharArray()) {cnt[c - 'a']--;if(cnt[c - 'a'] < 0) {return false;}}return true;}
}
class Solution {public List> threeSum(int[] nums) {int n = nums.length;Arrays.sort(nums);List> ans = new ArrayList>();// 枚举 afor (int first = 0; first < n; ++first) {// 需要和上一次枚举的数不相同if (first > 0 && nums[first] == nums[first - 1]) {continue;}// c 对应的指针初始指向数组的最右端int third = n - 1;int target = -nums[first];// 枚举 bfor (int second = first + 1; second < n; ++second) {// 需要和上一次枚举的数不相同if (second > first + 1 && nums[second] == nums[second - 1]) {continue;}// 需要保证 b 的指针在 c 的指针的左侧while (second < third && nums[second] + nums[third] > target) {--third;}// 如果指针重合,随着 b 后续的增加// 就不会有满足 a+b+c=0 并且 bbreak;}if (nums[second] + nums[third] == target) {List list = new ArrayList();list.add(nums[first]);list.add(nums[second]);list.add(nums[third]);ans.add(list);}}}return ans;}
}
class Solution {public List> fourSum(int[] nums, int target) {List> quadruplets = new ArrayList>();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 ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {break;}if ((long) 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 ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {break;}if ((long) nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {continue;}int left = j + 1, right = length - 1;while (left < right) {long sum = (long) 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;}
}
class Solution {public void reverseString(char[] s) {int n = s.length;for (int left = 0, right = n - 1; left < right; ++left, --right) {char tmp = s[left];s[left] = s[right];s[right] = tmp;}}
}
class Solution {public String reverseStr(String s, int k) {int n = s.length();char[] arr = s.toCharArray();for (int i = 0; i < n; i += 2 * k) {reverse(arr, i, Math.min(i + k, n) - 1);}return new String(arr);}public void reverse(char[] arr, int left, int right) {while (left < right) {char temp = arr[left];arr[left] = arr[right];arr[right] = temp;left++;right--;}}
}
class Solution {public String replaceSpace(String s) {int length = s.length();char[] array = new char[length * 3];int size = 0;for (int i = 0; i < length; i++) {char c = s.charAt(i);if (c == ' ') {array[size++] = '%';array[size++] = '2';array[size++] = '0';} else {array[size++] = c;}}String newStr = new String(array, 0, size);return newStr;}
}
class Solution {public String reverseWords(String s) {// 除去开头和末尾的空白字符s = s.trim();// 正则匹配连续的空白字符作为分隔符分割List wordList = Arrays.asList(s.split("\\s+"));Collections.reverse(wordList);return String.join(" ", wordList);}
}
class Solution {public String reverseLeftWords(String s, int n) {return s.substring(n, s.length()) + s.substring(0, n);}
}
//KMP算法
class Solution {public int strStr(String haystack, String needle) {int n = haystack.length(), m = needle.length();if (m == 0) {return 0;}int[] pi = new int[m];for (int i = 1, j = 0; i < m; i++) {while (j > 0 && needle.charAt(i) != needle.charAt(j)) {j = pi[j - 1];}if (needle.charAt(i) == needle.charAt(j)) {j++;}pi[i] = j;}for (int i = 0, j = 0; i < n; i++) {while (j > 0 && haystack.charAt(i) != needle.charAt(j)) {j = pi[j - 1];}if (haystack.charAt(i) == needle.charAt(j)) {j++;}if (j == m) {return i - m + 1;}}return -1;}
}
class Solution {public boolean repeatedSubstringPattern(String s) {return (s + s).indexOf(s, 1) != s.length();}
}
class Solution {public int removeElement(int[] nums, int val) {int n = nums.length;int left = 0;for (int right = 0; right < n; right++) {if (nums[right] != val) {nums[left] = nums[right];left++;}}return left;}
}
class Solution {public void reverseString(char[] s) {int n = s.length;for (int left = 0, right = n - 1; left < right; ++left, --right) {char tmp = s[left];s[left] = s[right];s[right] = tmp;}}
}
class Solution {public String replaceSpace(String s) {int length = s.length();char[] array = new char[length * 3];int size = 0;for (int i = 0; i < length; i++) {char c = s.charAt(i);if (c == ' ') {array[size++] = '%';array[size++] = '2';array[size++] = '0';} else {array[size++] = c;}}String newStr = new String(array, 0, size);return newStr;}
}
class Solution {public String reverseWords(String s) {// 除去开头和末尾的空白字符s = s.trim();// 正则匹配连续的空白字符作为分隔符分割List wordList = Arrays.asList(s.split("\\s+"));Collections.reverse(wordList);return String.join(" ", wordList);}
}
class Solution {public ListNode reverseList(ListNode head) {ListNode prev = null;ListNode curr = head;while (curr != null) {ListNode next = curr.next;curr.next = prev;prev = curr;curr = next;}return prev;}
}
class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0, head);int length = getLength(head);ListNode cur = dummy;for (int i = 1; i < length - n + 1; ++i) {cur = cur.next;}cur.next = cur.next.next;ListNode ans = dummy.next;return ans;}public int getLength(ListNode head) {int length = 0;while (head != null) {++length;head = head.next;}return length;}
}
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {Set visited = new HashSet();ListNode temp = headA;while (temp != null) {visited.add(temp);temp = temp.next;}temp = headB;while (temp != null) {if (visited.contains(temp)) {return temp;}temp = temp.next;}return null;}
}
public class Solution {public ListNode detectCycle(ListNode head) {ListNode pos = head;Set visited = new HashSet();while (pos != null) {if (visited.contains(pos)) {return pos;} else {visited.add(pos);}pos = pos.next;}return null;}
}
class Solution {public List> threeSum(int[] nums) {int n = nums.length;Arrays.sort(nums);List> ans = new ArrayList>();// 枚举 afor (int first = 0; first < n; ++first) {// 需要和上一次枚举的数不相同if (first > 0 && nums[first] == nums[first - 1]) {continue;}// c 对应的指针初始指向数组的最右端int third = n - 1;int target = -nums[first];// 枚举 bfor (int second = first + 1; second < n; ++second) {// 需要和上一次枚举的数不相同if (second > first + 1 && nums[second] == nums[second - 1]) {continue;}// 需要保证 b 的指针在 c 的指针的左侧while (second < third && nums[second] + nums[third] > target) {--third;}// 如果指针重合,随着 b 后续的增加// 就不会有满足 a+b+c=0 并且 bbreak;}if (nums[second] + nums[third] == target) {List list = new ArrayList();list.add(nums[first]);list.add(nums[second]);list.add(nums[third]);ans.add(list);}}}return ans;}
}
class Solution {public List> fourSum(int[] nums, int target) {List> quadruplets = new ArrayList>();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 ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {break;}if ((long) 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 ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {break;}if ((long) nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {continue;}int left = j + 1, right = length - 1;while (left < right) {long sum = (long) 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;}
}
class MyQueue {Deque inStack;Deque outStack;public MyQueue() {inStack = new ArrayDeque();outStack = new ArrayDeque();}public void push(int x) {inStack.push(x);}public int pop() {if (outStack.isEmpty()) {in2out();}return outStack.pop();}public int peek() {if (outStack.isEmpty()) {in2out();}return outStack.peek();}public boolean empty() {return inStack.isEmpty() && outStack.isEmpty();}private void in2out() {while (!inStack.isEmpty()) {outStack.push(inStack.pop());}}
}
class MyStack {Queue queue1;Queue queue2;/** Initialize your data structure here. */public MyStack() {queue1 = new LinkedList();queue2 = new LinkedList();}/** Push element x onto stack. */public void push(int x) {queue2.offer(x);while (!queue1.isEmpty()) {queue2.offer(queue1.poll());}Queue temp = queue1;queue1 = queue2;queue2 = temp;}/** Removes the element on top of the stack and returns that element. */public int pop() {return queue1.poll();}/** Get the top element. */public int top() {return queue1.peek();}/** Returns whether the stack is empty. */public boolean empty() {return queue1.isEmpty();}
}
class Solution {public boolean isValid(String s) {int n = s.length();if (n % 2 == 1) {return false;}Map pairs = new HashMap() {{put(')', '(');put(']', '[');put('}', '{');}};Deque stack = new LinkedList();for (int i = 0; i < n; i++) {char ch = s.charAt(i);if (pairs.containsKey(ch)) {if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {return false;}stack.pop();} else {stack.push(ch);}}return stack.isEmpty();}
}
//时间复杂度o(n),空间复杂度o(n+|E|),E表示字符集
class Solution {public String removeDuplicates(String s) {StringBuffer stack = new StringBuffer();int top = -1;for (int i = 0; i < s.length(); ++i) {char ch = s.charAt(i);if (top >= 0 && stack.charAt(top) == ch) {stack.deleteCharAt(top);--top;} else {stack.append(ch);++top;}}return stack.toString();}
}
class Solution {public int evalRPN(String[] tokens) {Deque stack = new LinkedList();int n = tokens.length;for (int i = 0; i < n; i++) {String token = tokens[i];if (isNumber(token)) {stack.push(Integer.parseInt(token));} else {int num2 = stack.pop();int num1 = stack.pop();switch (token) {case "+":stack.push(num1 + num2);break;case "-":stack.push(num1 - num2);break;case "*":stack.push(num1 * num2);break;case "/":stack.push(num1 / num2);break;default:}}}return stack.pop();}public boolean isNumber(String token) {return !("+".equals(token) || "-".equals(token) || "*".equals(token) || "/".equals(token));}
}
//时间复杂度o(n),空间复杂度o(n)
class Solution {public int[] maxSlidingWindow(int[] nums, int k) {int n = nums.length;PriorityQueue pq = new PriorityQueue(new Comparator() {public int compare(int[] pair1, int[] pair2) {return pair1[0] != pair2[0] ? pair2[0] - pair1[0] : pair2[1] - pair1[1];}});for (int i = 0; i < k; ++i) {pq.offer(new int[]{nums[i], i});}int[] ans = new int[n - k + 1];ans[0] = pq.peek()[0];for (int i = k; i < n; ++i) {pq.offer(new int[]{nums[i], i});while (pq.peek()[1] <= i - k) {pq.poll();}ans[i - k + 1] = pq.peek()[0];}return ans;}
}
//时间复杂度:o(nlogn),空间复杂度o(n)
class Solution {public int[] topKFrequent(int[] nums, int k) {Map occurrences = new HashMap();for (int num : nums) {occurrences.put(num, occurrences.getOrDefault(num, 0) + 1);}// int[] 的第一个元素代表数组的值,第二个元素代表了该值出现的次数PriorityQueue queue = new PriorityQueue(new Comparator() {public int compare(int[] m, int[] n) {return m[1] - n[1];}});for (Map.Entry entry : occurrences.entrySet()) {int num = entry.getKey(), count = entry.getValue();if (queue.size() == k) {if (queue.peek()[1] < count) {queue.poll();queue.offer(new int[]{num, count});}} else {queue.offer(new int[]{num, count});}}int[] ret = new int[k];for (int i = 0; i < k; ++i) {ret[i] = queue.poll()[0];}return ret;}
}
//时间复杂度:o(nlogn),空间复杂度o(n)
class Solution {List temp = new ArrayList();List> ans = new ArrayList>();public List> combine(int n, int k) {dfs(1, n, k);return ans;}public void dfs(int cur, int n, int k) {// 剪枝:temp 长度加上区间 [cur, n] 的长度小于 k,不可能构造出长度为 k 的 tempif (temp.size() + (n - cur + 1) < k) {return;}// 记录合法的答案if (temp.size() == k) {ans.add(new ArrayList(temp));return;}// 考虑选择当前位置temp.add(cur);dfs(cur + 1, n, k);temp.remove(temp.size() - 1);// 考虑不选择当前位置dfs(cur + 1, n, k);}
}
class Solution {List temp = new ArrayList();List> ans = new ArrayList>();public List> combine(int n, int k) {Scanner scanner= new Scanner(System.in);int[] nums= new int[n+1]; for(int i=1;i<=n;i++){nums[i]=i;}dfs(nums,1, n, k);return ans;}public void dfs(int[] nums,int cur, int n, int k) {// 剪枝:temp 长度加上区间 [cur, n] 的长度小于 k,不可能构造出长度为 k 的 tempif (temp.size() + (n - cur + 1) < k) {return;}// 记录合法的答案if (temp.size() == k) {ans.add(new ArrayList(temp));return;}// 考虑选择当前位置temp.add(nums[cur]);dfs(nums,cur + 1, n, k);temp.remove(temp.size() - 1);// 考虑不选择当前位置dfs(nums,cur + 1, n, k);}
}
class Solution {boolean[] vis;public List> permuteUnique(int[] nums) {List> ans = new ArrayList>();List perm = new ArrayList();vis = new boolean[nums.length];Arrays.sort(nums);backtrack(nums, ans, 0, perm);return ans;}public void backtrack(int[] nums, List> ans, int idx, List perm) {if (idx == nums.length) {ans.add(new ArrayList(perm));return;}for (int i = 0; i < nums.length; ++i) {if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {continue;}perm.add(nums[i]);vis[i] = true;backtrack(nums, ans, idx + 1, perm);vis[i] = false;perm.remove(idx);}}
}
(无题)