前言
每天刷一刷,5050发。
LeetCode Top Interview Questions(101 - 145)
101 Basic Calculator II
实现 + - * /计算
Example 1:
Input: "3+2*2"
Output: 7
Example 2:
Input: " 3/2 "
Output: 1
Example 3:
Input: " 3+5 / 2 "
Output: 5
class Solution {
public int calculate(String s) {
if(s == null || s.isEmpty())return -1;
int sum = 0, cur = 0, pre = 0;
char sign = '+';
char []chars = s.toCharArray();
for(int i = 0; i <= chars.length; i ++) {
if(i < chars.length && chars[i] == ' ')continue;
if(i < chars.length && Character.isDigit(chars[i])) {
cur = cur * 10 + (chars[i] - '0');
continue;
}
if(sign == '+') {
sum += cur;
pre = cur;
} else if(sign == '-') {
sum -= cur;
pre = -cur;
} else if(sign == '*') {
sum = sum - pre + pre * cur;
pre = pre * cur;
} else if(sign == '/') {
sum = sum - pre + pre / cur;
pre = pre / cur;
}
if(i < chars.length) {
sign = chars[i];
}
cur = 0;
}
return sum;
}
}
102 Kth Smallest Element in a BST
返回二叉搜索树的第k小的数
Example 1:
Input: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
Output: 1
思路:使用非递归的中序排序,到第k个时返回
class Solution {
public int kthSmallest(TreeNode root, int k) {
if(root == null)return -1;
Stack<TreeNode> stack = new Stack<>();
while(root != null || !stack.isEmpty()) {
while(root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
if(--k == 0)
return root.val;
root = root.right;
}
return -1;
}
}
103 Palindrome Linked List
判断一个链表是不是回文的
Example 1:
Input: 1->2
Output: false
Example 2:
Input: 1->2->2->1
Output: true
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) return true;
ListNode pre = null;
ListNode walker = head;
ListNode runner = head;
while (runner != null && runner.next != null) {
runner = runner.next.next;
//翻转链表
ListNode walkerNext = walker.next;
walker.next = pre;
pre = walker;
walker = walkerNext;
}
//说明为奇数个
if (runner != null) {
walker = walker.next;
}
while (pre != null) {
if (walker.val != pre.val)
return false;
walker = walker.next;
pre = pre.next;
}
return true;
}
}
104 Lowest Common Ancestor of a Binary Tree
给定二叉树,找到最低的共同祖先
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.
Lowest Common Ancestor of a Binary Tree
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//第一步:找到两个节点 并返回
if(root == null || p == root || q == root)return root;
//如果当前节点不是要找的
//进行左右子树查找
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
//如果左右子树都包含有目标节点,则当前节点就是交汇节点
if(left != null && right != null)return root;
//如果左右子树只找到一个,说明两个节点在同一边,则返回最先找到都节点即可
//因为是自上往下找的
//符合第二例子,返回其中之一
return left == null ? right : left;
}
}
105 Delete Node in a Linked List
编写一个函数以删除单链接列表中的节点(尾部除外),仅授予对该节点的访问权限。
Example 1:
Input: head = [4,5,1,9], node = 5
Output: [4,1,9]
Explanation: You are given the second node with value 5, the linked list should become 4 -> 1 -> 9 after calling your function.
//第一个问题,删除节点一定要有它的前置节点吗?
//答案是必须的,但是题目没提供,我们需要自己去创建出来
//只需要把上一个节点的值给到要删除的节点的值,把上一个节点删除即可
class Solution {
public void deleteNode(ListNode node) {
if(node.next == null)node = null;
node.val = node.next.val;
node.next = node.next.next;
}
}
106 Product of Array Except Self
给定一个由n个整数组成的数组num,其中n> 1,则返回一个数组输出,使得output [i]等于除nums [i]之外所有nums元素的乘积。
Example:
Input: [1,2,3,4]
Output: [24,12,8,6]
class Solution {
public int[] productExceptSelf(int[] nums) {
if(nums == null || nums.length == 0)return null;
int res[] = new int[nums.length];
//res = [1, 1 * 1, 1 * 1 * 2, 1 * 1 * 2 * 3]
res[0] = 1;
for(int i = 1; i < nums.length; i ++) {
res[i] = res[i - 1] * nums[i - 1];
}
int tmp = 1;
for(int i = nums.length - 1; i >= 0; i --) {
res[i] = res[i] * tmp;
tmp *= nums[i];
}
return res;
}
}
107 Sliding Window Maximum
给定一个数组num,存在一个大小为k的滑动窗口,该窗口从数组的最左边移到最右边。您只能在窗口中看到k个数字。每次滑动窗口向右移动一个位置。返回最大滑动窗口。
Example:
Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3
Output: [3,3,5,5,6,7]
Explanation:
Window position Max
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length == 0)return new int[]{};
int []res = new int[nums.length - k + 1];
int index = 0;
Deque<Integer> dq = new LinkedList<>();
for(int i = 0; i < nums.length; i ++) {
//存储最大值和其次
while(!dq.isEmpty() && nums[dq.peekLast()] < nums[i])
dq.pollLast();
dq.addLast(i);
//弹出过期数据
while(i - dq.peek() >= k)
dq.pollFirst();
if(i + 1 >= k) {
res[index ++] = nums[dq.peek()];
}
}
return res;
}
}
108 Search a 2D Matrix II
编写一种有效的算法,以在m x n矩阵中搜索值。该矩阵具有以下属性:每行中的整数按从左到右的升序排列。每列中的整数按从上到下的升序排列。
Example:
Consider the following matrix:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
Given target = 5
, return true
.
Given target = 20
, return false
.
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix.length == 0)return false;
int i = 0, j = matrix[0].length - 1;
while(i < matrix.length && j >= 0) {
if(matrix[i][j] == target) return true;
else if(matrix[i][j] < target) i ++;
else j--;
}
return false;
}
}
109 Valid Anagram
给定两个字符串s和t,编写一个函数来确定t是否是s的字谜。
Example 1:
Input: s = "anagram", t = "nagaram"
Output: true
Example 2:
Input: s = "rat", t = "car"
Output: false
class Solution {
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) return false;
int[] letters = new int[128];
for (char ch : s.toCharArray()) {
letters[(int) ch]++;
}
for (char ch : t.toCharArray()) {
letters[(int) ch]--;
}
for (int i : letters) {
if (i != 0)
return false;
}
return true;
}
}
110 Flatten 2D Vector(VIP)
111 Meeting Rooms II(VIP)
112 Missing Number
给定一个数组,其中包含从0、1、2,…,n中提取的n个不同的数字,请找到该数组中缺少的一个。
class Solution {
public int missingNumber(int[] nums) {
int res = nums.length;
for(int i = 0; i < nums.length; i ++){
res ^= i ^ nums[i];
}
return res;
}
}
113 Alien Dictionary(VIP)
114 Find the Celebrity(VIP)
115 Perfect Squares
给定一个正整数n,求和为n的最小平方数(例如1、4、9、16,…)。
Example 1:
Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.
Example 2:
Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.
class Solution {
public int numSquares(int n) {
if(n < 2)return n;
int []memo = new int[n + 1];
Arrays.fill(memo, Integer.MAX_VALUE);
memo[0] = 0;
for(int i = 1; i <= n; i ++) {
for(int j = 1; j * j <= i; j ++) {
memo[i] = Math.min(memo[i], memo[i - j * j] + 1);
}
}
return memo[n];
}
}
116 Move Zeroes
给定一个数组num,编写一个函数,将所有0移到它的末尾,同时保持非零元素的相对顺序。
Example:
Input: [0,1,0,3,12]
Output: [1,3,12,0,0]
class Solution {
public void moveZeroes(int[] nums) {
if(nums.length == 0)return;
int index = 0;
for(int i = 0; i < nums.length; i ++) {
if(nums[i] != 0) {
nums[index ++] = nums[i];
}
}
for(int i = index; i < nums.length; i ++) {
nums[i] = 0;
}
}
}
117 Inorder Successor in BST(VIP)
118 Find the Duplicate Number
给定一个包含n + 1个整数的数组,其中每个整数在1到n(含)之间,存在一个重复数。假定只有一个重复的数字,找到重复的一个。
Example:
Input: [1,3,4,2,2]
Output: 2
class Solution {
public int findDuplicate(int[] nums) {
if(nums.length == 0)return -1;
for(int i = 0; i < nums.length; i ++) {
if(nums[i] - 1 == i)continue;
int tmp = nums[i];
if(nums[tmp - 1] == tmp)return tmp;
nums[i] = nums[tmp - 1];
nums[tmp - 1] = tmp;
i --;
}
return -1;
}
}
119 Game of Life
120 Find Median from Data Stream
中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值。因此,中位数是两个中间值的平均值。
Example
[2,3,4], the median is 3
[2,3], the median is (2 + 3) / 2 = 2.5
class MedianFinder {
/** initialize your data structure here. */
PriorityQueue<Integer> min;
PriorityQueue<Integer> max;
public MedianFinder() {
min = new PriorityQueue<>();
max = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
}
public void addNum(int num) {
if(min.isEmpty() || min.peek() <= num)
min.add(num);
else max.add(num);
if(max.size() + 2 == min.size())
max.add(min.poll());
if(min.size() + 1== max.size())
min.add(max.poll());
}
public double findMedian() {
return min.size() == max.size() ?
(min.peek() + max.peek()) / 2.0 : 1.0 * min.peek();
}
}
121 Serialize and Deserialize Binary Tree
序列化和反序列化二叉树
Example:
You may serialize the following tree:
1
/ \
2 3
/ \
4 5
as "[1,2,3,null,null,4,5]"
Serialize and Deserialize Binary Tree
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuffer sb = new StringBuffer();
if(root == null) {
sb.append("#,");
return sb.toString();
}
sb.append(root.val + ",");
sb.append(serialize(root.left));
sb.append(serialize(root.right));
return sb.toString();
}
int index = -1;
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
String []res = data.split(",");
TreeNode root = null;
if(!res[++ index].equals("#")) {
root = new TreeNode(Integer.parseInt(res[index]));
root.left = deserialize(data);
root.right = deserialize(data);
}
return root;
}
}
122 Longest Increasing Subsequence
给定一个未排序的整数数组,请找到最长递增子序列的长度
Example:
Input: [10,9,2,5,3,7,101,18]
Output: 4
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
Longest Increasing Subsequence
class Solution {
public int lengthOfLIS(int[] nums) {
if(nums.length == 0)return 0;
int memo[] = new int[nums.length];
Arrays.fill(memo, 1);
int res = 1;
for(int i = 1; i < nums.length; i ++) {
for(int j = 0; j < i; j ++) {
if(nums[i] > nums[j]) {
memo[i] = Math.max(memo[i], memo[j] + 1);
}
}
}
for(int i = 0; i < memo.length; i ++) {
res = Math.max(res, memo[i]);
}
return res;
}
}
123 Range Sum Query 2D - Mutable(VIP)
124 Count of Smaller Numbers After Self
您将得到一个整数数组nums,并且必须返回一个新的counts数组。counts数组具有以下属性:counts [i]是nums [i]右侧较小元素的数量。
Example:
Input: [5,2,6,1]
Output: [2,1,1,0]
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.
Count of Smaller Numbers After Self
125 Coin Change
您会得到不同面额的硬币和总金额。编写一个函数来计算组成该数量所需的最少数量的硬币。如果这笔钱不能用硬币的任何组合来弥补,请返回-1。
Example 1:
Input: coins = [1, 2, 5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1
Example 2:
Input: coins = [2], amount = 3
Output: -1
- 记忆化搜索
public int coinChange(int[] coins, int amount) {
if (coins.length == 0) return -1;
int memo[] = new int[amount];
return helper(coins, amount, memo);
}
private int helper(int[] coins, int amount, int[] memo) {
if (amount < 0) return -1;
if (amount == 0) return 0;
if (memo[amount - 1] != 0) return memo[amount - 1];
int min = Integer.MAX_VALUE;
int res = 0;
for (int i = 0; i < coins.length; i++) {
res = helper(coins, amount - coins[i], memo);
if (res >= 0)
min = Math.min(min, res + 1);
}
memo[amount - 1] = (min == Integer.MAX_VALUE) ? -1 : min;
return memo[amount - 1];
}
- 动态规划
public int coinChange(int[] coins, int amount) {
if (coins.length == 0) return -1;
int memo[] = new int[amount + 1];
Arrays.fill(memo, amount + 1);
memo[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int c : coins) {
if (i - c >= 0) {
memo[i] = Math.min(memo[i], memo[i - c] + 1);
}
}
}
return memo[amount] > amount ? -1 : memo[amount];
}
126 Wiggle Sort II
给定未排序的数组num,请对其重新排序,以使nums [0] <nums [1]> nums [2] <nums [3]…。
Example 1:
Input: nums = [1, 5, 1, 1, 6, 4]
Output: One possible answer is [1, 4, 1, 5, 1, 6].
class Solution {
public void wiggleSort(int[] nums) {
Arrays.sort(nums);
int[] arr = Arrays.copyOf(nums, nums.length);
int j = nums.length - 1;
for (int i = 1; i < nums.length; i += 2) {
nums[i] = arr[j];
j--;
}
for (int i = 0; i < nums.length; i += 2) {
nums[i] = arr[j];
j--;
}
}
}
127 Power of Three
给定一个整数,编写一个函数以确定它是否为三的幂。
public class Solution {
public boolean isPowerOfThree(int n) {
return (Math.log10(n) / Math.log10(3)) % 1 == 0;
}
}
128 Odd Even Linked List
给定一个单链表,将所有奇数节点组合在一起,然后是偶数节点。请注意,这里我们谈论的是节点号,而不是节点中的值。您应该尝试就地进行。该程序应在O(1)空间复杂度和O(节点)时间复杂度下运行。
class Solution {
public ListNode oddEvenList(ListNode head) {
if(head == null)return null;
if(head.next == null)return head;
ListNode odd = head;
ListNode even = head.next;
ListNode evenHead = even;
while(even != null && even.next != null){
odd.next = even.next;
odd = odd.next;
even.next = odd.next;
even = even.next;
}
odd.next = evenHead;
return head;
}
}
129 Longest Increasing Path in a Matrix
给定一个整数矩阵,找到最长增加路径的长度。从每个单元格,您可以向四个方向移动:左,右,上或下。您不能对角移动或移动到边界之外(即不允许环绕)。
Longest Increasing Path in a Matrix
class Solution {
int m,n;
boolean[][] visited;//存储是否访问
int[][] memo;//存储从这个节点开始的最大路径
public int longestIncreasingPath(int[][] matrix) {
if(matrix.length == 0)return 0;
m = matrix.length;
n = matrix[0].length;
visited = new boolean[m][n];
memo = new int[m][n];
int res = 0;
for(int i = 0; i < m; i ++) {
for(int j = 0; j < n; j ++) {
//如果这个位置已经计算过了,直接比较
if(memo[i][j] != 0) {
res = Math.max(memo[i][j], res);
} else {
//寻找最大值
res = Math.max(res, findPath(matrix, i, j));
}
}
}
return res;
}
private int findPath(int[][] matrix, int x, int y) {
if(visited[x][y] == true)return 0;
if(memo[x][y] != 0)return memo[x][y];
//如果都不能走都情况就是1
int res = 1;
//上下左右走
visited[x][y] = true;
if(x < m - 1 && matrix[x][y] < matrix[x + 1][y])
res = Math.max(res, findPath(matrix, x + 1, y) + 1);
if(x > 0 && matrix[x][y] < matrix[x - 1][y])
res = Math.max(res, findPath(matrix, x - 1, y) + 1);
if(y < n - 1 && matrix[x][y] < matrix[x][y + 1])
res = Math.max(res, findPath(matrix, x, y + 1) + 1);
if(y > 0 && matrix[x][y] < matrix[x][y - 1])
res = Math.max(res, findPath(matrix, x, y - 1) + 1);
visited[x][y] = false;
//回溯时记录走过节点都最大值
memo[x][y] = res;
return res;
}
}
130 Increasing Triplet Subsequence
给定一个未排序的数组,返回数组中是否存在长度为3的递增子序列。
Example 1:
Input: [1,2,3,4,5]
Output: true
Increasing Triplet Subsequence
class Solution {
public boolean increasingTriplet(int[] nums) {
if (nums.length < 3) return false;
int i = Integer.MAX_VALUE, j = i, k = i;
boolean flagI = false, flagJ = flagI, flagK = flagI;//表示三个位置自满足的情况
//由于位置从小到大赋值,所以满足 0 ≤ i的位置 < j的位置 < k的位置 ≤ n-1
for (int q = 0; q < nums.length; q++) {
//i 只要满足位置不是倒数1,2即可
if (nums[q] < i && nums.length - q > 2) {
i = nums[q];
flagI = true;
}
//j 需要满足大于 i 的值 且位置不是倒数 1
else if (nums[q] > i && nums[q] < j && nums.length - q > 1) {
j = nums[q];
flagJ = true;
}
//k 需要满足大于 j 且小于 INTEGER.MAX_INTEGER
else if (nums[q] > j && nums[q] < k) {
k = nums[q];
flagK = true;
break;
}
}
return flagI && flagJ && flagK ? i < j && j < k : false;
}
}
131 Longest Substring with At Most K Distinct Characters(VIP)
Longest Substring with At Most K Distinct Characters
132 Flatten Nested List Iterator
给定一个嵌套的整数列表,请实现一个迭代器以使其扁平化。每个元素可以是整数,也可以是列表-其元素也可以是整数或其他列表。
/**
* // This is the interface that allows for creating nested lists.
* // You should not implement it, or speculate about its implementation
* public interface NestedInteger {
*
* // @return true if this NestedInteger holds a single integer, rather than a nested list.
* public boolean isInteger();
*
* // @return the single integer that this NestedInteger holds, if it holds a single integer
* // Return null if this NestedInteger holds a nested list
* public Integer getInteger();
*
* // @return the nested list that this NestedInteger holds, if it holds a nested list
* // Return null if this NestedInteger holds a single integer
* public List<NestedInteger> getList();
* }
*/
public class NestedIterator implements Iterator<Integer> {
ArrayList<Integer> list = new ArrayList<>();
int index = 0;
public NestedIterator(List<NestedInteger> nestedList) {
init(nestedList);
}
public void init(List<NestedInteger> nestedList) {
for (NestedInteger n : nestedList) {
addNestedInteger(n);
}
}
public void addNestedInteger(NestedInteger n) {
if (n.isInteger()) {
list.add(n.getInteger());
return;
}
init(n.getList());
}
@Override
public Integer next() {
return list.get(index++);
}
@Override
public boolean hasNext() {
return index < list.size() ? true : false;
}
}
133 Reverse String
反转字符串
class Solution {
public void reverseString(char[] s) {
for (var i = 0; i < s.Length / 2; i++) {
var tmp = s[i];
s[i] = s[s.Length - i - 1];
s[s.Length - i - 1] = tmp;
}
}
}
134 Top K Frequent Elements
给定一个非空的整数数组,返回k个最频繁的元素。
思路:使用最大堆
class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int count = map.getOrDefault(nums[i], 0);
map.put(nums[i], count + 1);
}
PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return map.get(b) - map.get(a);
}
});
for (int key : map.keySet()) {
pq.add(key);
}
LinkedList<Integer> list = new LinkedList<>();
while (k-- > 0) {
list.add(pq.remove());
}
return list;
}
}
135 Design Tic-Tac-Toe(VIP)
136 Intersection of Two Arrays II
给定两个数组,编写一个函数来计算它们的交集。
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
int[] result = new int[Math.min(nums1.length, nums2.length)];
for (int i = 0; i < nums1.length; i++) {
int count = map.getOrDefault(nums1[i], 0);
map.put(nums1[i], count + 1);
}
int j = 0;
for (int i = 0; i < nums2.length; i++) {
if (map.get(nums2[i]) != null && map.get(nums2[i]) > 0) {
map.put(nums2[i], map.get(nums2[i]) - 1);
result[j++] = nums2[i];
}
}
return Arrays.copyOfRange(result, 0, j);
}
}
137 Sum of Two Integers
计算两个整数a和b的总和,但不允许使用+和-运算符。
class Solution {
public int getSum(int a, int b) {
if(b == 0)return a;
int carry = a & b;
return getSum(a ^ b, carry << 1);
}
}
138 Kth Smallest Element in a Sorted Matrix
给定一个n x n矩阵,其中每个行和列都按升序排序,请找到矩阵中第k个最小的元素。请注意,它是排序顺序中第k个最小的元素,而不是第k个不同的元素。
Example:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
return 13.
Kth Smallest Element in a Sorted Matrix
class Solution {
private int count(int[][] a, int target) {
int i = a.length - 1, j = 0;
int c = 0;
while (i >= 0 && j < a.length) {
if (a[i][j] <= target) {
c += i + 1;
j++;
} else i--;
}
return c;
}
public int kthSmallest(int[][] matrix, int k) {
int l = matrix[0][0], h = matrix[matrix.length - 1][matrix.length - 1];
while (l < h) {
int mid = l + ((h - l) >> 1);
if (count(matrix, mid) < k) l = mid + 1;
else h = mid;
}
return h;
}
}
139 Insert Delete GetRandom O(1)
设计一个平均0(1)次支持所有后续操作的数据结构。
插入(val):如果项目val尚未存在,则将其插入到集合中。
移除(val):从集合中移除项目val(如果存在)。
getRandom:从当前元素集中返回一个随机元素。每个元素必须具有相同的返回概率。
class RandomizedSet {
/** Initialize your data structure here. */
HashMap<Integer,Integer> map;
ArrayList<Integer> list;
public RandomizedSet() {
map = new HashMap<>();
list = new ArrayList<>();
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
//插入使用HashMap O(1)
public boolean insert(int val) {
if(map.containsKey(val))return false;
map.put(val,list.size());
list.add(val);
return true;
}
//删除的时候判断是否是最后一个,如果不是最后一个
//把最后一个元素和要删除的元素下标对换位置
//然后删除List的最后一个 O(1)
/** Removes a value from the set. Returns true if the set contained the specified element. */
public boolean remove(int val) {
if(!map.containsKey(val))return false;
if(map.get(val) < list.size()){
int index = map.get(val);
list.set(index,list.get(list.size() - 1));
map.put(list.get(list.size() - 1),index);
}
map.remove(val);
list.remove(list.size() - 1);
return true;
}
//随机生成数用list取是O(1)
/** Get a random element from the set. */
public int getRandom() {
Random random = new Random();
return list.get(random.nextInt(list.size()));
}
}
140 Shuffle an Array
洗牌的一组数字不重复。
Example:
//初始化集合为1、2和3的数组。
int[] nums = {1,2,3};
Solution solution = new Solution(nums);
//洗牌数组[1,2,3]并返回其结果。[1,2,3]的任何置换必须同样可能被返回。
solution.shuffle();
//将数组重置回其原始配置[1,2,3]。
solution.reset();
//返回数组[1,2,3]的随机洗牌。
solution.shuffle();
思路:主要问题时如何返回一个随机的数组
class Solution {
private int[] array;
private int[] original;
Random rand = new Random();
private int randRange(int min, int max) {
return rand.nextInt(max - min) + min;
}
private void swapAt(int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public Solution(int[] nums) {
array = nums;
original = nums.clone();
}
public int[] reset() {
array = original;
original = original.clone();
return original;
}
public int[] shuffle() {
for (int i = 0; i < array.length; i++) {
//该位置的数和数组后的数位置随机交换
//因为从头开始,所有我们可以认为前面的数已经是随机过了的
swapAt(i, randRange(i, array.length));
}
return array;
}
}
141 First Unique Character in a String
找到字符串第一个不重复的字符,如果不存在则返回-1.注意:返回的是字符的位置
Examples:
s = "leetcode"
return 0.
s = "loveleetcode",
return 2.
First Unique Character in a String
class Solution {
public int firstUniqChar(String s) {
int let[] = new int[26];
for(int i = 0; i < s.length(); i ++){
let[s.charAt(i) - 'a']++;
}
for(int i = 0; i < s.length(); i ++){
if(let[s.charAt(i) - 'a'] == 1)return i;
}
return -1;
}
}
142 Longest Substring with At Least K Repeating Characters
查找给定字符串的最长子字符串T的长度(仅由小写字母组成),使T中的每个字符出现不少于k次。
Example 1:
Input:
s = "aaabb", k = 3
Output:
3
The longest substring is "aaa", as 'a' is repeated 3 times.
Example 2:
Input:
s = "ababbc", k = 2
Output:
5
The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
Longest Substring with At Least K Repeating Characters
class Solution {
public int longestSubstring(String s, int k) {
if(s.length() < k || k == 0)return 0;
int []arr = new int[26];
for(int i = 0; i < s.length(); i ++){
arr[s.charAt(i) - 'a'] ++;
}
boolean flag = true;
for(int i = 0; i < s.length(); i ++)
if(arr[s.charAt(i) - 'a'] < k){
flag = false;
break;
}
if(flag)return s.length();
int idx = 0;int start = 0;int res = 0;
while(idx < s.length()){
if(arr[s.charAt(idx) - 'a'] < k){
res = Math.max(res,longestSubstring(s.substring(start,idx),k));
start = idx + 1;
}
idx ++;
}
return Math.max(res,longestSubstring(s.substring(start,idx),k));
}
}
143 Fizz Buzz
编写一个程序,输出从1到n的数字的字符串表示形式。但是对于三的倍数,它应该输出“ Fizz”而不是数字,对于五的倍数,它应该输出“嗡嗡声”。对于三和五的倍数的数字,输出“ FizzBuzz”。
class Solution {
public List<String> fizzBuzz(int n) {
List<String> list = new ArrayList<>();
if(n == 0) return list;
for(int i = 1; i <= n; i ++){
if(i % 3 == 0 && i % 5 == 0)
list.add("FizzBuzz");
else if(i % 3 == 0)
list.add("Fizz");
else if(i % 5 == 0)
list.add("Buzz");
else
list.add(i + "");
}
return list;
}
}
144 4Sum II
给定四个具有整数值的列表A,B,C,D,计算有多少个元组(i,j,k,l),使得A [i] + B [j] + C [k] + D [l]
Example:
Input:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
Output:
2
Explanation:
The two tuples are:
1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
class Solution {
public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
int count = 0;
Map<Integer, Integer> map = new HashMap<>(A.length*A.length);
for (int a: A) {
for (int b: B) {
map.put(a+b, map.getOrDefault(a+b, 0) + 1);
}
}
for (int c: C) {
for (int d: D) {
if (map.containsKey(-c-d))
count += map.get(-c-d);
}
}
return count;
}
}