599. 两个列表的最小索引总和

添加链接描述
假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。

你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设答案总是存在。

示例 1:
输入: list1 = [“Shogun”, “Tapioca Express”, “Burger King”, “KFC”],list2 = [“Piatti”, “The Grill at Torrey Pines”, “Hungry Hunter Steakhouse”, “Shogun”]
输出: [“Shogun”]
解释: 他们唯一共同喜爱的餐厅是“Shogun”。

class Solution {public String[] findRestaurant(String[] list1, String[] list2) {Map<String, Integer> map = new HashMap<>();for (int i = 0; i < list1.length; i++) {map.put(list1[i], i);}int minIndexSum = Integer.MAX_VALUE;List<String> list = new ArrayList<>();for (int i = 0; i < list2.length; i++) {if(map.containsKey(list2[i])) {int j = map.get(list2[i]);if(i + j < minIndexSum) {list.clear();list.add(list2[i]);minIndexSum = i + j;} else if (i + j == minIndexSum) {list.add(list2[i]);}}}return list.toArray(new String[0]);}
}
2181. 合并零之间的节点

添加链接描述
给你一个链表的头节点 head ,该链表包含由 0 分隔开的一连串整数。链表的 开端 和 末尾 的节点都满足 Node.val == 0 。

对于每两个相邻的 0 ,请你将它们之间的所有节点合并成一个节点,其值是所有已合并节点的值之和。然后将所有 0 移除,修改后的链表不应该含有任何 0 。

返回修改后链表的头节点 head 。

示例 1:

输入:head = [0,3,1,0,4,5,2,0]
输出:[4,11]
解释:
上图表示输入的链表。修改后的链表包含:

  • 标记为绿色的节点之和:3 + 1 = 4
  • 标记为红色的节点之和:4 + 5 + 2 = 11
class Solution {public ListNode mergeNodes(ListNode head) {ListNode newHead = new ListNode(-1);ListNode tmp = newHead;ListNode cur = head;int val = 0;while(cur != null) {if(cur != head && cur.val == 0) { // 第一个头节点不加入tmp.next = new ListNode(val);tmp = tmp.next;val = 0; // 下一个} else {val += cur.val;}cur = cur.next;}return newHead.next;}
}
69. x 的平方根

添加链接描述
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

示例 1:
输入:x = 4
输出:2

class Solution {// 二分public int mySqrt(int x) {if(x == 1) return 1;int left = 1;int right = x / 2; //while(left <= right) {int mid = left + (right - left) / 2;if(x / mid > mid) { //不用x > mid * mid 防溢出left = mid + 1;} else if (x / mid < mid) {right = mid - 1;} else {return mid;}}return right; // -1->-1   0->1}// 2、根据平方数的性质——连续n个奇数相加的结果一定是平方数public int mySqrt2(int x) {if(x < 0) return 0;int i = 1;int ans = 0;while(x >= 0) {x -= i;i += 2;ans++;}return ans - 1;}public int mySqrt1(int x) {double mul = Math.sqrt(x);return (int)Math.floor(mul);}
}
917. 仅仅反转字母

添加链接描述
给你一个字符串 s ,根据下述规则反转字符串:

所有非英文字母保留在原有位置。
所有英文字母(小写或大写)位置反转。
返回反转后的 s 。

示例 1:
输入:s = “ab-cd”
输出:“dc-ba”

class Solution {public String reverseOnlyLetters(String s) {char[] ret = s.toCharArray();int left = 0;int right = ret.length - 1; // while(left < right) {while(left < right && !Character.isLetter(ret[left])) {left++;}while(left < right && !Character.isLetter(ret[right])) {right--;}if(left < right) {char tmp = ret[left];ret[left] = ret[right];ret[right] = tmp;}left++; //right--; //}return new String(ret);}
}
剑指 Offer 54. 二叉搜索树的第k大节点

添加链接描述
给定一棵二叉搜索树,请找出其中第 k 大的节点的值。
示例 1:

输入: root = [3,1,4,null,2], k = 1
3
/
1 4

2
输出: 4

class Solution {// 中序遍历 保存的list中是从小到大排序的public void inorder(TreeNode root, List<Integer> list) {if(root == null) {return;}inorder(root.left, list);list.add(root.val);inorder(root.right, list);}public int kthLargest(TreeNode root, int k) {List<Integer> list = new ArrayList<>();inorder(root, list);return list.get(list.size() - k); // 获取}
}
496. 下一个更大元素 I

添加链接描述
nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。

给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。

对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。

返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。

示例 1:
输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:

  • 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
  • 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
  • 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
class Solution {// 单调栈 + mappublic int[] nextGreaterElement(int[] nums1, int[] nums2) {Deque<Integer> stack = new ArrayDeque<>(); // 从小到大Map<Integer, Integer> map = new HashMap<>(); // 记录映射关系for (int i = nums2.length - 1; i >= 0; i--) { // 从后往前 记录nums2中向左第一个最大值int num = nums2[i];while(!stack.isEmpty() && num >= stack.peek()) {stack.pop(); // 比栈顶大或等于 出栈 判断下一个}// 空-> 右边无比之大的数 存储-1    不为空 -> 存储map.put(num, stack.isEmpty() ? -1 : stack.peek());stack.push(num); // 入栈}int[] ans = new int[nums1.length];for (int i = 0; i < nums1.length; i++) {ans[i] = map.get(nums1[i]); // 数组元素不重复 通过map找到当前数据对应的第一个最大值}return ans;}// 暴力算法 O(n*m)// 找在nums2中的位置->j  往后找第一个大的k  判断是否<n  若存在加入数组public int[] nextGreaterElement1(int[] nums1, int[] nums2) {int m = nums1.length;int n = nums2.length;int[] ans = new int[m];for (int i = 0; i < m; i++) {int j = 0;while(j < n && nums2[j] != nums1[i]) {j++;}int k = j + 1;while(k < n && nums2[k] < nums1[i]) {k++;}ans[i] = k < n ? nums2[k] : -1;}return ans;}
}
1441. 用栈操作构建数组

添加链接描述
给你一个目标数组 target 和一个整数 n。每次迭代,需要从 list = {1,2,3…, n} 中依序读取一个数字。

请使用下述操作来构建目标数组 target :

Push:从 list 中读取一个新元素, 并将其推入数组中。
Pop:删除数组中的最后一个元素。
如果目标数组构建完成,就停止读取更多元素。
题目数据保证目标数组严格递增,并且只包含 1 到 n 之间的数字。

请返回构建目标数组所用的操作序列。

题目数据保证答案是唯一的。

示例 1:
输入:target = [1,3], n = 3
输出:[“Push”,“Push”,“Pop”,“Push”]
解释:
读取 1 并自动推入数组 -> [1]
读取 2 并自动推入数组,然后删除它 -> [1]
读取 3 并自动推入数组 -> [1,3]

class Solution {public List<String> buildArray(int[] target, int n) {List<String> list = new ArrayList<>();int index = 0;for(int j = 1; j <= n && index < target.length; j++) {if(j == target[index]) { // 一个匹配 到 下一个元素list.add("Push");index++;} else {list.add("Push");list.add("Pop");}}return list;}
}
328. 奇偶链表

添加链接描述
给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。

第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。

请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。

你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。

class Solution {// 分离节点后合并public ListNode oddEvenList(ListNode head) {if(head == null || head.next == null) {return head;}ListNode evenHead = head.next; // 连接单节点的尾ListNode odd = head; // 单数链表的头节点ListNode even = head.next; // 偶数链表的头节点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;}
}
2. 两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

class Solution {// 正确做法:与67题类似// https://leetcode-cn.com/problems/add-binary/// 由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加。// 我们同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode newHead = new ListNode(-1);ListNode tmp = newHead;int carry = 0; // 进位while(l1 != null || l2 != null || carry != 0) {int val1 = l1 != null ? l1.val : 0;int val2 = l2 != null ? l2.val : 0;int val = val1 + val2 + carry; // 还需加入的总值carry = val / 10; // 如果是10,此次节点val为0,进位1tmp.next = new ListNode(val % 10);tmp = tmp.next; // 不要忘了往后走if(l1 != null) {l1 = l1.next;}if(l2 != null) {l2 = l2.next;}}return newHead.next;}// 修改为Long 还是有超出范围的情况public Long getSumOfVal(ListNode cur) {StringBuilder sb = new StringBuilder();while(cur != null) {sb.append(cur.val);cur = cur.next;}String str = sb.reverse().toString();return Long.valueOf(str);}public ListNode addTwoNumbers1(ListNode l1, ListNode l2) {Long num1 = getSumOfVal(l1);Long num2 = getSumOfVal(l2);Long sum = num1 + num2; // 两链表 val 之和// 逆置和String str = String.valueOf(sum);StringBuilder sb = new StringBuilder(str).reverse();ListNode newHead = new ListNode(-1);ListNode cur = newHead; // 连接每一个节点for (int i = 0; i < str.length(); i++) {ListNode node = new ListNode(sb.charAt(i) - '0');cur.next = node;cur = cur.next;}return newHead.next;}
}
67. 二进制求和

添加链接描述
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。

示例 1:
输入: a = “11”, b = “1”
输出: “100”

class Solution {public String addBinary(String a, String b) {int i = a.length() - 1;int j = b.length() - 1;StringBuilder sb = new StringBuilder();int carry = 0;while(i >= 0 || j >= 0 || carry != 0) { // 进位不为0int sum = carry;if(i >= 0) {sum += a.charAt(i--) - '0';}if(j >= 0) {sum += b.charAt(j--) - '0';}sb.append(sum % 2);carry = sum / 2;}/*if() { // 进位 不为0 放个位数sb.append(carry);}*/return sb.reverse().toString();}// 先将 a 和 b 转化成十进制数,求和后再转化为二进制数// 如果字符串超过 33 位,不能转化为 Integer// 如果字符串超过 65 位,不能转化为 Long// 如果字符串超过 500000001 位,不能转化为 BigInteger/*public String addBinary1(String a, String b) {return Integer.toBinaryString(Integer.parseInt(a, 2) + Integer.parseInt(b, 2));}*/
}
1171. 从链表中删去总和值为零的连续节点

给你一个链表的头节点 head,请你编写代码,反复删去链表中由 总和 值为 0 的连续节点组成的序列,直到不存在这样的序列为止。

删除完毕后,请你返回最终结果链表的头节点。

你可以返回任何满足题目要求的答案。

(注意,下面示例中的所有序列,都是对 ListNode 对象序列化的表示。)

示例 1:
输入:head = [1,2,-3,3,1]
输出:[3,1]
提示:答案 [1,2,1] 也是正确的。

class Solution {// 前缀和public ListNode removeZeroSumSublists(ListNode head) {ListNode newHead = new ListNode(0);newHead.next = head;int sum = 0; // 和ListNode cur = newHead;Map<Integer, ListNode> map = new HashMap<>();// 首次遍历建立 节点处链表和<->节点 哈希表// 若同一和出现多次会覆盖,即记录该sum出现的最后一次节点while(cur != null) {sum += cur.val;map.put(sum, cur);cur = cur.next;}// 第二遍遍历 若当前节点处sum在下一处出现了则表明两结点之间所有节点和为0 直接删除区间所有节点//(从前面的一个sum处的节点指向后面的另一个sum处的节点的next)sum = 0;cur = newHead;while(cur != null) {sum += cur.val;cur.next = map.get(sum).next;cur = cur.next;}return newHead.next;}
}
717. 1比特与2比特字符

有两种特殊字符:
第一种字符可以用一个比特 0 来表示
第二种字符可以用两个比特(10 或 11)来表示、
给定一个以 0 结尾的二进制数组 bits ,如果最后一个字符必须是一位字符,则返回 true 。

示例 1:
输入: bits = [1, 0, 0]
输出: true
解释: 唯一的编码方式是一个两比特字符和一个一比特字符。
所以最后一个字符是一比特字符。

class Solution {public boolean isOneBitCharacter(int[] bits) {int start = 0;while(start < bits.length - 1) {if(bits[start] == 0) {start++;} else {start += 2;}}return start == bits.length - 1;}
}
1791. 找出星型图的中心节点

有一个无向的 星型 图,由 n 个编号从 1 到 n 的节点组成。星型图有一个 中心 节点,并且恰有 n - 1 条边将中心节点与其他每个节点连接起来。

给你一个二维整数数组 edges ,其中 edges[i] = [ui, vi] 表示在节点 ui 和 vi 之间存在一条边。请你找出并返回 edges 所表示星型图的中心节点。

class Solution {// 顶点数目为 N,中心顶点的度为 N-1public int findCenter(int[][] edges) {Map<Integer, Integer> map = new HashMap<>();for(int[] e : edges) {map.put(e[0], map.getOrDefault(e[0], 0) + 1);map.put(e[1], map.getOrDefault(e[1], 0) + 1);}int size = map.size();for (Map.Entry<Integer, Integer> entry : map.entrySet()) {if(entry.getValue() == size - 1) {return entry.getKey();}}/*for (int key : map.keySet()) {if(map.get(key) == size - 1) { // 根据k找vreturn key;}}*/return -1;}public int findCenter1(int[][] edges) {return edges[0][0] == edges[1][0] || edges[0][0] == edges[1][1] ? edges[0][0] : edges[0][1];}
}
1046. 最后一块石头的重量

添加链接描述
有一堆石头,每块石头的重量都是正整数。

每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0。

示例:
输入:[2,7,4,1,8,1]
输出:1
解释:
先选出 7 和 8,得到 1,所以数组转换为 [2,4,1,1,1],
再选出 2 和 4,得到 2,所以数组转换为 [2,1,1,1],
接着是 2 和 1,得到 1,所以数组转换为 [1,1,1],
最后选出 1 和 1,得到 0,最终数组转换为 [1],这就是最后剩下那块石头的重量。

class Solution {// 优先级队列public int lastStoneWeight(int[] stones) {// 大根堆PriorityQueue<Integer> pr = new PriorityQueue<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}});for (int n : stones) {pr.offer(n);}// 拿出两个 不相等y-x入队列while(pr.size() > 1) {int num1 = pr.poll();int num2 = pr.poll();if(num1 != num2) {pr.offer(num1 - num2);}}return pr.isEmpty() ? 0 : pr.poll();}// 排序public int lastStoneWeight1(int[] stones) {int n = stones.length;if(n <= 1) {return stones[0];}while(stones[n - 2] != 0) {Arrays.sort(stones);if(stones[n - 1] != stones[n - 2]) {stones[n - 1] = stones[n - 1] - stones[n - 2];stones[n - 2] = 0;} else {stones[n - 1] = 0;stones[n - 2] = 0;}Arrays.sort(stones); // stones[n - 2] != 0}return stones[n - 1];}
}
1380. 矩阵中的幸运数

添加链接描述
给你一个 m * n 的矩阵,矩阵中的数字 各不相同 。请你按 任意 顺序返回矩阵中的所有幸运数。

幸运数是指矩阵中满足同时下列两个条件的元素:

在同一行的所有元素中最小
在同一列的所有元素中最大

示例 1:
输入:matrix = [[3,7,8],[9,11,13],[15,16,17]]
输出:[15]
解释:15 是唯一的幸运数,因为它是其所在行中的最小值,也是所在列中的最大值。

class Solution {public List<Integer> luckyNumbers1 (int[][] matrix) {int m = matrix.length;int n = matrix[0].length;int[] minRow = new int[m]; // 第 i 行的最小值Arrays.fill(minRow, Integer.MAX_VALUE);int[] maxCol = new int[n]; // 第 j 列的最大值// 遍历   记录行最小值,列最大值for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {minRow[i] = Math.min(minRow[i], matrix[i][j]);maxCol[j] = Math.max(maxCol[j], matrix[i][j]);}}// 再次遍历 同时满足即为答案List<Integer> list = new ArrayList<>();for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {if(matrix[i][j] == minRow[i] && matrix[i][j] == maxCol[j]) {list.add(matrix[i][j]);}}}return list;}// 遍历矩阵,判断 matrix[i][j] 是否是它所在行的最小值和所在列的最大值public List<Integer> luckyNumbers (int[][] matrix) {int m = matrix.length;int n = matrix[0].length;List<Integer> list = new ArrayList<>();for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {boolean isMin = true;boolean isMax = true;// 判断行最小值for (int k = 0; k < n; k++) {if(matrix[i][k] < matrix[i][j]) {isMin = false;break;}}if(!isMin) {continue;}// 判断列最大值for (int k = 0; k < m; k++) {if(matrix[k][j] > matrix[i][j]) {isMax = false;break;}}if(isMax) {list.add(matrix[i][j]);}}}return list;}
}
540. 有序数组中的单一元素

添加链接描述
给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。

请你找出并返回只出现一次的那个数。

你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。

示例 1:
输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2

class Solution {// O(logn) 二分查找public int singleNonDuplicate2(int[] nums) {int left = 0;int right = nums.length - 1;while (left < right) {int mid = (right - left) / 2 + left;if(mid % 2 == 0) { // 偶数if(nums[mid] == nums[mid + 1]) {left = mid + 1;} else {right = mid;}} else { // 奇数if(nums[mid] == nums[mid - 1]) {left = mid + 1;} else {right = mid;}}}return nums[right];}// 用异或来进行统一,因为 偶数异或1 等于 加1,奇数异或1 等于 减1public int singleNonDuplicate(int[] nums) {int left = 0;int right = nums.length - 1;while (left < right) {int mid = (right - left) / 2 + left;if(nums[mid] == nums[mid ^ 1]) {left = mid + 1;} else {right = mid;}}return nums[right];}// O(n) 每两个遍历public int singleNonDuplicate1(int[] nums) {for(int i = 0; i < nums.length - 1; i += 2) {if(nums[i] != nums[i + 1]) {return nums[i];}}return nums[nums.length - 1];}
}
1189. “气球” 的最大数量

添加链接描述
给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 “balloon”(气球)。
字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 “balloon”。

示例 1:
输入:text = “nlaebolko”
输出:1

class Solution {public int maxNumberOfBalloons(String text) {// 此单词每个字符次数int[] times = new int[5];for(int i = 0; i < text.length(); i++) {char ch = text.charAt(i);if(ch == 'b') {times[0]++;} else if (ch == 'a') {times[1]++;} else if (ch == 'l') {times[2]++;} else if (ch == 'o') {times[3]++;} else if(ch == 'n'){times[4]++;}}// 'l' 'o' 有两次times[2] /= 2;times[3] /= 2;int min = times[0];for (int i = 0; i < 5; i++) {min = Math.min(min, times[i]);}return min;}
}
面试题 01.02. 判定是否互为字符重排

添加链接描述
给定两个字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

示例 1:
输入: s1 = “abc”, s2 = “bca”
输出: true

class Solution {// 3、哈希表public boolean CheckPermutation(String s1, String s2) {if(s1.length() != s2.length()) {return false;}HashMap<Character, Integer> map = new HashMap<>();// 如果相等,抵消为0for(int i = 0; i < s1.length(); i++) {map.put(s1.charAt(i), map.getOrDefault(s1.charAt(i), 0) + 1);map.put(s2.charAt(i), map.getOrDefault(s2.charAt(i), 0) - 1);}// 判断for(HashMap.Entry<Character, Integer> entry : map.entrySet()) {if(entry.getValue() != 0) {return false;}}return true;}// 2、数组统计次数public boolean CheckPermutation2(String s1, String s2) {if(s1.length() != s2.length()) {return false;}// 数组记录两字符串的字符次数、int[] cnts1 = cntLetters(s1);int[] cnts2 = cntLetters(s2);for(int i = 0; i < 26; i++) {if(cnts1[i] != cnts2[i]) {return false;}}return true;}public int[] cntLetters(String str) {int[] cnts = new int[26];for(int i = 0; i < str.length(); i++) {cnts[str.charAt(i) - 'a']++;}return cnts;}// 1、转字符数组 排序public boolean CheckPermutation1(String s1, String s2) {if(s1.length() != s2.length()) {return false;}char[] chars1 = s1.toCharArray();Arrays.sort(chars1);char[] chars2 = s2.toCharArray();Arrays.sort(chars2);// 字符串比较return new String(chars1).equals(new String(chars2));}
}
1984. 学生分数的最小差值

添加链接描述
给你一个 下标从 0 开始 的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数。另给你一个整数 k 。
从数组中选出任意 k 名学生的分数,使这 k 个分数间 最高分 和 最低分 的 差值 达到 最小化 。
返回可能的 最小差值 。

示例 1:
输入:nums = [90], k = 1
输出:0
解释:选出 1 名学生的分数,仅有 1 种方法:

