快手
无重复字符的最长子串
java
class Solution {
public int lengthOfLongestSubstring(String s) {
int[] cnt = new int[128];
char[] ch = s.toCharArray();
int left = 0;
int maxL = 0;
for(int right = 0; right < ch.length; right++){
cnt[ch[right]]++;
while(cnt[ch[right]] > 1){
cnt[ch[left]]--;
left++;
}
maxL = Math.max(maxL, right - left + 1);
}
return maxL;
}
}
合并区间
java
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (p, q) -> (p[0] - q[0]));
List<int[]> list = new ArrayList<>();
for(int[] num : intervals){
int m = list.size();
if(m > 0 && list.get(m - 1)[1] >= num[0]){
list.get(m - 1)[1] = Math.max(num[1], list.get(m - 1)[1]);
}else{
list.add(num);
}
}
return list.toArray(new int[list.size()][]);
}
}
数组中的第 K 个最大元素
215. 数组中的第K个最大元素 - 力扣(LeetCode)
java
class Solution {
public int findKthLargest(int[] nums, int k) {
List<Integer> list = new ArrayList<>();
for(int num : nums){
list.add(num);
}
return search(list, k);
}
public int search(List<Integer> list, int k){
int n = list.size();
Random r = new Random();
int pivot = list.get(r.nextInt(n));
List<Integer> small = new ArrayList<>();
List<Integer> equal = new ArrayList<>();
List<Integer> big = new ArrayList<>();
for(int num : list){
if(num < pivot) small.add(num);
else if(num > pivot) big.add(num);
else equal.add(num);
}
if(k <= big.size()){
return search(big, k);
}
if(n - small.size() < k){
return search(small, k - n + small.size());
}
return pivot;
}
}
有效的括号
java
class Solution {
public boolean isValid(String s) {
if(s.length() % 2 != 0) return false;
Map<Character, Character> map = new HashMap<>();
map.put('(', ')');
map.put('{', '}');
map.put('[', ']');
Deque<Character> q = new ArrayDeque<>();
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
if(map.containsKey(c)){
q.push(c);
}else{
if(q.isEmpty() || map.get(q.pop()) != c){
return false;
}
}
}
return q.isEmpty();
}
}
重排链表
java
/**
* 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; }
* }
*/
class Solution {
public void reorderList(ListNode head){
ListNode mid = getMid(head);
ListNode head2 = reverseList(mid.next);
mid.next = null; //找到中间点,断开链表
while(head2 != null){
ListNode tmp1 = head.next;
ListNode tmp2 = head2.next;
head.next = head2;
head2.next = tmp1;
head2 = tmp2;
head = tmp1;
}
}
public ListNode getMid(ListNode node){
ListNode fast = node;
ListNode slow = node;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
public ListNode reverseList(ListNode node){
ListNode pre = null;
while(node != null){
ListNode tmp = node.next;
node.next = pre;
pre = node;
node = tmp;
}
return pre;
}
}
LRU 缓存
java
class LRUCache {
private int capacity;
private Map<Integer, Integer> cache = new LinkedHashMap<>();
public LRUCache(int capacity) {
this.capacity = capacity;
}
public int get(int key) {
Integer value = cache.remove(key);
if(value == null){
return -1;
}
cache.put(key, value);
return value;
}
public void put(int key, int value) {
Integer val = cache.remove(key);
if(val != null){
cache.put(key, value);
return;
}
if(cache.size() == capacity){
Integer index = cache.keySet().iterator().next();
cache.remove(index);
}
cache.put(key, value);
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
最长回文子串
java
class Solution {
private int start = 0, end = 0;
public String longestPalindrome(String s) {
int n = s.length();
if(n < 2) return s;
for(int i = 0; i < n - 1; i++){
reform(s, i, i);
reform(s, i, i + 1);
}
return s.substring(start, end);
}
public void reform(String s, int l, int r){
while(l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)){
l--;
r++;
}
if(r - l - 1 > end - start){
start = l + 1;
end = r;
}
}
}
删除排序链表中的重复元素 II
82. 删除排序链表中的重复元素 II - 力扣(LeetCode)
java
/**
* 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; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode dummy = new ListNode(0, head);
ListNode cur = dummy;
while(cur.next != null && cur.next.next != null){
if(cur.next.val == cur.next.next.val){
int x = cur.next.val;
while(cur.next != null && cur.next.val == x){
cur.next = cur.next.next;
}
}else{
cur = cur.next;
}
}
return dummy.next;
}
}
数组中的第 K 个最大元素
215. 数组中的第K个最大元素 - 力扣(LeetCode)
java
class Solution {
public int findKthLargest(int[] nums, int k) {
List<Integer> list = new ArrayList<>();
for(int num : nums){
list.add(num);
}
return search(list, k);
}
public int search(List<Integer> list, int k){
int n = list.size();
Random r = new Random();
int pivot = list.get(r.nextInt(n));
List<Integer> small = new ArrayList<>();
List<Integer> equal = new ArrayList<>();
List<Integer> big = new ArrayList<>();
for(int num : list){
if(num < pivot) small.add(num);
else if(num > pivot) big.add(num);
else equal.add(num);
}
if(k <= big.size()){
return search(big, k);
}
if(n - small.size() < k){
return search(small, k - n + small.size());
}
return pivot;
}
}
环形链表 II
慢指针的路程:a+x
快指针的路程:a+x+n*环长
快指针速度是慢指针的两倍:相遇时
2(a+x) = a + x + n*环长
a = n* 环长-x
a = 环长-x
所以起点到入口的距离=相遇点到入口的距离
所以再搞一个指针,两个指针同时走,下次相遇就是重复点
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) {
if(head == null || head.next == null) return null;
ListNode slow = head;
ListNode fast = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(slow == fast){
//有环
ListNode cur = head;
while(cur != slow){
cur = cur.next;
slow = slow.next;
}
return cur;
}
}
return null;
}
}
平衡二叉树
java
/**
* Definition for a binary tree node.
* public 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;
* }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
return balance(root) != -1;
}
public int balance(TreeNode node){
if(node == null) return 0;
int leftHeight = balance(node.left);
if(leftHeight == - 1) return -1;
int rightHeight = balance(node.right);
if(rightHeight == -1) return -1;
if(Math.abs(leftHeight - rightHeight) > 1) return -1;
return Math.max(leftHeight, rightHeight) + 1;
}
}
合并 K 个升序链表
java
/**
* 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; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
Queue<ListNode> pq = new PriorityQueue<>((p, q) -> p.val - q.val);
for(ListNode list : lists){
if(list != null){
pq.offer(list);
}
}
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
while(!pq.isEmpty()){
ListNode node = pq.poll();
cur.next = new ListNode(node.val);
cur = cur.next;
if(node.next != null) pq.offer(node.next);
}
return dummy.next;
}
}
最长公共子序列
java
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int n = text1.length();
int m = text2.length();
int[][] dp = new int[n + 1][m + 1];
for(int i = 1; i <= n; i++){
char c1 = text1.charAt(i - 1);
for(int j = 1; j <= m; j++){
char c2 = text2.charAt(j - 1);
if(c1 == c2) dp[i][j] = dp[i - 1][j - 1] + 1;
else dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
return dp[n][m];
}
}
最长递增子序列
java
class Solution {
public int lengthOfLIS(int[] nums) {
int n = nums.length;
int[] dp = new int[n + 1];
Arrays.fill(dp, 1);
int max = 1;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= i; j++){
if(nums[i - 1] > nums[j - 1]){
dp[i] = Math.max(dp[j] + 1, dp[i]);
}
}
max = Math.max(max, dp[i]);
}
return max;
}
}
岛屿数量
java
class Solution {
public int numIslands(char[][] grid) {
int cnt = 0;
for(int i = 0; i < grid.length; i++){
for(int j = 0; j < grid[0].length; j++){
if(grid[i][j] == '1'){
dfs(grid, i, j);
cnt++;
}
}
}
return cnt;
}
public void dfs(char[][] grid, int i, int j){
if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] != '1') return;
grid[i][j] = '2';
dfs(grid, i - 1, j);
dfs(grid, i + 1, j);
dfs(grid, i, j + 1);
dfs(grid, i, j - 1);
}
}
二叉树的层序遍历
java
/**
* Definition for a binary tree node.
* public 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;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
if(root == null) return ans;
Queue<TreeNode> q = new ArrayDeque<>();
q.offer(root);
while(!q.isEmpty()){
List<Integer> list = new ArrayList<>();
for(int i = q.size(); i > 0; i--){
TreeNode node = q.poll();
list.add(node.val);
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
}
ans.add(list);
}
return ans;
}
}
二叉树的右视图
java
/**
* Definition for a binary tree node.
* public 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;
* }
* }
*/
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> ans = new ArrayList<>();
if(root == null) return ans;
Deque<TreeNode> pq = new ArrayDeque<>();
pq.offer(root);
while(!pq.isEmpty()){
int n = pq.size();
for(int i = n; i > 0; i--){
TreeNode node = pq.poll();
if(i == 1) ans.add(node.val);
if(node.left != null) pq.offer(node.left);
if(node.right != null) pq.offer(node.right);
}
}
return ans;
}
}
前序遍历
java
/**
* Definition for a binary tree node.
* public 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;
* }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
dfs(root, ans);
return ans;
}
public void dfs(TreeNode node, List<Integer> ans){
if(node == null) return;
ans.add(node.val);
dfs(node.left, ans);
dfs(node.right, ans);
}
}
盛最多水的容器
java
class Solution {
public int maxArea(int[] height) {
int right = height.length - 1;
int left = 0;
int max = 0;
while(left < right){
int width = right - left;
int minHeight = Math.min(height[left], height[right]);
max = Math.max(max, minHeight * width);
if(height[left] < height[right]){
left++;
}else{
right--;
}
}
return max;
}
}
二叉树的最大深度
java
/**
* Definition for a binary tree node.
* public 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;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
return trace(root);
}
public int trace(TreeNode root){
if(root == null) return 0;
int leftH = trace(root.left);
int rightH = trace(root.right);
return Math.max(leftH, rightH) + 1;
}
}
x 的平方根
java
class Solution {
public int mySqrt(int x) {
if(x < 2) return x;
int l = 1;
int r = x / 2;
int ans = 0;
while(l <= r){
int mid = l + r >>> 1;
if(mid <= x / mid){
ans = mid;
l = mid + 1;
}else{
r = mid - 1;
}
}
return ans;
}
}
最小路径和
java
class Solution {
public int minPathSum(int[][] grid) {
int n = grid.length;
int m = grid[0].length;
int[][] dp = new int[n][m];
dp[0][0] = grid[0][0];
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(i == 0 && j == 0) continue;
else if(i == 0 && j != 0) dp[i][j] = dp[i][j - 1] + grid[i][j];
else if(j == 0 && i != 0) dp[i][j] = dp[i - 1][j] + grid[i][j];
else dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
}
}
return dp[n - 1][m - 1];
}
}
比较版本号
java
class Solution {
public int compareVersion(String version1, String version2) {
int n = version1.length();
int m = version2.length();
int i = 0;
int j = 0;
while(i < n || j < m){
int num1 = 0;
while(i < n && version1.charAt(i) != '.'){
num1 = num1 * 10 + version1.charAt(i) - '0';
i++;
}
int num2 = 0;
while(j < m && version2.charAt(j) != '.'){
num2 = num2 * 10 + version2.charAt(j) - '0';
j++;
}
if(num1 < num2){
return -1;
}else if(num1 > num2){
return 1;
}
//跳过.
i++;
j++;
}
return 0;
}
}
反转链表 II
java
/**
* 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; }
* }
*/
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode pre = dummy;
for(int i = 1; i < left; i++){
pre = pre.next;
}
ListNode start = pre.next;
ListNode end = start;
for(int i = left; i < right; i++){
end = end.next;
}
ListNode afterRight = end.next;
end.next = null;
pre.next = reverse(start);
start.next = afterRight;
return dummy.next;
}
public ListNode reverse(ListNode head){
ListNode pre = null;
while(head != null){
ListNode tmp = head.next;
head.next = pre;
pre = head;
head = tmp;
}
return pre;
}
}
三数之和
java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums);
for(int i = 0; i < n - 2; i++){
if(i > 0 && nums[i] == nums[i - 1]) continue; //如果一样跳过
if(nums[i] + nums[i + 1] + nums[i + 2] > 0) break;
if(nums[i] + nums[n - 2] + nums[n - 1] < 0) continue;
int l = i + 1;
int r = n - 1;
while(l < r){
if(nums[i] + nums[l] + nums[r] > 0){
r--;
}else if(nums[i] + nums[l] + nums[r] < 0){
l++;
}else{
ans.add(List.of(nums[i], nums[l], nums[r]));
for(l++; l < r && nums[l] == nums[l - 1]; l++);
for(r--; l < r && nums[r] == nums[r + 1]; r--);
}
}
}
return ans;
}
}
合并两个升序链表
java
/**
* 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; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
while(list1 != null && list2 != null){
if(list1.val <= list2.val){
cur.next = new ListNode(list1.val);
list1 = list1.next;
}else{
cur.next = new ListNode(list2.val);
list2 = list2.next;
}
cur = cur.next;
}
if(list1 != null){
cur.next = list1;
}
if(list2 != null){
cur.next = list2;
}
return dummy.next;
}
}
买卖股票的最佳时机
java
class Solution {
public int maxProfit(int[] prices) {
int minPrice = prices[0]; //表示迄今为止,最低价格
int maxPrice = 0; //表示迄今为止,最大价格
int cur;
int profit = 0;
for(int i = 0; i < prices.length; i++){
cur = prices[i];
maxPrice = Math.max(maxPrice, cur);
minPrice = Math.min(minPrice, cur);
profit = Math.max(cur - minPrice, profit);
}
return Math.max(0, profit);
}
}
最大子数组和
java
class Solution {
public int maxSubArray(int[] nums) {
int cur = nums[0];
int max = nums[0];
for(int i = 1; i < nums.length; i++){
cur = Math.max(cur + nums[i], nums[i]);
max = Math.max(max, cur);
}
return max;
}
}
爬楼梯
java
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i <= n; i++){
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
字符串转换为整数(atoi)
8. 字符串转换整数 (atoi) - 力扣(LeetCode)
java
class Solution {
public int myAtoi(String s) {
if(s == null || s.isEmpty()) return 0;
int n = s.length();
int index = 0;
while(index < n && s.charAt(index) == ' ') index++;
if(index == n) return 0;
int sign = 1;
if(s.charAt(index) == '+' || s.charAt(index) == '-'){
sign = s.charAt(index) == '+' ? 1 : -1;
index++;
}
int res = 0;
while(index < n){
char cur = s.charAt(index);
if(cur < '0' || cur > '9') break;
int digit = cur - '0';
if(res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && digit > Integer.MAX_VALUE % 10)){
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
res = res * 10 + digit;
index++;
}
return res * sign;
}
}