1. 两数之和
题目
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
答案
java
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
Map<Integer,Integer> map = new HashMap();
for(int i=0;i<nums.length;i++){
if(map.get(target-nums[i])!=null){
res[0] = map.get(target-nums[i]);
res[1] = i;
break;
}
map.put(nums[i],i);
}
return res;
}
}
202. 快乐数
题目
编写一个算法来判断一个数 n
是不是快乐数。
「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n
是 快乐数 就返回 true
;不是,则返回 false
。
示例 1:
输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
答案
java
class Solution {
public boolean isHappy(int n) {
Set<Integer> set = new HashSet();
while(n!=1 && !set.contains(n)){
set.add(n);
n = getSum(n);
}
return n == 1;
}
int getSum(int n){
int sum = 0;
while(n>0){
int temp = n % 10;
sum += temp * temp;
n = n / 10;
}
return sum;
}
}
219. 存在重复元素 II
题目
给你一个整数数组 nums
和一个整数 k
,判断数组中是否存在两个 不同的索引 i
和 j
,满足 nums[i] == nums[j]
且 abs(i - j) <= k
。如果存在,返回 true
;否则,返回 false
。
示例 1:
输入:nums = [1,2,3,1], k = 3
输出:true
示例 2:
输入:nums = [1,0,1,1], k = 1
输出:true
答案
java
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Map<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;
}
}
128. 最长连续序列
题目
给定一个未排序的整数数组 nums
,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n)
的算法解决此问题。
示例 1:
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
示例 2:
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9
答案
java
class Solution {
public int longestConsecutive(int[] nums) {
Set<Integer> set = new HashSet();
for(int num : nums){
set.add(num);
}
int res = 0;
for(int num : nums){
if(!set.contains(num-1)){
int count = 1;
while(set.contains(num+1)){
count++;
num++;
}
res = Math.max(res,count);
}
}
return res;
}
}
228. 汇总区间
题目
给定一个 无重复元素 的 有序 整数数组 nums
。
返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums
的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums
的数字 x
。
列表中的每个区间范围 [a,b]
应该按如下格式输出:
"a->b"
,如果a != b
"a"
,如果a == b
示例 1:
输入:nums = [0,1,2,4,5,7]
输出:["0->2","4->5","7"]
解释:区间范围是:
[0,2] --> "0->2"
[4,5] --> "4->5"
[7,7] --> "7"
答案
java
class Solution {
public List<String> summaryRanges(int[] nums) {
List<String> res = new ArrayList();
for(int i=0;i<nums.length;i++){
int left = i;
while(i<nums.length-1 && nums[i]+1==nums[i+1]) i++;
int right = i;
StringBuilder sb = new StringBuilder(nums[left]+"");
if(left<right){
sb.append("->").append(nums[right]+"");
}
res.add(sb.toString());
}
return res;
}
}
56. 合并区间
题目
以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例 1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
答案
java
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals,(a,b)->a[0]-b[0]);
List<int[]> res = new ArrayList();
int start = intervals[0][0],end = intervals[0][1];
for(int i=1;i<intervals.length;i++){
int[] curr = intervals[i];
if(curr[0]>end){
res.add(new int[]{start,end});
start = curr[0];
end = curr[1];
}else{
start = Math.min(start,curr[0]);
end = Math.max(end,curr[1]);
}
}
res.add(new int[]{start,end});
return res.toArray(new int[res.size()][]);
}
}
452. 用最少数量的箭引爆气球
题目
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points
,其中points[i] = [xstart, xend]
表示水平直径在 xstart
和 xend
之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x
处射出一支箭,若有一个气球的直径的开始和结束坐标为 x``start
,x``end
, 且满足 xstart ≤ x ≤ x``end
,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 points
,返回引爆所有气球所必须射出的 最小 弓箭数 。
示例 1:
输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:
-在x = 6处射出箭,击破气球[2,8]和[1,6]。
-在x = 11处发射箭,击破气球[10,16]和[7,12]。
答案
java
class Solution {
public int findMinArrowShots(int[][] points) {
Arrays.sort(points,(a,b)->Integer.compare(a[0],b[0]));//防溢出
int res = 1;
for(int i=1;i<points.length;i++){
if(points[i][0]>points[i-1][1]){
res++;
}else{
points[i][1] = Math.min(points[i][1],points[i-1][1]);
}
}
return res;
}
}
57. 插入区间
题目
给你一个 无重叠的 *,*按照区间起始端点排序的区间列表 intervals
,其中 intervals[i] = [starti, endi]
表示第 i
个区间的开始和结束,并且 intervals
按照 starti
升序排列。同样给定一个区间 newInterval = [start, end]
表示另一个区间的开始和结束。
在 intervals
中插入区间 newInterval
,使得 intervals
依然按照 starti
升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。
返回插入之后的 intervals
。
注意 你不需要原地修改 intervals
。你可以创建一个新数组然后返回它。
示例 1:
输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]
示例 2:
输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出:[[1,2],[3,10],[12,16]]
解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。
答案
java
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
int m = intervals.length;
int[][] temp = new int[m+1][2];
for(int i=0;i<m;i++){
temp[i] = intervals[i];
}
temp[m] = newInterval;
List<int[]> res = new ArrayList();
Arrays.sort(temp,(a,b)->Integer.compare(a[0],b[0]));
int start = temp[0][0],end = temp[0][1];
for(int i=1;i<m+1;i++){
int[] curr = temp[i];
if(curr[0]>end){
res.add(new int[]{start,end});
start = curr[0];
end = curr[1];
}else{
start = Math.min(start,curr[0]);
end = Math.max(end,curr[1]);
}
}
res.add(new int[]{start,end});
return res.toArray(new int[res.size()][]);
}
}
`