  • [90] 最高分和最低分之间的差值是 90 - 90 = 0
    可能的最小差值是 0
// 滑动窗口最右边的值就是窗口内的最大值,滑动窗口最左边的值就是窗口内的最小值
// 因此,我们要寻找的就是已经排序的数组中,所有大小为 k 的滑动窗口中,最右端数字 - 最左端数字 的最小结果
class Solution {public int minimumDifference(int[] nums, int k) {Arrays.sort(nums);int min = Integer.MAX_VALUE;for(int i = 0; i + k - 1 < nums.length; i++) {min = Math.min(min, nums[i + k - 1] - nums[i]);}return min;}// 滑动窗口:通过两个指针截取固定长度的数组public int minimumDifference1(int[] nums, int k) {//   先将数组进行排序Arrays.sort(nums);// 截取一定长度的数组int left=0;int right=k-1;// 创建一个变量保存最小的差值int min = Integer.MAX_VALUE;while(right < nums.length) {min = Math.min(min, nums[right] - nums[left]);left++;right = left + k - 1;}return min;}
}
1447. 最简分数

添加链接描述
给你一个整数 n ,请你返回所有 0 到 1 之间(不包括 0 和 1)满足分母小于等于 n 的 最简 分数 。分数可以以 任意 顺序返回。

示例 1:
输入:n = 2
输出:[“1/2”]
解释:“1/2” 是唯一一个分母小于等于 2 的最简分数。

class Solution {// 更相减损法int gcd(int a, int b) {while(true) {if(a > b) {a -= b;} else if (a < b) {b -= a;} else {return a;}}}// 欧几里得算法int gcd1(int a, int b) {return b == 0 ? a : gcd(b, a % b);// int c = a % b;// while(c != 0) {//     a = b;//     b = c;//     c = a % b;// }// return b;}public List<String> simplifiedFractions(int n) {List<String> list = new ArrayList<>();for(int i = 1; i < n; i++) {for(int j = i + 1; j <= n; j++) {if(gcd(i, j) == 1) {list.add(i + "/" + j);}}}return list;}
}
2006. 差的绝对值为 K 的数对数目

添加链接描述
给你一个整数数组 nums 和一个整数 k ,请你返回数对 (i, j) 的数目,满足 i < j 且 |nums[i] - nums[j]| == k 。
|x| 的值定义为:
如果 x >= 0 ,那么值为 x 。
如果 x < 0 ,那么值为 -x 。

示例 1:
输入:nums = [1,2,2,1], k = 1
输出:4
解释:差的绝对值为 1 的数对为:

  • [1,2,2,1]
  • [1,2,2,1]
  • [1,2,2,1]
  • [1,2,2,1]
class Solution {public int countKDifference(int[] nums, int k) {int ans = 0;HashMap<Integer, Integer> map = new HashMap<>();for(int n : nums) {ans += map.getOrDefault(n + k, 0) + map.getOrDefault(n - k, 0);map.put(n, map.getOrDefault(n, 0) + 1);}return ans;}public int countKDifference1(int[] nums, int k) {int ans = 0;for (int i = 0; i < nums.length; i++) {for (int j = i + 1; j < nums.length; j++) {if(nums[i] - nums[j] == k || nums[j] - nums[i] == k) {ans++;}}}return ans;}
}
1748. 唯一元素的和

添加链接描述
给你一个整数数组 nums 。数组中唯一元素是那些只出现 恰好一次 的元素。
请你返回 nums 中唯一元素的 和 。

示例 1:
输入:nums = [1,2,3,2]
输出:4
解释:唯一元素为 [1,3] ,和为 4 。

class Solution {// 哈希表记录次数public int sumOfUnique1(int[] nums) {HashMap<Integer, Integer> map = new HashMap<>();for(int n : nums) {map.put(n, map.getOrDefault(n, 0) + 1);}int ans = 0;for(HashMap.Entry<Integer, Integer> entry : map.entrySet()) {if(entry.getValue() == 1) {ans += entry.getKey();}}return ans;}// 一次遍历  没有出现加起来 出现过就减 同时设为2public int sumOfUnique2(int[] nums) {HashMap<Integer, Integer> map = new HashMap<>();int ans = 0;for(int n : nums) {if(!map.containsKey(n)) {ans += n; // 没有此值map.put(n, 1); // 同时加入哈希表} else if(map.get(n) == 1) {ans -= n; // 出现过一次 表示加过了 需要减掉map.put(n, 2); // 同时设为2}}return ans;}// 数组public int sumOfUnique(int[] nums) {int[] cnts = new int[101];int ans = 0;for(int n : nums) {if(++cnts[n] == 1) {ans += n;} else if (cnts[n] == 2) {ans -= n;}}return ans;}
}
278. 第一个错误的版本

添加链接描述
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。

假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。

你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。

示例 1:
输入:n = 5, bad = 4
输出:4
解释:
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。

public class Solution extends VersionControl {public int firstBadVersion(int n) {int left = 1;int right = n;while(left < right) {int mid = left + ((right - left) >> 1);if(isBadVersion(mid)) {right = mid;  // 答案在区间 [left, mid] 中} else {left = mid + 1; // 答案在区间 [mid+1, right] 中}}return left;}
}
202. 快乐数

添加链接描述
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

示例 1:
输入:n = 19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1

class Solution {// 1、用哈希集合检测循环/* 算法分为两部分,我们需要设计和编写代码:- 给一个数字 n,它的下一个数字是什么?- 按照一系列的数字来判断我们是否进入了一个循环。第 1 部分我们按照题目的要求做数位分离,求平方和。第 2 部分可以使用哈希集合完成。每次生成链中的下一个数字时,我们都会检查它是否已经在哈希集合中。如果它不在哈希集合中,我们应该添加它。如果它在哈希集合中,这意味着我们处于一个循环中,因此应该返回 false。*/public int getNextNum(int n) {int num = 0;while(n > 0) {num += Math.pow(n % 10, 2);n /= 10;}return num;}public boolean isHappy1(int n) {Set<Integer> set = new HashSet<>();while(n != 1 && !set.contains(n)) {set.add(n);n = getNextNum(n);}return n == 1;}// 2、快慢指针法判断是否有环  龟兔赛跑public boolean isHappy(int n) {int slow = n;int fast = getNextNum(n);while(fast != 1 && slow != fast) {slow = getNextNum(slow);fast = getNextNum(getNextNum(fast));}return fast == 1;}
}
1816. 截断句子

添加链接描述
句子 是一个单词列表,列表中的单词之间用单个空格隔开,且不存在前导或尾随空格。每个单词仅由大小写英文字母组成(不含标点符号)。

例如,“Hello World”、“HELLO” 和 “hello world hello world” 都是句子。
给你一个句子 s​​​​​​ 和一个整数 k​​​​​​ ,请你将 s​​ 截断 ​,​​​使截断后的句子仅含 前 k​​​​​​ 个单词。返回 截断 s​​​​​​ 后得到的句子。

示例 1:
输入:s = “Hello how are you Contestant”, k = 4
输出:“Hello how are you”
解释:
s 中的单词为 [“Hello”, “how” “are”, “you”, “Contestant”]
前 4 个单词为 [“Hello”, “how”, “are”, “you”]
因此,应当返回 “Hello how are you”

class Solution {public String truncateSentence(String s, int k) {StringBuilder sb = new StringBuilder();for(int i = 0; i < s.length(); i++) {if(s.charAt(i) == ' ') {k--;}if(k == 0) {break;}sb.append(s.charAt(i));}return sb.toString();}
}
1725. 可以形成最大正方形的矩形数目

添加链接描述
给你一个数组 rectangles ,其中 rectangles[i] = [li, wi] 表示第 i 个矩形的长度为 li 、宽度为 wi 。

如果存在 k 同时满足 k <= li 和 k <= wi ,就可以将第 i 个矩形切成边长为 k 的正方形。例如,矩形 [4,6] 可以切成边长最大为 4 的正方形。

设 maxLen 为可以从矩形数组 rectangles 切分得到的 最大正方形 的边长。

请你统计有多少个矩形能够切出边长为 maxLen 的正方形,并返回矩形 数目 。

示例 1:
输入:rectangles = [[5,8],[3,9],[5,12],[16,5]]
输出:3
解释:能从每个矩形中切出的最大正方形边长分别是 [5,3,5,5] 。
最大正方形的边长为 5 ,可以由 3 个矩形切分得到。

class Solution {public int countGoodRectangles(int[][] rectangles) {int maxLen = 0; // maxLenint cnt = 0;for(int x[] : rectangles) {int min = Math.min(x[0], x[1]); // 每组中的最小边长if(min > maxLen) {cnt = 1; // 更新最大边长数}if(min == maxLen) {cnt++;}maxLen = Math.max(min, maxLen);}return cnt;}
}
1414. 和为 K 的最少斐波那契数字数目

添加链接描述
给你数字 k ,请你返回和为 k 的斐波那契数字的最少数目,其中,每个斐波那契数字都可以被使用多次。

斐波那契数字定义为:
F1 = 1
F2 = 1
Fn = Fn-1 + Fn-2 , 其中 n > 2 。
数据保证对于给定的 k ,一定能找到可行解。

示例 1:
输入:k = 7
输出:2
解释:斐波那契数字为:1,1,2,3,5,8,13,……
对于 k = 7 ,我们可以得到 2 + 5 = 7 。

class Solution {// 获取1-k的数列  从大到小找public int findMinFibonacciNumbers(int k) {List<Integer> list = new ArrayList<>();list.add(1);int f1 = 1;int f2 = 1;while (f1 + f2 <= k) {int f3 = f1 + f2;list.add(f3);f1 = f2;f2 = f3;}int ans = 0;for (int i = list.size() - 1; i >= 0 && k > 0; i--) {int num = list.get(i);// ans += k / num;// k %= num;// 斐波那契数字为:1,1,2,3,5,8,13// k = 19// 输出:3 // 解释:对于 k = 19 ,我们可以得到 1 + 5 + 13 = 19if(k >= num) {k -= num;ans++;}}return ans;}
}
1688. 比赛中的配对次数

添加链接描述

class Solution {// 每一场比赛中,输的队伍无法晋级,且不会再参加后续的比赛。// 由于最后只决出一个获胜队伍,因此就有 n-1 个无法晋级的队伍,也就是会有 n−1 场比赛。public int numberOfMatches(int n) {return n - 1;}public int numberOfMatches1(int n) {int ans = 0;while(n > 1) {ans += n / 2;if(n % 2 != 0) {n = n / 2 + 1;}else {n = n / 2;}}return ans;}
}
884. 两句话中的不常见单词

添加链接描述

class Solution {public String[] uncommonFromSentences(String s1, String s2) {String[] words1 = s1.split(" ");String[] words2 = s2.split(" ");HashMap<String, Integer> map = new HashMap<>();for (int i = 0; i < words1.length; i++) {map.put(words1[i], map.getOrDefault(words1[i], 0) + 1);}for (int i = 0; i < words2.length; i++) {map.put(words2[i], map.getOrDefault(words2[i], 0) + 1);}List<String> list = new ArrayList<>();for(Map.Entry<String, Integer> ret : map.entrySet ()) {if(ret.getValue() == 1) {list.add(ret.getKey());}}return list.toArray(new String[0]);}
}
1332. 删除回文子序列

添加链接描述

class Solution {// 如果该字符串本身为回文串,此时只需删除1次即可,删除次数为1// 如果该字符串本身不是回文串,此时只需删除2次即可,比如可以先删除所有的'a',再删除所有的'b',删除次数为2public int removePalindromeSub(String s) {int len = s.length();for(int i = 0; i < len / 2; i++) {if(s.charAt(i) != s.charAt(len - 1 - i)) {return 2;}}return 1;}
}
1512. 好数对的数目

添加链接描述
给你一个整数数组 nums 。
如果一组数字 (i,j) 满足 nums[i] == nums[j] 且 i < j ,就可以认为这是一组 好数对 。
返回好数对的数目。

示例 1:
输入:nums = [1,2,3,1,1,3]
输出:4
解释:有 4 组好数对,分别是 (0,3), (0,4), (3,4), (2,5) ,下标从 0 开始

class Solution {// 哈希表  x(x-1)/2public int numIdenticalPairs(int[] nums) {int cnt = 0;Map<Integer, Integer> map = new HashMap<>();for (int n : nums) {map.put(n, map.getOrDefault(n, 0) + 1);}for(Map.Entry<Integer, Integer> entry : map.entrySet()) {int x = entry.getValue();cnt += x * (x - 1) / 2;}return cnt;}// 数组下标 相当于排列求和// 假设nums = [1,1,1,1]// 第一遍   temp是[0,0,0,0]   ans+=0   temp[0]++// 第二遍   temp是[1,0,0,0]   ans+=1   temp[0]++// 第三遍   temp=[2,0,0,0]    ans+=2   temp[0]++// 第四遍   temp=[3,0,0,0]   ans+=3    temp[0]++public int numIdenticalPairs2(int[] nums) {int cnt = 0;int[] ret = new int[101];for(int x : nums) {cnt += ret[x];ret[x]++;}return cnt;}// 暴力public int numIdenticalPairs1(int[] nums) {int cnt = 0;for (int i = 0; i < nums.length; i++) {for (int j = i + 1; j < nums.length; j++) {if(nums[i] == nums[j]) {cnt++;}}}return cnt;}
}
617. 合并二叉树

添加链接描述
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

    // 非递归public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {if(root1 == null) return root2;if(root2 == null) return root1;TreeNode merged = new TreeNode(root1.val + root2.val);Queue<TreeNode> queue = new LinkedList<>(); // 合并的队列Queue<TreeNode> queue1 = new LinkedList<>();Queue<TreeNode> queue2 = new LinkedList<>();queue.offer(merged);queue1.offer(root1);queue2.offer(root2);while(!queue2.isEmpty() && !queue2.isEmpty()) {TreeNode node = queue.poll(), node1 = queue1.poll(), node2 = queue2.poll();TreeNode left1 = node1.left, left2 = node2.left;TreeNode right1 = node1.right, right2 = node2.right;if(left1 != null || left2 != null) {if(left1 != null && left2 != null) {TreeNode left = new TreeNode(left1.val + left2.val);node.left = left;queue.offer(left);queue1.offer(left1);queue2.offer(left2);} else if (left1 != null) {node.left = left1;} else if (left2 != null) {node.left = left2;}}if(right1 != null || right2 != null) {if(right1 != null && right2 != null) {TreeNode right = new TreeNode(right1.val + right2.val);node.right = right;queue.offer(right);queue1.offer(right1);queue2.offer(right2);} else if (right1 != null) {node.right = right1;} else if (right2 != null) {node.right = right2;}}}return merged;}// 递归public TreeNode mergeTrees1(TreeNode root1, TreeNode root2) {if(root1 == null) {return root2;}if(root2 == null) {return root1;}TreeNode root = new TreeNode(root1.val + root2.val);root.left = mergeTrees(root1.left, root2.left);root.right = mergeTrees(root1.right, root2.right);return root;}
}
844. 比较含退格的字符串

添加链接描述
给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,请你判断二者是否相等。# 代表退格字符。

如果相等,返回 true ;否则,返回 false 。

注意:如果对空文本输入退格字符,文本继续为空。

示例 1:
输入:s = “ab#c”, t = “ad#c”
输出:true
解释:S 和 T 都会变成 “ac”。

class Solution {// 指针 逆序遍历// 定义 skip 意为需要跳过的字符数量,skip != 0 跳过当前字符// 直到两字符串能够各自确定一个字符,然后将这两个字符进行比较public static boolean backspaceCompare(String s, String t) {int i = s.length() - 1;int j = t.length() - 1;int skip1 = 0;int skip2 = 0;while(i >= 0 || j >= 0) {while(i >= 0) {if(s.charAt(i) == '#') { // 需要跳过的字符+1skip1++;i--;} else if(skip1 > 0) { // 跳过skip1--;i--;} else {break; // 不需要删的字符 出去比较是否相等}}while(j >= 0) {if(t.charAt(j) == '#') {skip2++;j--;} else if(skip2 > 0) {skip2--;j--;} else {break;}}if(i >= 0 && j >= 0) {if(s.charAt(i) != t.charAt(j)) { // 字符不相等return false;}} else {if(i >= 0 || j >= 0) { // 有一个遍历完return false;}}i--;j--;}return true;}// 重构字符串// 退格符和应当被删除的字符都去除 比较两字符串是否相等public static boolean backspaceCompare2(String s, String t) {return build(s).equals(build(t));}public static String build(String str) {StringBuilder sb = new StringBuilder();for (int i = 0; i < str.length(); i++) {if(str.charAt(i) != '#') {sb.append(str.charAt(i));}  else {if(sb.length() > 0) {sb.deleteCharAt(sb.length() - 1); // 删除最后一个下标的元素}}}return sb.toString();}// 栈public boolean backspaceCompare1(String s, String t) {Stack<Character> stack1 = new Stack<>();Stack<Character> stack2 = new Stack<>();int len = Math.max(s.length(), t.length());for (int i = 0; i < len; i++) {if(i < s.length()) {if(s.charAt(i) != '#') {stack1.push(s.charAt(i));} else if (s.charAt(i) == '#' && !stack1.empty()) { // 退格 栈不为空stack1.pop();}}if(i < t.length()) {if(t.charAt(i) != '#') {stack2.push(t.charAt(i));} else if (t.charAt(i) == '#' && !stack2.empty()){stack2.pop();}}}if(stack1.size() != stack2.size()) {return false;}int size = stack1.size(); // for (int i = 0; i < size; i++) {if(stack1.pop() != stack2.pop()) {return false;}}return true;}
}
933. 最近的请求次数

添加链接描述

class RecentCounter {// 存3002的时候删除1,因为1不在[2,3002]之间,而100,3001,3002都是在[2,3002]之间,返回siz为3;Queue<Integer> que;public RecentCounter() {que = new LinkedList();}public int ping(int t) {que.offer(t);while(que.peek() < t - 3000) {que.poll();}return que.size();}
}
682. 棒球比赛

添加链接描述

你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。

比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:

整数 x - 表示本回合新获得分数 x
“+” - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。
“D” - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。
“C” - 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。
请你返回记录中所有得分的总和。

class Solution {public int calPoints(String[] ops) {int ans = 0;Stack<Integer> stack = new Stack<>();for (int i = 0; i < ops.length; i++) {String str = ops[i];if(str.equals("+")) {int num1 = stack.pop();int num2 = stack.peek(); // 前第二个stack.push(num1); // 重新加入stack.push(num1 + num2);ans += stack.peek();} else if (str.equals("D")) {stack.push(stack.peek() * 2);              ans += stack.peek();} else if (str.equals("C")) {int ret = stack.pop();             ans -= ret;} else {// 是数字 -> 转数字 入栈stack.push(Integer.parseInt(str));ans += stack.peek();}}return ans;}
}
1716. 计算力扣银行的钱

添加链接描述

Hercy 想要为购买第一辆车存钱。他 每天 都往力扣银行里存钱。
最开始,他在周一的时候存入 1 块钱。从周二到周日,他每天都比前一天多存入 1 块钱。在接下来每一个周一,他都会比 前一个周一 多存入 1 块钱。
给你 n ,请你返回在第 n 天结束的时候他在力扣银行总共存了多少块钱。

示例 1:
输入:n = 4
输出:10
解释:第 4 天后,总额为 1 + 2 + 3 + 4 = 10 。

class Solution {/*每周多 7 块,因此每周的钱之和的序列是一个等差数列,等差数列求和公式求所有完整周剩下的天数里,每天存的钱也是一个等差数列,可以用相同的公式进行求和。两者相加*/public int totalMoney(int n) {// 所有完整周int week = n / 7;int firstWeek = (1 + 7) * 7 / 2; // 每周多7int lastWeek = firstWeek + 7 * (week - 1);int weekMoney = (firstWeek + lastWeek) * week / 2;// 剩下不足一周int day = n % 7;int firstDay = 1 + week; // 最后一周周一int lastDay = firstDay + day - 1;int dayMoney = (firstDay + lastDay) * day / 2;return weekMoney + dayMoney;}public int totalMoney1(int n) {int week = 0;int day = 1;int ans = 0;for(int i = 0; i < n; i++) {ans += week + day;day++; // 每天if(day == 8) { // 每一周day = 1;week++;}}return ans;}
}
747. 至少是其他数字两倍的最大数

添加链接描述

class Solution {// 最大值 m1,和次大值 m2,如果 m1 >= m2*2,同时记录 m1 下标public int dominantIndex(int[] nums) {int m1 = -1;int m2 = -1;int index = -1;for (int i = 0; i < nums.length; i++) {if(nums[i] > m1) {m2 = m1;m1 = nums[i];index = i;} else if(nums[i] > m2) {m2 = nums[i];}}return m1 >= m2 * 2 ? index : -1;}public int dominantIndex1(int[] nums) {// 用array找maxint[] array = new int[nums.length];for(int i = 0; i < nums.length; i++) {array[i] = nums[i];}Arrays.sort(array);int max = array[array.length - 1];int index = 0; // 记录下标int flag = 0;for (int i = 0; i < nums.length; i++) {            if(nums[i] == max) {flag++;index = i;}else if(nums[i] * 2 > max) {return -1;}if(flag > 1) { // 不止一个最大数return -1;}}return index;}
}
334. 递增的三元子序列

添加链接描述
给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。
如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false 。

示例 1:
输入:nums = [1,2,3,4,5]
输出:true
解释:任何 i < j < k 的三元组都满足题意

class Solution {public boolean increasingTriplet1(int[] nums) {int n = nums.length;if(n < 3) {return false;}// leftMin[i] 表示 nums[0] 到 nums[i] 中的最小值,int[] leftMin = new int[n];leftMin[0] = nums[0];for (int i = 1; i < n; i++) {leftMin[i] = Math.min(leftMin[i - 1], nums[i]);}// rightMax[i] 表示 nums[i] 到 nums[n−1] 中的最大值。int[] rightMax = new int[n];rightMax[n - 1] = nums[n - 1];for (int i = n - 2; i >= 0; i--) {rightMax[i] = Math.max(rightMax[i + 1], nums[i]);}// 查找是否存在一个下标 i 满足 leftMin[i−1] < nums[i] < rightMax[i + 1]for (int i = 1; i < n - 1; i++) {if(leftMin[i - 1] < nums[i] && nums[i] < rightMax[i + 1]) {return true;}}return false;}// 赋初始值的时候,已经满足second > first了,现在找第三个数third// (1) 如果third比second大,那就是找到了,直接返回true// (2) 如果third比second小,但是比first大,那就把second的值设为third,然后继续遍历找thrid// (3) 如果third比first还小,那就把first的值设为third,然后继续遍历找thrid// (这样的话first会跑到second的后边,但是不要紧,因为在second的前边,老first还是满足的)public static boolean increasingTriplet(int[] nums) {int n = nums.length;if(n < 3) {return false;}int first = nums[0];int second = Integer.MAX_VALUE;for (int i = 1; i < n; i++) {int num = nums[i];if(num > second) {return true;} else if (num >first) { // 比second小 比first大second  = num;} else {first = num; // 比first小}}return false;}
}
1920. 基于排列构建数组

添加链接描述
给你一个 从 0 开始的排列 nums(下标也从 0 开始)。请你构建一个 同样长度 的数组 ans ,其中,对于每个 i(0 <= i < nums.length),都满足 ans[i] = nums[nums[i]] 。返回构建好的数组 ans 。
从 0 开始的排列 nums 是一个由 0 到 nums.length - 1(0 和 nums.length - 1 也包含在内)的不同整数组成的数组。

示例 1:
输入:nums = [0,2,1,5,3,4]
输出:[0,1,2,4,5,3]

class Solution {// 在原数组更改public int[] buildArray(int[] nums) {// 范围 [0, 999]  用%1000取原值// 最终值 原数值for(int i = 0; i < nums.length; i++) {nums[i] += 1000 * (nums[nums[i]] % 1000);}for(int i = 0; i < nums.length; i++) {nums[i] /= 1000;}return nums;}public int[] buildArray1(int[] nums) {int[] ans = new int[nums.length];for(int i = 0; i < nums.length; i++) {ans[i] = nums[nums[i]];}return ans;}
}

1629. 按键持续时间最长的键

添加链接描述

class Solution {public char slowestKey(int[] releaseTimes, String keysPressed) {// 字符 时间 都初识为第一个char ans = keysPressed.charAt(0);int time = releaseTimes[0];for(int i = 1; i < releaseTimes.length; i++) {int nextTime = releaseTimes[i] - releaseTimes[i - 1]; // 下一个持续时间if(time < nextTime) {// 下一个持续时间更长 更新字符与时间ans = keysPressed.charAt(i);time = nextTime;}else if(time == nextTime && ans < keysPressed.charAt(i)) {// 时间相同 比较字符大小是否需要更新 c>bans = keysPressed.charAt(i);}}return ans;}
}
89. 格雷编码

添加链接描述

class Solution {// 如果二进制码字的第i位和i+1位相同,则对应的格雷码的第i位为0,否则为1public List<Integer> grayCode(int n) {List<Integer> list = new ArrayList<>();for(int i = 0; i < 1 << n; i++) { // 2^nlist.add((i >> 1) ^ i);}return list;}/*1位格雷码有两个码字(n+1)位格雷码中的前2^n个码字等于n位格雷码的码字,按顺序书写,加前缀0(n+1)位格雷码中的后2^n个码字等于n位格雷码的码字,按逆序书写,加前缀1n+1位格雷码的集合 = n位格雷码集合(顺序)加前缀0 + n位格雷码集合(逆序)加前缀1*/// n 位的格雷码序列 等于 (n-1) 位的格雷码序列 并上 (n-1) 位的格雷码序列倒序前面加1的结果// 3位的格雷码 [000, 001, 011, 010] | [110, 111, 101, 100]public List<Integer> grayCode1(int n) {List<Integer> list = new ArrayList<>();list.add(0);if(n < 1) {return list;}int head = 1;for (int i = 0; i < n; i++) {// 逆序 每一层for (int j = list.size() - 1; j >= 0; j--) {list.add(head + list.get(j));}// 每一层 左移一位head <<= 1;}return list;}
}
976. 三角形的最大周长

添加链接描述
给定由一些正数(代表长度)组成的数组 A,返回由其中三个长度组成的、面积不为零的三角形的最大周长。
如果不能形成任何面积不为零的三角形,返回 0。

示例 1:
输入:[2,1,2]
输出:5

class Solution {// 排序 // a + b > c  找 c 前面符合条件的a b最大值public int largestPerimeter(int[] nums) {Arrays.sort(nums);for(int i = nums.length - 1; i >= 2; --i) {if(nums[i - 2] + nums[i - 1] > nums[i]) {return nums[i - 2] + nums[i - 1] + nums[i];}}return 0;}
}
495. 提莫攻击

添加链接描述
当提莫攻击艾希,艾希的中毒状态正好持续 duration 秒。
正式地讲,提莫在 t 发起发起攻击意味着艾希在时间区间 [t, t + duration - 1](含 t 和 t + duration - 1)处于中毒状态。如果提莫在中毒影响结束 前 再次攻击,中毒状态计时器将会 重置 ,在新的攻击之后,中毒影响将会在 duration 秒后结束。
给你一个 非递减 的整数数组 timeSeries ,其中 timeSeries[i] 表示提莫在 timeSeries[i] 秒时对艾希发起攻击,以及一个表示中毒持续时间的整数 duration 。
返回艾希处于中毒状态的 总 秒数。

示例 1:
输入:timeSeries = [1,4], duration = 2
输出:4
解释:提莫攻击对艾希的影响如下:

  • 第 1 秒,提莫攻击艾希并使其立即中毒。中毒状态会维持 2 秒,即第 1 秒和第 2 秒。
  • 第 4 秒,提莫再次攻击艾希,艾希中毒状态又持续 2 秒,即第 4 秒和第 5 秒。
    艾希在第 1、2、4、5 秒处于中毒状态,所以总中毒秒数是 4 。
class Solution {// 未中毒状态,加duration,更新中毒结束时间expired,本次中毒结束时间timeSeries[i]+duration// 中毒状态,本次中毒结束时间 - 上次中毒时间expiredpublic int findPoisonedDuration(int[] timeSeries, int duration) {int anx = 0; // 每次中毒时间总和int expired = 0; // 中毒结束时间for(int i = 0; i < timeSeries.length; i++) {if(timeSeries[i] >= expired) { // 未中毒anx += duration;}else { // 中毒anx += timeSeries[i] + duration - expired;}expired = timeSeries[i] + duration; // 加每次中毒时间}return anx;}
}
剑指 Offer 61. 扑克牌中的顺子

从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
示例 1:
输入: [1,2,3,4,5]
输出: True

class Solution {// 排序// 相邻判断重复 末位为max 最后一个0后为minpublic boolean isStraight(int[] nums) {int joker = 0;Arrays.sort(nums);for(int i = 0; i < 4; i++) {if(nums[i] == 0) { // 大小王的数量joker++;} else if(nums[i] == nums[i + 1]) { // 有重复return false;}}return nums[4] - nums[joker] < 5;}// 除大小王 没有重复牌// max - min < 5public boolean isStraight1(int[] nums) {HashSet<Integer> set = new HashSet<>();int max = 0; // int min = 14; // for(int i = 0; i < 5; i++) {if(nums[i] == 0) { // 跳过大小王continue;}if(set.contains(nums[i])) { // 有重复return false;}set.add(nums[i]);max = Math.max(max, nums[i]); // 最大min = Math.min(min, nums[i]); // 最小}return max - min < 5;}
}
1646. 获取生成数组中的最大值

添加链接描述

class Solution {public int getMaximumGenerated(int n) {if(n < 2) {return n;}int max = 1;int[] nums = new int[n + 1];// nums[0] = 0;nums[1] = 1;for (int i = 2; i <= n; i++) {nums[i] = nums[i / 2] +i % 2 * nums[i / 2 + 1]; // 奇数判断为0/*if(i % 2 == 0) { // 偶数->[i/2]nums[i] = nums[i / 2];}else { // 奇数->[i/2] + [i/2+1]nums[i] = nums[i / 2] + nums[i / 2 + 1];}*/max = Math.max(max, nums[i]);}return max;}
}
1614. 括号的最大嵌套深度

添加链接描述

class Solution {public int getMaximumGenerated(int n) {if(n < 2) {return n;}int max = 1;int[] nums = new int[n + 1];// nums[0] = 0;nums[1] = 1;for (int i = 2; i <= n; i++) {nums[i] = nums[i / 2] +i % 2 * nums[i / 2 + 1]; // 奇数判断为0/*if(i % 2 == 0) { // 偶数->[i/2]nums[i] = nums[i / 2];}else { // 奇数->[i/2] + [i/2+1]nums[i] = nums[i / 2] + nums[i / 2 + 1];}*/max = Math.max(max, nums[i]);}return max;}
}
119. 杨辉三角 II

添加链接描述

class Solution {/*递推:一行一行地计算,计算到需要的那一行,返回第一行只有一个数:1首尾:都是1。中间的数:获取上一行的两个数相加计算完一行加入C,计算到rowIndex,返回C的rowIndex*/public List<Integer> getRow1(int rowIndex) {List<List<Integer>> C  = new ArrayList<>();for (int i = 0; i <= rowIndex; i++) {List<Integer> row = new ArrayList<>();for (int j = 0; j <= i; j++) {if(j == 0 || j == i) {row.add(1);} else {row.add(C.get(i - 1).get(j - 1) + C.get(i - 1).get(j));}}C.add(row);}return C.get(rowIndex);}// 只需要上一行 每次更新即可public List<Integer> getRow2(int rowIndex) {List<Integer> prev = new ArrayList<>();for(int i = 0; i <= rowIndex; i++) {List<Integer> cur = new ArrayList<>();for(int j = 0; j <= i; j++) {if(j == 0 || j == i) {cur.add(1);} else {cur.add(prev.get(j - 1) + prev.get(j));}}prev = cur;}return prev;}// 从后往前加 每次加给jpublic List<Integer> getRow(int rowIndex) {List<Integer> row = new ArrayList<>();row.add(1);for(int i = 1; i <= rowIndex; i++) {row.add(0);for(int j = i; j > 0; j--) {row.set(j, row.get(j - 1) + row.get(j)); // j的位置更新}}return row;}
}

1576. 替换所有的问号

添加链接描述
给你一个仅包含小写英文字母和 ‘?’ 字符的字符串 s,请你将所有的 ‘?’ 转换为若干小写字母,使最终的字符串不包含任何 连续重复 的字符。

示例 1:
输入:s = “?zs”
输出:“azs”
解释:该示例共有 25 种解决方案,从 “azs” 到 “yzs” 都是符合题目要求的。只有 “z” 是无效的修改,因为字符串 “zzs” 中有连续重复的两个 ‘z’ 。

class Solution {public String modifyString(String s) {char[] array = s.toCharArray();int len = array.length;for (int i = 0; i < len; i++) {// if(!Character.isLetter(array[i])) { // 不是字母if(array[i] == '?') {for (char ch = 'a'; ch <= 'c'; ch++) { // 用 a b c 判断if((i > 0 && array[i - 1] == ch) || (i < len - 1 && array[i + 1] == ch)) {continue; // 判断前 判断后}array[i] = ch;break;}}}return new String(array);}
}
1185. 一周中的第几天

添加链接描述
给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。
输入为三个整数:day、month 和 year,分别表示日、月、年。
您返回的结果必须是这几个值中的一个 {“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”}。

示例 1:
输入:day = 31, month = 8, year = 2019
输出:“Saturday”

class Solution {public String dayOfTheWeek(int day, int month, int year) {String[] weeks = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int days = 0;for(int i = 1971; i < year; i++) {days += (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) ? 366 : 365;}if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {monthDays[1] = 29;}for(int i = 0; i < month - 1; i++) {days += monthDays[i];}days += day;return weeks[(days + 3) % 7];}public String dayOfTheWeek2(int day, int month, int year) {String[] weeks = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};// 当前年份之前的天数int days = 0;for(int i = 1971; i < year; i++) {days += isRun(i) ? 366 : 365; // 闰年}// 当前年为闰年 -> 二月加一天if(isRun(year)) {monthDays[1] = 29;}// 当前月份之前的天数for(int i = 0; i < month - 1; i++) {days += monthDays[i];}// 当前月份的天数days += day;return weeks[(days + 3) % 7];}public static boolean isRun(int year) {return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);}// 1970年12月31日->星期四,算出输入的日期距离1970年12月31日有几天,再加上3后对7求余/* 求输入的日期距离 19701970 年 1212 月 3131 日的天数,可以分为三部分分别计算后求和:(1)输入年份之前的年份的天数贡献;(2)输入年份中,输入月份之前的月份的天数贡献;(3)输入月份中的天数贡献。例如,如果输入是 21002100 年 1212 月 3131 日,即可分为三部分分别计算后求和:(1)19711971 年 11 月 11 到 20992099 年 1212 月 3131 日之间所有的天数;(2)21002100 年 11 月 11 日到 21002100 年 1111 月 3131 日之间所有的天数;(3)21002100 年 1212 月 11 日到 21002100 年 1212 月 3131 日之间所有的天数。*/public String dayOfTheWeek1(int day, int month, int year) {String[] weeks = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};// 当前年份之前的天数int days  = 365 * (year - 1971) + (year - 1969) / 4; // 加闰年// 当前月份之前的天数for(int i = 0; i < month - 1; i++) {days += monthDays[i];}if((year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) && month >= 3) {days += 1;}// 当前月份的天数days += day;return weeks[(days + 3) % 7];}
}
930. 和相同的二元子数组

添加链接描述
给你一个二元数组 nums ,和一个整数 goal ,请你统计并返回有多少个和为 goal 的 非空 子数组。
子数组 是数组的一段连续部分。

示例 1:
输入:nums = [1,0,1,0,1], goal = 2
输出:4
解释:
有 4 个满足题目要求的子数组:[1,0,1]、[1,0,1,0]、[0,1,0,1]、[1,0,1]

class Solution {// 滑动窗口public int numSubarraysWithSum(int[] nums, int goal) {int cnt = 0;int len = nums.length;int left1 = 0, left2 = 0, right = 0, sum1 = 0, sum2 = 0;while(right < len) {sum1 += nums[right];while(left1 <= right && sum1 > goal) {sum1 -= nums[left1];left1++;}sum2 += nums[right];while(left2 <= right && sum2 >= goal) {sum2 -= nums[left2];left2++;}cnt += left2 - left1;right++;}return cnt;}// 滑动窗口  本题只有0/1public int numSubarraysWithSum4(int[] nums, int goal) {int cnt = 0;int len = nums.length;for(int left = 0; left < len; left++) {if(nums[left] > goal) {continue;}int sum = nums[left];if(sum == goal) { // 单个数cnt++;}int right = left + 1;while(right < len && sum <= goal) {sum += nums[right];if(sum == goal) {cnt++;if(right + 1 < len && nums[right + 1] != 0) {break; // 下一个为1 大于goal 提前结束本次循环}}right++; // }}return cnt;}// 数组public int numSubarraysWithSum3(int[] nums, int goal) {int cnt = 0;int sum = 0;int[] array = new int[nums.length + 1];for(int i : nums) {array[sum]++;sum += i;if(sum - goal >= 0) {cnt += array[sum - goal];}}return cnt;}// 哈希表 前缀和public int numSubarraysWithSum2(int[] nums, int goal) {int cnt = 0;int prevsum = 0;HashMap<Integer, Integer> map = new HashMap<>();/*map.put(0, 1); // 前缀和为0for(int num : nums) {prevsum += num; // [0,0,0,0,0] 0 -->15cnt += map.getOrDefault(prevsum - goal, 0);map.put(prevsum, map.getOrDefault(prevsum, 0) + 1);}*/for(int num : nums) {map.put(prevsum, map.getOrDefault(prevsum, 0) + 1);prevsum += num;cnt += map.getOrDefault(prevsum - goal, 0);}return cnt;}// 双循环public int numSubarraysWithSum1(int[] nums, int goal) {int cnt = 0;int n = nums.length;for(int i = 0; i < n; i++) {int sum = nums[i];if(sum == goal) {cnt++;}for(int j = i + 1; j < n; j++) {sum += nums[j];if(sum == goal) {cnt++;}}}return cnt;}
}
390. 消除游戏

添加链接描述
列表 arr 由在范围 [1, n] 中的所有整数组成,并按严格递增排序。请你对 arr 应用下述算法:

从左到右,删除第一个数字,然后每隔一个数字删除一个,直到到达列表末尾。
重复上面的步骤,但这次是从右到左。也就是,删除最右侧的数字,然后剩下的数字每隔一个删除一个。
不断重复这两步,从左到右和从右到左交替进行,直到只剩下一个数字。
给你整数 n ,返回 arr 最后剩下的数字。

示例 1:
输入:n = 9
输出:6
解释:
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
arr = [2, 4, 6, 8]
arr = [2, 6]
arr = [6]

class Solution {// https://leetcode.com/problems/elimination-game/discuss/87119/JAVA%3A-Easiest-solution-O(logN)-with-explanationpublic int lastRemaining(int n) {int head = 1; // n为1时 head就是最后一个数int step = 1;boolean left = true;while(n > 1) {// 从左移除(奇数->从右移除)if(left || n % 2 == 1) {head += step;}step *= 2; // 步长left = !left; // 反向n /= 2; // 减少一半}return head;}
}
461. 汉明距离

添加链接描述
两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。

给你两个整数 x 和 y,计算并返回它们之间的汉明距离。

class Solution {public int hammingDistance(int x, int y) {return Integer.bitCount(x ^ y);}public int hammingDistance3(int x, int y) {int cnt = 0;int s = x ^ y;while(s != 0) {s &= s - 1; // 取出最低位的 1cnt++;}return cnt;}public int hammingDistance2(int x, int y) {int cnt = 0;int s = x ^ y; // 统计不同位个数while(s != 0) {cnt += s & 1;s >>= 1;}return cnt;}public int hammingDistance1(int x, int y) {int cnt = 0;for(int i = 0; i < 32; i++) {cnt += (x & 1) ^ (y & 1); // x y 最低位判断相等x >>>= 1;y >>>= 1;}return cnt;}
}
405. 数字转换为十六进制数

添加链接描述
示例:
输入:
26
输出:
“1a”

class Solution {// 分组 4个8组public String toHex(int num) {if(num == 0) {return "0";}StringBuilder sb = new StringBuilder();for(int i = 7; i >= 0; --i) {int ret = (num >> (4 * i)) & 15; // 正向转if(sb.length() > 0 || ret > 0) { // 零和正整数,可能出现前导零char c = ret < 10 ? (char)(ret + '0') : (char)(ret - 10 + 'a');sb.append(c);}}return sb.toString();/*while(num != 0) {int ret = num & 15; // 每4位char c = (char)(ret + '0');if(ret >= 10) {c = (char)(ret - 10 + 'a');}sb.append(c);num >>>= 4; // 无符号右移}return sb.reverse().toString();*/}// 位运算 %16 /16public String toHex1(int num2) {if(num2 == 0) {return "0";}long num = num2;if(num < 0) {num = (long)(Math.pow(2, 32) + num); // 负数 加2^32偏移量}StringBuilder sb = new StringBuilder();while(num != 0) {long ret = num % 16;char c  = (char)(ret + '0');if(ret >= 10) {c = (char)(ret - 10 + 'a'); // abcdef}sb.append(c);num /=  16;}/*String letter = "abcdef";while(num != 0) {int ret = (int)(num % 16);if(ret >= 10) {sb.append(letter.charAt(ret-10));} else {sb.append(ret);}num /= 16;}*/return sb.reverse().toString();}
}
2022. 将一维数组转变成二维数组

添加链接描述

class Solution {public int[][] construct2DArray(int[] original, int m, int n) {if(original.length != m * n) {return new int[0][];}int[][] ans = new int[m][n];for(int i = 0; i < original.length; i += n) {System.arraycopy(original, i, ans[i / n], 0, n);}/*for(int i = 0; i < original.length; i++) {ans[i / n][i % n] = original[i];}*//*int k = 0;for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {ans[i][j] = original[k++];}}*/return ans;}
}
1160. 拼写单词

添加链接描述
给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。
注意:每次拼写(指拼写词汇表中的一个单词)时,chars 中的每个字母都只能用一次。
返回词汇表 words 中你掌握的所有单词的 长度之和。

示例 1:
输入:words = [“cat”,“bt”,“hat”,“tree”], chars = “atach”
输出:6
解释:
可以形成字符串 “cat” 和 “hat”,所以答案是 3 + 3 = 6。

class Solution {// 哈希表  统计chars字符个数 与 words每个单词字符个数 小于 加长度public int countCharacters(String[] words, String chars) {HashMap<Character, Integer> charsCnt = new HashMap<>();int len = chars.length();for (int i = 0; i < len; i++) { // 1、chars字符次数char c = chars.charAt(i);charsCnt.put(c, charsCnt.getOrDefault(c, 0) + 1);}int ans = 0;for (String word : words) { // 2、遍历words单词HashMap<Character, Integer> wordCnt = new HashMap<>();int wordLength = word.length(); // 每个单词长度for (int i = 0; i < wordLength; i++) {char c = word.charAt(i);wordCnt.put(c, wordCnt.getOrDefault(c, 0) + 1); // 统计每个单词的字符次数}boolean isAns = true;for (int i = 0; i < wordLength; i++) {char c = word.charAt(i);if(charsCnt.getOrDefault(c, 0) < wordCnt.getOrDefault(c, 0)) { // 小于isAns = false;break;}}if(isAns) {ans += word.length();}}/*for (int i = 0; i < words.length; i++) { // 2、遍历words单词HashMap<Character, Integer> wordCnt = new HashMap<>();for (int j = 0; j < words[i].length(); j++) { // 加入每个字符char c = words[i].charAt(j);wordCnt.put(c, wordCnt.getOrDefault(c, 0) + 1);}boolean isAns = true;for (int j = 0; j < words[i].length(); j++) {char c = words[i].charAt(j);if(charsCnt.getOrDefault(c, 0) < wordCnt.getOrDefault(c, 0)) { // 字符小于isAns = false;break;}}if(isAns) {ans += words[i].length();}}*/return ans;}
}
1995. 统计特殊四元组

添加链接描述
给你一个 下标从 0 开始 的整数数组 nums ,返回满足下述条件的 不同 四元组 (a, b, c, d) 的 数目 :
nums[a] + nums[b] + nums[c] == nums[d] ,且
a < b < c < d

示例 1:
输入:nums = [1,2,3,6]
输出:1
解释:满足要求的唯一一个四元组是 (0, 1, 2, 3) 因为 1 + 2 + 3 == 6 。

class Solution {// 4、数组public int countQuadruplets(int[] nums) {int[] cache = new int[201];int cnt = 0;for (int i = 2; i < nums.length; i++) {for (int j = 0; j < i - 1; j++) {cache[nums[i - 1] + nums[j]]++;}for (int j = i + 1; j < nums.length; j++) {int diff = nums[j] - nums[i];cnt += diff >= 0 ? cache[diff] : 0;}}return cnt;}// 3、d-c// nums[a]+nums[b]=nums[d]−nums[c]public int countQuadruplets3(int[] nums) {int cnt = 0;int n = nums.length;HashMap<Integer, Integer> map = new HashMap<>();for (int b = n - 3; b >= 1; --b) {// nums[d]−nums[c] 出现的次数for (int d = b + 2; d < n; d++) {map.put(nums[d] - nums[b + 1], map.getOrDefault(nums[d] - nums[b + 1], 0) + 1);}for (int a = 0; a < b; a++) {cnt += map.getOrDefault(nums[a] + nums[b], 0);}}return cnt;}// 2、哈希表public int countQuadruplets2(int[] nums) {int cnt = 0;int n = nums.length;HashMap<Integer, Integer> map = new HashMap<>();for (int i = n - 2; i >= 2; --i) {map.put(nums[i + 1], map.getOrDefault(nums[i + 1],0) + 1);for (int a = 0; a < i; a++) {for (int b = a + 1; b < i; b++) {cnt += map.getOrDefault(nums[a] + nums[b] + nums[i], 0);}}}return cnt;}//  1、暴力public int countQuadruplets1(int[] nums) {int cnt = 0;int n = nums.length;for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {for (int k = j + 1; k < n; k++) {for (int l = k + 1; l < n; l++) {if(nums[i] + nums[j] + nums[k] == nums[l]) {cnt++;}}}}}return cnt;}
}
290. 单词规律

添加链接描述
给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。

这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。

示例1:

输入: pattern = “abba”, str = “dog cat cat dog”
输出: true

class Solution {// 循环取字符串public static boolean wordPattern(String pattern, String str) {Map<String, Character> str2ch = new HashMap<>(); // 单词Map<Character, String> ch2str = new HashMap<>(); // 字符int i = 0; // i j 取str字符串for (int p = 0; p < pattern.length(); p++) {char ch = pattern.charAt(p); // 遍历pattern字符if(i >= str.length()) {return false;}int j = i;while(j < str.length() && str.charAt(j) != ' ') { // 跳过空白字符j++;}String tmp = str.substring(i, j); // 返回子字符串 [i, j) 取str一个单词if(str2ch.containsKey(tmp) && str2ch.get(tmp) != ch) {return false;}if(ch2str.containsKey(ch) && !tmp.equals(ch2str.get(ch))) {return false;}str2ch.put(tmp, ch);ch2str.put(ch, tmp);i = j + 1;}return i >= str.length();}// 哈希表  记录字符对应字符串 字符串对应字符public static boolean wordPattern2(String pattern, String str) {Map<String, Character> str2ch = new HashMap<>(); // 单词Map<Character, String> ch2str = new HashMap<>(); // 字符String[] strings = str.split(" "); // 分割if(strings.length != pattern.length()) { // 长度不想相等return false;}for (int i = 0; i < pattern.length(); i++) {char ch = pattern.charAt(i);if(str2ch.containsKey(strings[i]) && str2ch.get(strings[i]) != ch) { // 判断字符串对应的字符return false;}if(ch2str.containsKey(ch) && !strings[i].equals(ch2str.get(ch))) { // 判断字符对应的字符串return false;}str2ch.put(strings[i], ch);ch2str.put(ch, strings[i]);}return true;}// int i -- > java 自动装箱,转成 Integer// put 返回的是一个 Integer// 判断对象相等的话,相当于判断的是引用的地址,即使 Integer 包含的值相等,也不会相等// 如果key不存在,插入成功,返回null;如果key存在,返回之前对应的valuepublic boolean wordPattern1(String pattern, String str) {String[] words = str.split(" ");if(pattern.length() != words.length) {return false;}Map<Object, Integer> map = new HashMap<>();for (Integer i = 0; i < words.length; i++) {if(map.put(words[i], i) != map.put(pattern.charAt(i), i)) {return false;}}return true;}
}
242. 有效的字母异位词

添加链接描述
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true

class Solution {// Unicode 哈希表public boolean isAnagram(String s, String t) {if(s.length() != t.length()) {return false;}HashMap<Character, Integer> map = new HashMap<>();for (int i = 0; i < s.length(); i++) {map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);}for (int i = 0; i < t.length(); i++) {map.put(t.charAt(i), map.getOrDefault(t.charAt(i), 0) - 1);if(map.get(t.charAt(i)) < 0) {return false;}}return true;}// 记录字母次数public boolean isAnagram2(String s, String t) {if(s.length() != t.length()) {return false;}int[] table = new int[26];for (int i = 0; i < s.length(); i++) {table[s.charAt(i) - 'a']++;}for (int i = 0; i < t.length(); i++) {table[t.charAt(i) - 'a']--;if(table[t.charAt(i) - 'a'] < 0) { // 为负return false;}}return true;}// 转字符数组 排序public boolean isAnagram1(String s, String t) {if(s.length() != t.length()) {return false;}char[] ret1 = s.toCharArray();char[] ret2 = t.toCharArray();Arrays.sort(ret1);Arrays.sort(ret2);return Arrays.equals(ret1, ret2);}
}
167. 两数之和 II - 输入有序数组

添加链接描述
给定一个已按照 非递减顺序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

class Solution {// mappublic int[] twoSum(int[] numbers, int target) {Map<Integer, Integer> map = new HashMap<>();for(int i = 0; i < numbers.length; i++) {if(map.containsKey(target - numbers[i])) {return new int[]{map.get(target- numbers[i]), i+1};}map.put(numbers[i], i + 1);}return new int[]{-1, -1};}// 双指针public int[] twoSum3(int[] numbers, int target) {for (int i = 0; i < numbers.length; i++) { // 一个int left = i + 1;int right = numbers.length - 1;while(left <= right) {int mid = (right - left) / 2 + left;if(numbers[mid] == target - numbers[i]) { // 另一个return new int[]{i+1, mid+1};}else if (numbers[mid] < target- numbers[i]) {left = mid + 1;}else {right = mid - 1;}}}return new int[]{-1, -1};}// 暴力public int[] twoSum1(int[] numbers, int target) {int ret = 0;int[] ans = new int[2];for (int i = 0; i < numbers.length; i++) {for (int j = i + 1; j < numbers.length; j++) {ret = numbers[i] + numbers[j];if(ret == target) {ans[0] = i+1;ans[1] = j+1;break;}}}return ans;}
}
125. 验证回文串

添加链接描述
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。

示例 1:
输入: “A man, a plan, a canal: Panama”
输出: true
解释:“amanaplanacanalpanama” 是回文串

class Solution {// 原字符串 指针 比较public boolean isPalindrome(String s) {int left = 0;int right = s.length() - 1;while(left < right) {while(left < right && !Character.isLetterOrDigit(s.charAt(left))) {left++;}while(left < right && !Character.isLetterOrDigit(s.charAt(right))) {right--;}if(left < right) {if(Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) {return false;}left++;right--;}}return true;}// 字符数字拿出 1、函数判断public boolean isPalindrome1(String s) {StringBuilder ret = new StringBuilder();for(int i = 0; i < s.length(); i++) {char ch = s.charAt(i);if(Character.isLetterOrDigit(ch)) { // 同时判断字符数字ret.append(Character.toLowerCase(ch));}}StringBuilder retReverse = new StringBuilder(ret).reverse();return retReverse.toString().equals(ret.toString());}// 字符数字拿出 1、双指针判断public boolean isPalindrome2(String s) {StringBuilder ret = new StringBuilder();for(int i = 0; i < s.length(); i++) {char ch = s.charAt(i);if(Character.isLetterOrDigit(ch)) { // 同时判断字符数字ret.append(Character.toLowerCase(ch));}}int len = ret.length();int left = 0;int right = len - 1;while(left < right) {if(ret.charAt(left++) != ret.charAt(right--)) {return false;}}return true;}
}
229. 求众数 II

添加链接描述
给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。

示例 1:
输入:[3,2,3]
输出:[3]

class Solution {// 3、摩尔投票算法// 找3/n,最多只有两个。相同->加一,不相同->抵消public List<Integer> majorityElement(int[] nums) {// 初始化两个候选人和机票int cand1 = 0;int cand2 = 0;int vote1 = 0;int vote2 = 0;//for(int num : nums) {if(vote1 > 0 && num == cand1) { // 该元素是第一个元素 机票加一vote1++;} else if (vote2 > 0 && num == cand2) { // 该元素是第二个元素 机票加一vote2++;} else if (vote1 == 0) { // 第一个元素cand1 = num;vote1++;} else if (vote2 == 0) { // 第二个元素cand2 = num;vote2++;} else { // 三个都不相等 都抵消vote1--;vote2--;}}// 判断机票是否 > len/3int cnt1 = 0 ;int cnt2 = 0 ;for(int num : nums) {if(vote1 > 0 && num == cand1) {cnt1++;}if(vote2 > 0 && num == cand2) {cnt2++;}}List<Integer> list = new ArrayList<>();if(vote1 > 0 && cnt1 > nums.length / 3) {list.add(cand1);}if(vote2 > 0 && cnt2 > nums.length / 3) {list.add(cand2);}return list;}// 2、哈希表 记录次数public List<Integer> majorityElement2(int[] nums) {List<Integer> list = new ArrayList<>();HashMap<Integer, Integer> set = new HashMap<>();for(int n : nums) {set.put(n, set.getOrDefault(n, 0) + 1);}for (int n : set.keySet()) {if(set.get(n) > nums.length / 3) {list.add(n);}}return list;}// 1、循环遍历次数 哈希去重public List<Integer> majorityElement1(int[] nums) {List<Integer> list = new ArrayList<>();HashSet<Integer> set = new HashSet<>();if(nums.length <= 2) {list.add(nums[0]);if(nums.length == 2) {if(nums[0] != nums[1]) { // 避免重复list.add(nums[1]);}}return list;}Arrays.sort(nums);int cnt = 1;for (int i = 0; i < nums.length - 1; i++) {if(nums[i] == nums[i+1]) {cnt++;} else {cnt = 1;}if(cnt > nums.length / 3) { // >if(set.add(nums[i])) {list.add(nums[i]); // 避免重复}cnt = 1;}}return list;}
}
169. 多数元素

添加链接描述
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:
输入:[3,2,3]
输出:3

class Solution {// 摩尔投票算法// 多数元素的次数>n/2 其余<n/2 相减>=1/*候选人(cand_num)初始化为nums[0],票数count初始化为1。当遇到与cand_num相同的数,则票数count = count + 1,否则票数count = count - 1。当票数count为0时,更换候选人,并将票数count重置为1。遍历完数组后,cand_num即为最终答案。*/public int majorityElement(int[] nums) {int cand = nums[0];int cnt = 0;for(int n : nums) {if(cnt == 0) {cand = n;}if(n == cand) {cnt++;}else {cnt--;}}// int cnt = 1;// for(int i = 1; i < nums.length; i++) {//     if(nums[i] == cand) {//         cnt++;//    } else if(--cnt == 0) { // 更新//         cand = nums[i];//         cnt = 1;//     }// }return cand;}// 排序 后半位置public int majorityElement2(int[] nums) {Arrays.sort(nums);return nums[nums.length / 2];}// 遍历 次数超过lenpublic int majorityElement1(int[] nums) {Arrays.sort(nums);int cnt = 0;for(int i = 0; i < nums.length - 1; i++) {if(nums[i] == nums[i+1]) {cnt++;}else {cnt = 0;}if(cnt >= (nums.length / 2)) {return nums[i];}}return nums[0];}
}
260. 只出现一次的数字 III

添加链接描述
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
示例 1:
输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。

class Solution {// 位运算public int[] singleNumber(int[] nums) {int sum = nums[0];for(int i = 1; i < nums.length; i++) {sum ^= nums[i];}// 取最低位 1  防溢出int lsb = sum == Integer.MIN_VALUE ? sum : sum & (-sum);int type1 = 0;int type2 = 0;// 为 0 为 1 分成两组for(int n : nums) {if((lsb & n) != 0) {type1 ^= n;}else {type2 ^= n;}}return new int[]{type1, type2};}// 异或 暴力查找public int[] singleNumber1(int[] nums) {Arrays.sort(nums);int ret = nums[0];int len = nums.length;for(int i = 1; i < len; i++) {ret ^= nums[i];}for(int i = 0; i < len; i++) {for(int j = i + 1; j < len; j++) {if((nums[i] ^ nums[j]) == ret) {return new int[]{nums[i], nums[j]};}}}return new int[]{-1, -1};}
}
136. 只出现一次的数字

添加链接描述
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1

class Solution {// list  没有-加入 有-删除public int singleNumber(int[] nums) {ArrayList<Integer> list = new ArrayList<>();for(int n : nums) {if(list.contains(n)) {list.remove(Integer.valueOf(n)); // }else {list.add(n);}}return list.get(0);}// 哈希 存储次数public int singleNumber2(int[] nums) {HashMap<Integer, Integer> map = new HashMap<>();for(int n : nums)  { int cnt = map.getOrDefault(n, 0) + 1;map.put(n, cnt);}for(int i : map.keySet()) {if(map.get(i) == 1) {return i;}}return -1;}// 按位异或public int singleNumber1(int[] nums) {int single = nums[0];for(int i = 1; i < nums.length; i++) {single ^= nums[i];}return single;}
}
58. 最后一个单词的长度

添加链接描述
给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中最后一个单词的长度。
单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。

示例 1:
输入:s = “Hello World”
输出:5

class Solution {// 删除头尾空白字符串// 最后一次" "前  lastIndexOf 从后向前找子串public int lengthOfLastWord(String s) {return s.trim().length() - s.trim().lastIndexOf(" ") - 1;}// 最后一个单词 到前面的空格长度public int lengthOfLastWord1(String s) {int index = s.length() - 1;while(s.charAt(index) == ' ') {index--;}int wordLength = 0;while(index >= 0 &&s.charAt(index) != ' ') {wordLength++;index--;}return wordLength;}
}
13. 罗马数字转整数

添加链接描述
例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

class Solution {public int romanToInt(String s) {HashMap<Character, Integer> map = new HashMap<>();map.put('I', 1);map.put('V', 5);map.put('X', 10);map.put('L', 50);map.put('C', 100);map.put('D', 500);map.put('M', 1000);int ans = 0;int n = s.length();// 若一个数字右侧的数字比它大,则将该数字的符号取反。for(int i = 0; i < n; i++) {int val = map.get(s.charAt(i));if(i < n - 1 && val < map.get(s.charAt(i + 1))) {ans -= val;}else {ans += val;}}return ans;}
}
448. 找到所有数组中消失的数字

添加链接描述
给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。

示例 1:
输入:nums = [4,3,2,7,8,2,3,1]
输出:[5,6]

class Solution {// 加 n 找小于n的public List<Integer> findDisappearedNumbers(int[] nums) {int len = nums.length;for (int n : nums) {int k = (n - 1) % len;nums[k] += len;}ArrayList<Integer> list = new ArrayList<>();for(int i = 0; i < len; i++) {if(nums[i] <= len) {list.add(i+1);}}return list;}// 用哈希表检查 1-n 中的每一个数是否出现public List<Integer> findDisappearedNumbers1(int[] nums) {HashSet<Integer> set = new HashSet<>();for(int n : nums) {set.add(n);}ArrayList<Integer> list = new ArrayList<>();for(int i = 0; i < nums.length; i++) {if(!set.contains(i+1)) {list.add(i+1);}}return list;}
}

88. 合并两个有序数组

添加链接描述
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

class Solution {// 从后放public void merge(int[] nums1, int m, int[] nums2, int n) {int p1 = m - 1;int p2 = n - 1;int cur = 0;int tail = m + n - 1; // 尾巴while(p1 >= 0 || p2 >= 0) {if(p1 == -1) {cur = nums2[p2--];} else if (p2 == -1) {cur = nums1[p1--];} else if (nums1[p1] > nums2[p2]) {cur = nums1[p1--];} else {cur = nums2[p2--];}nums1[tail--] = cur;}}// 双指针public void merge2(int[] nums1, int m, int[] nums2, int n) {int p1 = 0;int p2 = 0;int[] sorted = new int[m+n];int i = 0;while(p1 < m || p2 < n) {if(p1 == m) {sorted[i++] = nums2[p2++];} else if(p2 == n) {sorted[i++] = nums1[p1++];} else if(nums1[p1] < nums2[p2]) {sorted[i++] = nums1[p1++];} else {sorted[i++] = nums2[p2++];}}i = 0;for(int k : sorted) {nums1[i++] = k;}}// 合并 排序public void merge1(int[] nums1, int m, int[] nums2, int n) {for(int i = 0; i < n; i++) {nums1[m + i] = nums2[i];}Arrays.sort(nums1);}
}

80. 删除有序数组中的重复项 II

添加链接描述
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

输入
[0,0,1,1,1,1,2,3,3]
输出
[0,0,1,1,2,3,3]
预期结果
[0,0,1,1,2,3,3]

class Solution {public int removeDuplicates(int[] nums) {int fast = 2;int slow = 2;while(fast < nums.length) {if(nums[slow-2] != nums[fast]) {nums[slow] = nums[fast];slow++;}fast++;}return slow;}
}

442. 数组中重复的数据

添加链接描述
给定一个整数数组 a,其中1 ≤ a[i] ≤ n (n为数组长度), 其中有些元素出现两次而其他元素出现一次。
找到所有出现两次的元素。

你可以不用到任何额外空间并在O(n)时间复杂度内解决这个问题吗?

示例:
输入:
[4,3,2,7,8,2,3,1]
输出:
[2,3]

class Solution {// 哈希public List<Integer> findDuplicates(int[] nums) {HashSet<Integer> set  = new HashSet<>();ArrayList<Integer> list = new ArrayList<>();for (int n : nums) {if(!set.contains(n)) {set.add(n);}else {list.add(n); // 重复}}return list;}public List<Integer> findDuplicates2(int[] nums) {ArrayList<Integer> list = new ArrayList<>();if(nums.length < 2) {return list;}if(nums.length == 2) {if(nums[0] == nums[1]) {list.add(nums[0]);}return list;}Arrays.sort(nums);for (int i = 1; i < nums.length - 1; i++) {if(nums[i-1] == nums[i] && nums[i] != nums[i+1]) {list.add(nums[i]);}}// [1,1,2,3,4,5,7,9,10,10] 最后两个相等if(nums[nums.length-1] == nums[nums.length-2]) {list.add(nums[nums.length-1]);}return list;}// 加长度public List<Integer> findDuplicates1(int[] nums) {List<Integer> list = new ArrayList<>();for (int n : nums) {int len = nums.length;nums[(n-1) % nums.length] += nums.length; // 下标 加len}for (int i = 0; i < nums.length; i++) {if(nums[i] > 2*nums.length && nums[i] < 3*nums.length+1) {list.add(i+1);}}return list;}
}

441. 排列硬币

添加链接描述

你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。
给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数。

输入:n = 5
输出:2
解释:因为第三行不完整,所以返回 2 。

class Solution {public int arrangeCoins(int n) {long left = 1;long right = n;while(left <= right) {long mid = left + (right - left) / 2;long total = mid * (mid + 1) / 2;if(total == n) {return (int)mid;}if(total > n) {right = mid - 1;}else {left = mid + 1;}}return (int)right;}
}

434. 字符串中的单词数

添加链接描述

统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。
请注意,你可以假定字符串里不包括任何不可打印的字符。
示例:
输入: “Hello, my name is John”
输出: 5
解释: 这里的单词是指连续的不是空格的字符,所以 “Hello,” 算作 1 个单词。

class Solution {// 该下标对应的字符不为空格;// 该下标为初始下标或者该下标的前下标对应的字符为空格;public int countSegments1(String s) {int cnt = 0;for(int i = 0; i < s.length(); i++) {if((i == 0 || s.charAt(i-1) == ' ') && s.charAt(i) != ' ') {cnt++;}}return cnt;}public int countSegments(String s) {int cnt = 0;String[] strings = s.split(" ");for (int i = 0; i < strings.length; i++) {if(!strings[i].equals("")) {cnt++;}}return cnt;}
}

415. 字符串相加

添加链接描述
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

示例 1:
输入:num1 = “11”, num2 = “123”
输出:“134”

class Solution {public String addStrings(String num1, String num2) {int i = num1.length() - 1;int j = num2.length() - 1;int carry = 0;StringBuilder sb = new StringBuilder();while(i >= 0 || j >= 0 || carry != 0) {int x = i >= 0 ? num1.charAt(i) - '0' : 0;int y = j >= 0 ? num2.charAt(j) - '0' : 0;int result = x + y + carry;sb.append(result % 10);carry = result / 10; // 进位i--;j--;}sb.reverse(); // 逆置return sb.toString();}
}

1154. 一年中的第几天

添加链接描述
给你一个字符串 date ,按 YYYY-MM-DD 格式表示一个 现行公元纪年法 日期。请你计算并返回该日期是当年的第几天。
通常情况下,我们认为 1 月 1 日是每年的第 1 天,1 月 2 日是每年的第 2 天,依此类推。每个月的天数与现行公元纪年法(格里高利历)一致。

示例 1:
输入:date = “2019-01-09”
输出:9

class Solution {public int dayOfYear(String date) {String[] strings = date.split("-");int year = Integer.parseInt(strings[0]);int month = Integer.parseInt(strings[1]);int day = Integer.parseInt(strings[2]);int[] amount = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};// 闰年 2月变29天if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {amount[1]++;}int ans = 0;for (int i = 0; i < month - 1; i++) {ans += amount[i];}return ans + day;}
}

414. 第三大的数

添加链接描述
给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。

示例 1:
输入:[3, 2, 1]
输出:1
解释:第三大的数是 1 。

示例 2:
输入:[1, 2]
输出:2
解释:第三大的数不存在, 所以返回最大的数 2 。

示例 3:
输入:[2, 2, 3, 1]
输出:1
解释:注意,要求返回第三大的数,是指在所有不同数字中排第三大的数。
此例中存在两个值为 2 的数,它们都排第二。在所有不同数字中排第三大的数为 1 。

class Solution {// a b c 最大值、次大值和第三大值// 若c仍为−2^63,则不存在三个或以上的不同元素,即第三大值不存在,返回a,否则返回cpublic int thirdMax(int[] nums) {long a = Long.MIN_VALUE;long b = Long.MIN_VALUE;long c = Long.MIN_VALUE;for (long n : nums) {if(n > a) {c = b;b = a;a = n;} else if (a > n && n > b) {c = b;b = n;} else if (b > n && n > c) {c = n;}}return c == Long.MIN_VALUE ? (int)a : (int)c;}public int thirdMax2(int[] nums) {TreeSet<Integer> set = new TreeSet<>();for (int n : nums) {set.add(n);if(set.size() > 3) { // 超过3个 删除最小set.remove(set.first());}}// 有序集合大小为3,最小值就是第三大的数;不足3,返回最大值。return set.size() == 3 ? set.first() : set.last();}// 排序 逆置 找第三public int thirdMax1(int[] nums) {Arrays.sort(nums);reverse(nums);for (int i = 0, diff =  1; i < nums.length - 1; i++) {if(nums[i] != nums[i+1] && ++diff == 3) {return nums[i+1];}}return nums[0];}public void reverse(int[] nums) {int left = 0;int right = nums.length - 1;while(left < right) {int tmp = nums[left];nums[left++] = nums[right];nums[right--] = tmp;}}
}

412. Fizz Buzz

添加链接描述
给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中:

answer[i] == “FizzBuzz” 如果 i 同时是 3 和 5 的倍数。
answer[i] == “Fizz” 如果 i 是 3 的倍数。
answer[i] == “Buzz” 如果 i 是 5 的倍数。
answer[i] == i (以字符串形式)如果上述条件全不满足。

示例 1:
输入:n = 3
输出:[“1”,“2”,“Fizz”]

class Solution {public List<String> fizzBuzz(int n) {List<String> answer = new ArrayList<>();for(int i = 1; i <= n; i++) {if(i % 15 == 0) {answer.add("FizzBuzz");}else if(i % 3 == 0) {answer.add("Fizz");}else if(i % 5 == 0) {answer.add("Buzz");}else {answer.add(i+"");}}return answer;}
}

389. 找不同

添加链接描述
给定两个字符串 s 和 t,它们只包含小写字母。
字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。
请找出在 t 中被添加的字母。

示例 1:
输入:s = “abcd”, t = “abcde”
输出:“e”
解释:‘e’ 是那个被添加的字母。

class Solution {public char findTheDifference(String s, String t) {int[] cnt = new int[26];for(int i = 0; i < s.length(); i++) {cnt[s.charAt(i) - 'a']++;}for(int i = 0; i < t.length(); i++) {char ch = t.charAt(i);cnt[ch - 'a']--;if(cnt[ch - 'a'] < 0) {return ch;}}return ' ';    }// 位运算public char findTheDifference2(String s, String t) {int ret = 0;for(int i = 0; i < s.length(); i++) {ret ^= s.charAt(i);ret ^= t.charAt(i);}ret ^= t.charAt(t.length()-1);return (char)ret;    }// 排序 遍历 public char findTheDifference1(String s, String t) {char[] ss = s.toCharArray();char[] tt = t.toCharArray();Arrays.sort(ss);Arrays.sort(tt);for (int i = 0; i < ss.length; i++) {if(ss[i] != tt[i]) {return tt[i];}}return tt[tt.length-1];}
}

387. 字符串中的第一个唯一字符

添加链接描述
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

示例:
s = “leetcode”
返回 0

class Solution {public int firstUniqChar(String s) {int[] ret = new int[26];for(int i = 0; i < s.length(); i++) {ret[s.charAt(i) - 'a']++;}for(int i = 0; i < s.length(); i++) {if(ret[s.charAt(i) - 'a'] == 1) { // 按顺序找 只出现一次的字符return i;}}return -1;}public int firstUniqChar1(String s) {HashMap<Character, Integer> map = new HashMap<>();for (int i = 0; i < s.length(); i++) {int cnt = map.getOrDefault(s.charAt(i), 0) + 1;map.put(s.charAt(i), cnt);}for (int i = 0; i < s.length(); i++) {if(map.get(s.charAt(i)) == 1) { // 找次数为1return i;}}return -1;}
}

383. 赎金信

添加链接描述

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次。

示例 1:
输入:ransomNote = “a”, magazine = “b”
输出:false

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;}// 哈希public boolean canConstruct1(String ransomNote, String magazine) {if(ransomNote.length() > magazine.length()) { // 不够构成ransomNotereturn false;}HashMap<Character, Integer> map = new HashMap<>();for (int i = 0; i < magazine.length(); i++) { // 记录字符 和次数int cnt = map.getOrDefault(magazine.charAt(i), 0) + 1;map.put(magazine.charAt(i), cnt);}for (int i = 0; i < ransomNote.length(); i++) {int cnt = 0;if(!map.containsKey(ransomNote.charAt(i))) {return false; // 找不到字符}else {cnt = map.get(ransomNote.charAt(i)) - 1;map.put(ransomNote.charAt(i), cnt); // 次数减一}if(cnt == 0) { // 没有次数 移除该字符map.remove(ransomNote.charAt(i), 0);}}return true; // 遍历完 都能在magazine里找到}
}

374. 猜数字大小

添加链接描述
We are playing the Guess Game. The game is as follows:
I pick a number from 1 to n. You have to guess which number I picked.
Every time you guess wrong, I will tell you whether the number I picked is higher or lower than your guess.

You call a pre-defined API int guess(int num), which returns 3 possible results:
-1: The number I picked is lower than your guess (i.e. pick < num).
1: The number I picked is higher than your guess (i.e. pick > num).
0: The number I picked is equal to your guess (i.e. pick == num).
Return the number that I picked.

Example 1:
Input: n = 10, pick = 6
Output: 6

public class Solution extends GuessGame {public int guessNumber(int n) {int left = 1;int right = n;while(left < right) {int pick = left + (right - left) / 2; // 防止mid加法溢出// The number I picked is higher than your guess ...if(guess(pick) > 0) {left = pick + 1;}else if (guess(pick) < 0) {right = pick - 1;}else {return pick;}}return left;}
}

367. 有效的完全平方数

添加链接描述
给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。

示例 1:
输入:num = 16
输出:true

class Solution {// 二分public boolean isPerfectSquare(int num) {long left = 0;long right = num / 2;long mid = 0;while(left <= right) {mid = (left + right) / 2;if(mid * mid == num) {return true;} else if (mid * mid < num) {left = mid + 1;} else {right = mid - 1;}}return left * left == num; // 1}// 暴力public boolean isPerfectSquare2(int num) {for(long i = 1; i <= num; i++) {long x = i * i;if(x == num) {return true;}else if (x > num) { // i*i > num return false;}}return false;}// 减public boolean isPerfectSquare1(int num) {// 平方数 =1+3+5+...+(2∗n−1)int i = 1;while(num > 0) {num -= i;i += 2;}return num == 0;}
}

24. 两两交换链表中的节点

添加链接描述

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例:
输入:head = [1,2,3,4]
输出:[2,1,4,3]

class Solution {// 迭代public ListNode swapPairs(ListNode head) {ListNode newHead = new ListNode(-1);ListNode tmp = newHead;tmp.next = head;while(tmp.next != null && tmp.next.next != null) {ListNode node1 = tmp.next; // 1ListNode node2 = tmp.next.next; // 2tmp.next = node2; // newHead: 2node1.next = node2.next; // 1-3node2.next = node1; // 2-1-3tmp = node1; // 下一组}return newHead.next;}// 递归public ListNode swapPairs1(ListNode head) {if(head == null || head.next == null) {return head;}ListNode newHead = head.next; // 1 2 3 4  保存2head.next = swapPairs(newHead.next); // 交换下一组4-3  把head指向4:1-4newHead.next = head; // 2指向1return newHead;}
}

997. 找到小镇的法官

添加链接描述

在一个小镇里,按从 1 到 n 为 n 个人进行编号。传言称,这些人中有一个是小镇上的秘密法官。

如果小镇的法官真的存在,那么:

  • 小镇的法官不相信任何人。
  • 每个人(除了小镇法官外)都信任小镇的法官。
  • 只有一个人同时满足条件 1 和条件 2 。
    给定数组 trust,该数组由信任对 trust[i] = [a, b] 组成,表示编号为 a 的人信任编号为 b 的人。

如果小镇存在秘密法官并且可以确定他的身份,请返回该法官的编号。否则,返回 -1。

示例 1:
输入:n = 2, trust = [[1,2]]
输出:2

class Solution {// 法官:被信任 n-1 && 信任别人 0public int findJudge1(int n, int[][] trust) {int[][] array = new int[n+1][2];for (int[] k : trust) {array[k[0]][0]++; // k[0] 信任别人array[k[1]][1]++; // k[1] 被信任}for (int i = 1; i <= n; i++) {if(array[i][1] == n - 1 && array[i][0] == 0) {return i;}}return -1;}public int findJudge(int n, int[][] trust) {int[] array = new int[n+1];for (int[] k : trust) {array[k[0]]--; // k[0] 信任别人array[k[1]]++; // k[1] 被信任}for (int i = 1; i <= n; i++) {if(array[i] == n - 1) {return i;}}return -1;}
}

350. 两个数组的交集 II

添加链接描述

给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]

class Solution {// 哈希  数字的个数public int[] intersect(int[] nums1, int[] nums2) {// 较短数组放到哈希表 较长数组遍历取交集if(nums1.length > nums2.length) {intersect(nums2, nums1);}HashMap<Integer, Integer> map = new HashMap<>();for (int n : nums1) { // 放nums1 数和个数int cnt = map.getOrDefault(n, 0) + 1;map.put(n, cnt);}int[] array = new int[nums1.length];int index = 0;for (int n : nums2) {int cnt = map.getOrDefault(n, 0);if(cnt > 0) { // 有重复array[index++] = n;cnt--; // 减少一次if(cnt > 0) {map.put(n, cnt); // 修改key}else {map.remove(n); // 次数为0 没有n的交集了}}}return Arrays.copyOfRange(array, 0, index);}// 指针public int[] intersect1(int[] nums1, int[] nums2) {Arrays.sort(nums1);Arrays.sort(nums2);int index = 0; // 要返回的数组的范围int index1 = 0; // nums1int index2 = 0; // nums2int[] array = new int[nums1.length];while(index1 < nums1.length && index2 < nums2.length) {int x = nums1[index1];int y = nums2[index2];if(x == y) {array[index++] = x;index1++;index2++;} else if (x < y) { // x != y 指向较小数的指针右移index1++;} else {index2++;}}return Arrays.copyOfRange(array, 0, index);}
}
349. 两个数组的交集

添加链接描述

给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]

class Solution {// 排序 双指针public int[] intersection(int[] nums1, int[] nums2) {Arrays.sort(nums1);Arrays.sort(nums2);int index = 0; // 要返回的数组的范围int index1 = 0; // nums1int index2 = 0; // nums2int[] array = new int[nums1.length];while(index1 < nums1.length && index2 < nums2.length) { // 一个遍历完 停止int x = nums1[index1];int y = nums2[index2];if(x == y) {if(index == 0 || x != array[index - 1]) { // 保证唯一性array[index++] = x;}index1++;index2++;} else if (x < y) { // x != y 指向较小数的指针右移index1++;} else {index2++;}}return Arrays.copyOfRange(array, 0, index);}// 哈希public int[] intersection1(int[] nums1, int[] nums2) {int[] array = new int[nums1.length];HashSet<Integer> set = new HashSet<>(); // 放nums1for (int i = 0; i < nums1.length; i++) {set.add(nums1[i]);}int k = 0; // 记录要返回的范围for (int i = 0; i < nums2.length; i++) {if(set.contains(nums2[i])) { // 有重复 放到array 删除array[k++] = nums2[i];set.remove(nums2[i]); }}return Arrays.copyOfRange(array, 0, k);}
}

419. 甲板上的战舰

添加链接描述

class Solution {// 左边为空位 board[i][j-1]// 上方为空位 board[i-1][j]public int countBattleships(char[][] board) {int cnt = 0;int row = board.length; // 行int col = board[0].length; // 列for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {if(board[i][j] == 'X') {if(i > 0 && board[i-1][j] == 'X') {continue;}if(j > 0 && board[i][j-1] == 'X') {continue;}cnt++;}}}return cnt;}// 如果是'X' 就设为' ' 判断行列public int countBattleships1(char[][] board) {int cnt = 0;int row = board.length; // 行int col = board[0].length; // 列for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {if(board[i][j] == 'X') {board[i][j] = ' ';for (int k = i+1; k < row && board[k][j] == 'X'; k++) {board[k][j] = ' ';}for (int k = j+1; k < col && board[i][k] == 'X'; k++) {board[i][k] = ' ';}cnt++;}}}return cnt;}
}

345. 反转字符串中的元音字母

添加链接描述

给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括 ‘a’、‘e’、‘i’、‘o’、‘u’,且可能以大小写两种形式出现。

示例 1:
输入:s = “hello”
输出:“holle”

class Solution {public String reverseVowels(String s) {int l = 0;int r = s.length() - 1;String str = "aeiouAEIOU";char[] newS = s.toCharArray();while(l < r) {if(str.contains(s.charAt(l)+"")) {if(str.contains(s.charAt(r)+"")) {char ch = newS[l];newS[l] = newS[r];newS[r] = ch;++l;--r;}else {r--;}}else {l++;}}return new String(newS);}/*public String reverseVowels1(String s) {int l = 0;int r = s.length() - 1;String str = "aeiouAEIOU";char[] newS = s.toCharArray();while(l < r) {if(str.contains(s.charAt(l)+"") && str.contains(s.charAt(r)+"")) {char ch = newS[l];newS[l] = newS[r];newS[r] = ch;++l;--r;}if(!str.contains(s.charAt(l)+"")) {++l;}if(!str.contains(s.charAt(r)+"")) {--r;}}return new String(newS);}*/
}

268. 丢失的数字

添加链接描述

给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。

示例 1:
输入:nums = [3,0,1]
输出:2
解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢失的数字,因为它没有出现在 nums 中。

class Solution {// 数学求和 n(n+1)/2public int missingNumber(int[] nums) {int n = nums.length;int sumN = (1+n)*n/2; // 1-N 的和int sumNums = 0; // 数组的和for(int i = 0; i < n; ++i) {sumNums += nums[i];}return sumN - sumNums;}// 哈希public int missingNumber3(int[] nums) {Arrays.sort(nums); // 排序后判断加入的nums[i]是否是iHashSet<Integer> set = new HashSet<>();for(int i = 0; i < nums.length; i++) {set.add(nums[i]);if(!set.contains(i)) {return i;}}return nums.length;}// 排序public int missingNumber2(int[] nums) {Arrays.sort(nums);for(int i = 0; i < nums.length; i++) {if(nums[i] != i) {return i;}}return nums.length;}// 按位异或 同为0 异为1public int missingNumber1(int[] nums) {int len = nums.length; // 长度就是最大值int ret = nums[0];for (int i = 1; i < len; i++) {ret ^= nums[i]; // 数组的每一位ret ^= i; // i}ret ^= len;return ret;}
}

219. 存在重复元素 II

添加链接描述

给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k。

示例 1:
输入: nums = [1,2,3,1], k = 3
输出: true

class Solution {// 记录下标public boolean containsNearbyDuplicate(int[] nums, int k) {HashMap<Integer, Integer> map = new HashMap<>();for(int i = 0; i < nums.length; i++) {if(map.containsKey(nums[i]) && i - map.get(nums[i]) <= k) {return true;}map.put(nums[i], i);}return false;}public boolean containsNearbyDuplicate1(int[] nums, int k) {// 哈希表  限定范围 只需要判断有重复直接返回trueHashSet<Integer> set = new HashSet<>();for(int i = 0; i < nums.length; i++) {if(set.contains(nums[i])) {return true;}set.add(nums[i]);if(set.size() > k) {set.remove(nums[i-k]); // 移除最前面的数字}}return false;}
}

217. 存在重复元素

添加链接描述

给定一个整数数组,判断是否存在重复元素。
如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。

示例 1:
输入: [1,2,3,1]
输出: true

class Solution {// 排序 相邻比较相等public boolean containsDuplicate(int[] nums) {Arrays.sort(nums);for(int i = 0; i < nums.length - 1; i++) {if(nums[i] == nums[i+1]) {return true;}}return false;}// 哈希public boolean containsDuplicate1(int[] nums) {HashSet<Integer> map = new HashSet<>();for (int n : nums) {/*if(map.contains(n)) {return true;}map.add(n);*/// 如果 e 已经存在于 set 中,那么 add() 方法就会返回 falseif(!map.add(n)) {return true;}}return false;}
}
70. 爬楼梯

添加链接描述

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。

示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1 阶 + 1 阶
2 阶

class Solution {public int climbStairs(int n) {int n1 = 1;int n2 = 1;int n3 = 1;for(int i = 2; i <= n; i++) {n3 = n1 + n2;n1 = n2;n2 = n3;}return n3;/*if(n <= 2) {return n;}int n1 = 1;int n2 = 2;int n3 = 0;for(int i = 3; i <= n; i++) {n3 = n1 + n2;n1 = n2;n2 = n3;}return n3;*/}
}

1518. 换酒问题

添加链接描述

小区便利店正在促销,用 numExchange 个空酒瓶可以兑换一瓶新酒。你购入
了 numBottles 瓶酒。
如果喝掉了酒瓶中的酒,那么酒瓶就会变成空的。
请你计算 最多 能喝到多少瓶酒。

输入:numBottles = 9, numExchange = 3
输出:13
解释:你可以用 3 个空酒瓶兑换 1 瓶酒。
所以最多能喝到 9 + 3 + 1 = 13 瓶酒。

class Solution {public int numWaterBottles(int numBottles, int numExchange) {return numBottles + (numBottles-1)/(numExchange-1);}public int numWaterBottles1(int numBottles, int numExchange) {int total = numBottles;while(numBottles >= numExchange) {total += numBottles / numExchange;// 加不够换剩下的numBottles = numBottles/numExchange + numBottles%numExchange; }return total;}
}

258. 各位相加

添加链接描述

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。

示例:
输入: 38
输出: 2
解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。

class Solution {// O(1)public int addDigits(int num) {if(num > 0 && num % 9 == 0) { // 防止0return 9;}return num % 9; // 如果是个位数也可以直接输出}// 循环public int addDigits2(int num) {while(num >= 10) {int sum = 0;while(num != 0) {sum += num % 10;num /= 10;}num = sum;}return num;}// 递归public int addDigits1(int num) {if(num < 10) {return num;}int sum = 0;while(num != 0) {sum += num % 10;num /= 10;}return addDigits(sum);}
}

292. Nim 游戏

添加链接描述
示例 1:
输入:n = 4
输出:false
解释:如果堆中有 4 块石头,那么你永远不会赢得比赛;
因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。

class Solution {public boolean canWinNim(int n) {if(n % 4 == 0) {return false;}return true;}
}

巴什博奕(Bash Game):

只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个.最后取光者得胜

结论:如果 n % (m + 1) == 0,则先手必败,否则先手必胜

你和你的朋友,两个人一起玩 Nim 游戏:

桌子上有一堆石头。
你们轮流进行自己的回合,你作为先手。
每一回合,轮到的人拿掉 1 - 3 块石头。
拿掉最后一块石头的人就是获胜者。
假设你们每一步都是最优解。请编写一个函数,来判断你是否可以在给定石头数量为 n 的情况下赢得游戏。如果可以赢,返回 true;否则,返回 false 。


190. 颠倒二进制位

添加链接描述
颠倒给定的 32 位无符号整数的二进制位。

  • 输入:n = 00000010100101000001111010011100
  • 输出:964176192 (00111001011110000010100101000000)
  • 解释:输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596,
    因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。
public class Solution {// you need treat n as an unsigned valuepublic int reverseBits(int n) {int num = 0;for (int i = 1; i <= 32 && n != 0; i++) {// 如果最低位是1 就可以颠倒或给numnum |= (n & 1) << (32 - i);n >>>= 1;}return num;}
}

191. 位1的个数

添加链接描述
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

public class Solution {// you need to treat n as an unsigned value// 每次去一个1public int hammingWeight(int n) {int cnt = 0;while(n != 0) {n &= (n - 1);cnt++;}return cnt;}public int hammingWeight1(int n) {int cnt = 0;for (int i = 0; i < 32; i++) {if((n & (1 << i)) != 0) { // 用1<<i 判断每一位cnt++;}}return cnt;}
}

231. 2 的幂

添加链接描述

给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。

示例 1:
输入:n = 1
输出:true
解释:20 = 1

class Solution {// 判断是否为最大 22 的幂的约数public boolean isPowerOfTwo(int n) {return n > 0 && (1 << 30) % n == 0;}// 一个数 n 是 2 的幂,当且仅当 n 是正整数,并且 n 的二进制表示中仅包含 1 个 1// 将 n 的二进制表示中最低位的那个 1 提取出来,再判断剩余的数值是否为 0public boolean isPowerOfTwo1(int n) {return n > 0 && (n & (n-1)) == 0;}
}

263. 丑数

添加链接描述

给你一个整数 n ,请你判断 n 是否为 丑数 。如果是,返回 true ;否则,返回 false 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。

示例 1:
输入:n = 6
输出:true
解释:6 = 2 × 3

class Solution {public boolean isUgly(int n) {if(n <= 0) {return false;}int[] factors = {2, 3, 5};for (int factor : factors) {while(n % factor == 0) {n /= factor;}}return n == 1;}
}

283. 移动零

添加链接描述

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

class Solution {// 2、双指针public void moveZeroes(int[] nums) {int left = 0;int right = 0;while (right < nums.length) {if(nums[right] != 0) {swap(nums, left, right);left++;}right++;}}public void swap(int[] nums, int left, int right) {int tmp = nums[right];nums[right] = nums[left];nums[left] = tmp;}// 1、快慢指针public void moveZeroes1(int[] nums) {int slow = 0;for(int fast = 0; fast < nums.length; fast++) {if(nums[fast] != 0) {nums[slow++] = nums[fast];}}// slow-len都置为0while(slow < nums.length) {nums[slow++] = 0;}}
}

面试题 01.01. 判定字符是否唯一

添加链接描述

实现一个算法,确定一个字符串 s 的所有字符是否全都不同。

示例 1:
输入: s = “leetcode”
输出: false

class Solution {public boolean isUnique(String astr) {int[] array = new int[128];for (int i = 0; i < astr.length(); i++) {if (array[astr.charAt(i)] != 0) {return false;}array[astr.charAt(i)]++;}return true;}public boolean isUnique1(String astr) {HashMap<Character, Integer> map = new HashMap();for (int i = 0; i < astr.length(); i++) {if(map.containsKey(astr.charAt(i))) {return false;}map.put(astr.charAt(i), i);}return true;}
}

面试题 01.02. 判定是否互为字符重排

添加链接描述
给定两个字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

示例 1:
输入: s1 = “abc”, s2 = “bca”
输出: true

class Solution {public boolean CheckPermutation(String s1, String s2) {if(s1.length() != s2.length()) {return false;}// 转字符数组 排序char[] chars1 = s1.toCharArray();Arrays.sort(chars1);char[] chars2 = s2.toCharArray();Arrays.sort(chars2);// 字符串比较return new String(chars1).equals(new String(chars2));}
}

面试题 01.09. 字符串轮转

添加链接描述
字符串轮转。给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成(比如,waterbottle是erbottlewat旋转后的字符串)。

示例1:
输入:s1 = “waterbottle”, s2 = “erbottlewat”
输出:True

class Solution {public boolean isFlipedString(String s1, String s2) {// helloworld// rldhellowo// helloworldhelloworldreturn s1.length() == s2.length() && (s1 + s1).contains(s2);}
}

344. 反转字符串

添加链接描述

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:
输入:s = [“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]

class Solution {public void reverseString(char[] s) {int left = 0;int right = s.length - 1;while(left < right) {char tmp = s[left];s[left++] = s[right];s[right--] = tmp;}System.out.println(Arrays.toString(s));}
}

338. 比特位计数

添加链接描述

给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。

示例 1:
输入:n = 2
输出:[0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10

class Solution {public int[] countBits(int n) {int[] ans = new int[n+1];for (int i = 0; i <= n; i++) {ans[i] = cntEveryBIt(i);}return ans;}public int cntEveryBIt(int n) {int cnt = 0;while(n > 0) {/*if((n & 1) == 1) {cnt++;}n >>= 1;*/n &= (n - 1);cnt++;}return cnt;}
}

326. 3 的幂

添加链接描述
给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 3 的幂次方需满足:存在整数 x 使得 n == 3x

示例 1:
输入:n = 27
输出:true

示例 2:
输入:n = 0
输出:false

class Solution {public boolean isPowerOfThree(int n) {// 32位有符号整数的范围内,最大的3的幂为3^19 = 1162261467// 判断 n 是否是 3^19的约数return n > 0 && 1162261467 % n == 0;}public boolean isPowerOfThree1(int n) {while(n > 0 && n % 3 == 0) {n /= 3;}return n == 1;}
}

66. 加一

添加链接描述

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123

class Solution {public int[] plusOne(int[] digits) {for(int i = digits.length - 1; i >= 0; --i) {digits[i] = (digits[i] + 1) % 10;if(digits[i] != 0) {return digits;}}// 全是9digits = new int[digits.length+1];digits[0] = 1;return digits;}
}

35. 搜索插入位置

添加链接描述

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。

示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2

示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1

class Solution {public int searchInsert(int[] nums, int target) {int left = 0;int right = nums.length - 1;while(left <= right) {int mid = (left + right) / 2;if(nums[mid] < target) {left = mid + 1;}else if(nums[mid] > target) {right = mid - 1;}else {return mid;}}return left;}
}

28. 实现 strStr()

添加链接描述

实现 strStr() 函数。

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。

class Solution {public int strStr(String haystack, String needle) {if(haystack == null || needle == null) {return -1;}int i = 0;int j = 0;int lenHay  = haystack.length();int lenNee = needle.length();while(i < lenHay && j < lenNee) {if(haystack.charAt(i) == needle.charAt(j)) {i++;j++;}else {i = i - j + 1;j = 0;}}if(j >= lenNee) {return i-j;}return -1;}
}

27. 移除元素

添加链接描述
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

class Solution {public int removeElement(int[] nums, int val) {int fast = 0;int slow = 0;while(fast < nums.length) {if(nums[fast] != val) {nums[slow++] = nums[fast];}fast++;}return slow;}
}
26. 删除有序数组中的重复项

添加链接描述

有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。

示例 1:
输入:nums = [1,1,2]
输出:2, nums = [1,2]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

class Solution {// 快慢指针public int removeDuplicates(int[] nums) {int len = nums.length;if(len == 0) {return 0;}int fast = 1;int slow = 1;while(fast < len) {if(nums[fast] != nums[fast-1]) {nums[slow++] = nums[fast];}fast++;}return slow;}// 两个循环遍历public int removeDuplicates1(int[] nums) {// Arrays.sort(nums); 已经是有序数组int len = nums.length -1;for (int i = 0; i < len; i++) {if(nums[i] == nums[i+1]) { // 一样// 往前放for (int j = i; j < len; j++) {nums[j] = nums[j+1];}i--;len--;}}return len+1;}
}

709. 转换成小写字母

添加链接描述

给你一个字符串 s ,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。

示例 1:
输入:s = “Hello”
输出:“hello”

Java

class Solution {public String toLowerCase1(String s) {return s.toLowerCase();}public String toLowerCase(String s) {StringBuilder sb = new StringBuilder();for (int i = 0; i < s.length(); i++) {char ch = s.charAt(i);if(ch >= 65 && ch <= 90) {ch |= 32;}sb.append(ch);}return sb.toString();}
}

C

char* toLowerCase1(char* s) {int i = 0;int len = strlen(s);for (i = 0; i < len; i++){s[i] = tolower(s[i]);}return s;
}char* toLowerCase(char* s) {int i = 0;int len = strlen(s);for (i = 0; i < len; i++){if (s[i] >= 65 && s[i] <= 90) {s[i] |= 32;}}return s;
}

9. 回文数

添加链接描述

class Solution {public boolean isPalindrome(int x) {if(x < 0) {return false;}int tmp = x;int res = 0; // 逆转的xwhile(tmp != 0) {res = res*10 + tmp % 10;tmp /= 10;}if(x == res) {return true;}return false;}public boolean isPalindrome1(int x) {StringBuilder sb = new StringBuilder(x+"").reverse();if(sb.toString().equals(x+"")) {return true;}return false;}
}

7. 整数反转

添加链接描述

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:
输入:x = 123
输出:321

class Solution {public int reverse(int x) {int res = 0;while(x != 0) {// 判断未来 下一次的范围 否则x==0 直接返回超范围的resif(res < Integer.MIN_VALUE/10 || res > Integer.MAX_VALUE/10) {return 0;}res = res*10 + x%10;x /= 10;}return res;}
}

1. 两数之和

添加链接描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

class Solution {public int[] twoSum(int[] nums, int target) {Map<Integer, Integer> hash = new HashMap<>();for (int i = 0; i < nums.length; i++) {if(hash.containsKey(target - nums[i])) {return new int[]{hash.get(target - nums[i]), i};}hash.put(nums[i], i);}return new int[0];}public int[] twoSum2(int[] nums, int target) {int len = nums.length;for (int i = 0; i < len; i++) {for (int j = i + 1; j < len; j++) {if(nums[i] + nums[j] == target) {return new int[]{i, j};}}}return new int[0];}public int[] twoSum1(int[] nums, int target) {int[] array = new int[2];for (int i = 0; i < nums.length; i++) {for (int j = i; j < nums.length; j++) {if(i == j) continue;if(nums[i] + nums[j] == target) {array[0] = i;array[1] = j;}}}return array;}/* public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int[] nums = new int[4];for (int i = 0; i < nums.length; i++) {nums[i] = scanner.nextInt();}int target = scanner.nextInt();int[] ret = twoSum(nums, target);System.out.println(Arrays.toString(ret));} */
}

189. 轮转数组

添加链接描述

class Solution {// 2、逆置public void reverse(int[] nums, int left, int right) {while(left < right) {int tmp = nums[left];nums[left++] = nums[right];nums[right--] = tmp;}}public void rotate(int[] nums, int k) {k %= nums.length;reverse(nums, nums.length-k, nums.length-1); // 后reverse(nums, 0, nums.length-k-1); // 前reverse(nums, 0, nums.length-1); // 整体}// 1、超出时间限制public void rotate1(int[] nums, int k) {k %= nums.length;while(k != 0) {int tmp = nums[nums.length-1];for (int i = nums.length - 2; i >= 0; i--) {nums[i+1] = nums[i];}nums[0] = tmp;k--;}}
}

面试题 17.04. 消失的数字

添加链接描述

class Solution {public int missingNumber(int[] nums) {int x = 0;for(int i = 0; i < nums.length; i++) {x ^= nums[i];}for(int i = 0; i < nums.length + 1; i++) {x ^= i;}return x;}public int missingNumber1(int[] nums) {int sum1 = 0;for(int i = 0; i < nums.length; i++) {sum1 += nums[i];}int sum2 = 0;for(int i = 0; i < nums.length + 1; i++) {sum2 += i;}return sum2 -sum1;}
}

剑指 Offer 18. 删除链表的节点
class Solution {public ListNode deleteNode(ListNode head, int val) {if(head == null) {return null;}if(head.val == val) {return head.next; // 头节点是}ListNode prev = head; // 前一个ListNode cur = head.next;while(cur != null) {if(cur.val == val) {prev.next = cur.next;return head;}prev = prev.next;cur = cur.next;}return head;}
}

面试题 02.02. 返回倒数第 k 个节点

添加链接描述

class Solution {public int kthToLast(ListNode head, int k) {ListNode fast = head;ListNode slow = head;while(k != 0) {fast = fast.next;k--;}while(fast != null) {fast = fast.next;slow = slow.next;}return slow.val;}
}

面试题 02.01. 移除未排序重复节点

题目链接

class Solution {public ListNode removeDuplicateNodes(ListNode head) {if(head == null) {return null;}HashSet<Integer> set = new HashSet<>();ListNode cur = head;// set.add(cur.val); // // while(cur != null && cur.next != null) {//     if(set.contains(cur.next.val)) { // 用下一个查找//         cur.next = cur.next.next;//     } else {//         set.add(cur.next.val); // //         cur = cur.next;//     }// }// 双指针ListNode pre = null;while(cur != null) {if(set.contains(cur.val)) {pre.next  = cur.next;} else {set.add(cur.val);pre = cur;}cur = cur.next;}return head;}
}

剑指 Offer 06. 从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

class Solution {// 3、栈public int[] reversePrint(ListNode head) {Stack<Integer> stack = new Stack<>();ListNode cur = head;while(cur != null) {stack.push(cur.val);cur = cur.next;}int i = 0;int[] ans =  new int[stack.size()];while(!stack.isEmpty()) {ans[i++] = stack.pop();}return ans;}// 2、反转链表 遍历public int[] reversePrint2(ListNode head) {ListNode prev = null;ListNode cur = head;int size = 0; // 计算链表长度while(cur != null) {ListNode curNext = cur.next;cur.next = prev;prev = cur;cur = curNext;size++;}int[] array = new int[size];cur = prev;for (int i = 0; i < size; i++) {array[i] = cur.val;cur = cur.next;}return array;}// 1、ArrayListpublic int[] reversePrint1(ListNode head) {ArrayList<Integer> list = new ArrayList<>();ListNode cur = head;while(cur != null) {list.add(cur.val);cur = cur.next;}// 获取链表长度int size = list.size();// 遍历放到数组里int[] array = new int[size];for (int i = 0; i < size; i++) {array[i] = list.get(size-i-1); // 减一}return array;}
}

1290. 二进制链表转整数

题目链接

每到下一个,乘2,就不用计算长度

class Solution {public int getDecimalValue(ListNode head) {if(head == null) {return 0;}ListNode cur = head;int sum = 0;while(cur != null) {sum = sum * 2 + cur.val;cur = cur.next;}return sum;}
}

237. 删除链表中的节点

【题目链接】

class Solution {public void deleteNode(ListNode node) {// 把node变成它的下一个node.val = node.next.val;node.next = node.next.next;}
}
83. 删除排序链表中的重复元素

【题目链接】

和牛客删除链表重复节点一样,只是需要保留一个

class Solution {public ListNode deleteDuplicates(ListNode head) {if(head == null || head.next == null) {return head;}ListNode prev = head;ListNode cur = head.next;while(cur != null) {// 相同 删除if(cur.next != null && cur.val == cur.next.val) {while(cur.next != null && cur.val == cur.next.val) {cur = cur.next;}prev.next = cur;prev = prev.next; // cur = cur.next;} else {prev = cur;cur = cur.next;}}// 如果头节点需要删除if(head.val == head.next.val) {head = head.next;}return head;}
}

19. 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点

【题目链接】

class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {if(n < 0 || head == null) {return null;}ListNode fast = head.next;ListNode slow = head;// 找要删的前一个节点while(n-1 != 0) {fast = fast.next;if(fast == null) {break;}n--;}// 要删的是headif(fast == null) {head = head.next;return head;}// 要删的是头节点的下一个if(fast.next == null) {head.next = head.next.next;return head;}//while(fast.next != null) {fast = fast.next;slow = slow.next;}// 删slow.next = slow.next.next;return head;}
}

LeetCode 496. 下一个更大元素 I相关推荐

  1. Java实现 LeetCode 496 下一个更大元素 I

    496. 下一个更大元素 I 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nu ...

  2. LeetCode 496. 下一个更大元素 I(哈希)

    1. 题目 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nums1 中数字 x ...

  3. LeetCode 496. 下一个更大元素 I 解题思路及C++实现

    解题思路: 因为这两个int型的vector中不包含重复元素,所以考虑使用c++中的unordered_map,对num2进行遍历,找到每一个元素的下一个更大元素,这样的话,时间复杂度就是O(n). ...

  4. leetcode 496. 下一个更大元素 I(Java版,单调栈解法)

    题目 https://leetcode-cn.com/problems/next-greater-element-i/ 题解 通过Stack.HashMap解决,经典的单调栈问题 先遍历大数组nums ...

  5. 496. 下一个更大元素 I

    496. 下一个更大元素 I 题目 分析 我的解答 官方解答 题目 给定两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 ...

  6. 【LeetCode】496. 下一个更大元素 I 【单调栈】

    题目链接:https://leetcode-cn.com/problems/next-greater-element-i/ 题目描述 给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中 ...

  7. 496.下一个更大元素I

    给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nums1 中数字 x 的下一个更 ...

  8. Leecode 496. 下一个更大元素 I——Leecode每日一题系列

    我是小张同学,立志用更简洁的代码做更高效的表达 给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集. 请你找出 nums1 中每个元素在 nums2 ...

  9. leetcode 503. 下一个更大元素 II(单调栈)

    给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它 ...

最新文章

  1. oracle稳定执行计划1
  2. 让 windows 的桌面 干净。。。再干净点。。。
  3. r语言 断轴 画图_R 绘图 – 函数曲线图 | 菜鸟教程
  4. Acwing第 21 场周赛【完结】
  5. java框架缓存,缓存框架(Java缓存)与框架缓存(介绍mybatis缓存)
  6. 网盘php资料,怎么搜索百度网盘里的资料(php版)
  7. android2.2桌面,手机桌面课表软件
  8. ASP.NET Core Web 项目文件介绍
  9. eap和psk_针对WildFly和EAP运行Java Mission Control和Flight Recorder
  10. html表单中按钮添加超链接,JS 实现点击按钮实现超链接功能
  11. java中关于重写的说法_Java中有关“重载”和“重写”的说法正确的是()
  12. 【干货】数字化转型工作手册.pdf(附下载链接)
  13. 抱怨一下有些邮件列表的气氛
  14. UVA11876 N + NOD (N)【欧拉筛法+前缀和】
  15. 我不是领导,如何让别人听我的话?
  16. 从零开始学编程之我见
  17. 一文了解常用效率记笔记软件(超过20款含有图片和双向链笔记)
  18. 中印程序员对比:是什么让我们觉得印度程序员很厉害?
  19. win7设置桌面计算机图标不见了,win7桌面图标不见了_win7桌面图标不见了恢复显示设置教程 - 系统家园...
  20. 您可以在哪里播放最喜欢的圣诞节特价商品

热门文章

  1. Mysql存时间不一致_node mysql 存在数据库中的时间和取到前端的时间不一致,请问怎么解决...
  2. 反射 数据类型_这是一份超全面详细的Java反射机制学习指南
  3. MARKDOWN使用小计
  4. 移动应用的一般测试流程和需要注意的测试项
  5. 作为一个女程序员,有感而发
  6. set是无序集合,放入set中的元素通过iterator输出时候是无序的
  7. [2767]翻转排序 sdutOJ
  8. 转android项目开发 工作日志 2011.10.8--toast消息框使用
  9. Shell每行前面加上行号
  10. Android远程桌面助手之功能简介