274. H 指数
题目
给你一个整数数组 citations
,其中 citations[i]
表示研究者的第 i
篇论文被引用的次数。计算并返回该研究者的 h
指数。
根据维基百科上 h 指数的定义:h
代表“高引用次数” ,一名科研人员的 h
指数 是指他(她)至少发表了 h
篇论文,并且 至少 有 h
篇论文被引用次数大于等于 h
。如果 h
有多种可能的值,h
指数 是其中最大的那个。
示例 1:
输入:citations = [3,0,6,1,5]
输出:3
解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 3, 0, 6, 1, 5 次。由于研究者有 3 篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3。
示例 2:
输入:citations = [1,3,1]
输出:1
答案
class Solution {public int hIndex(int[] citations) {Arrays.sort(citations);int i = citations.length - 1;int h = 0;while(i>=0 && h<citations[i]){i--;h++;}return h;}
}
380. O(1) 时间插入、删除和获取随机元素
题目
实现RandomizedSet
类:
RandomizedSet()
初始化RandomizedSet
对象bool insert(int val)
当元素val
不存在时,向集合中插入该项,并返回true
;否则,返回false
。bool remove(int val)
当元素val
存在时,从集合中移除该项,并返回true
;否则,返回false
。int getRandom()
随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。
你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1)
。
答案
class RandomizedSet {Map<Integer,Integer> map;List<Integer> list;Random random;public RandomizedSet() {map = new HashMap();list = new ArrayList();random = new Random();}public boolean insert(int val) {if(map.containsKey(val)){return false;}int index = list.size();list.add(val);map.put(val,index);return true;}public boolean remove(int val) {if(!map.containsKey(val)){return false;}//让最后一个填补删除的位置,保持list的索引映射int index = map.get(val);int last = list.get(list.size()-1);list.set(index,last);map.put(last,index);list.remove(list.size()-1);map.remove(val);return true;}public int getRandom() {int index = random.nextInt(list.size());return list.get(index);}
}
238. 除自身以外数组的乘积
题目
给你一个整数数组 nums
,返回 数组 answer
,其中 answer[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积 。
题目数据 保证 数组 nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请 **不要使用除法,**且在 O(*n*)
时间复杂度内完成此题。
示例 1:
输入: nums = [1,2,3,4]
输出: [24,12,8,6]
示例 2:
输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]
答案
class Solution {public int[] productExceptSelf(int[] nums) {int len = nums.length;int[] left = new int[len];int[] right = new int[len];left[0] = 1;for(int i=1;i<len;i++){left[i] = nums[i-1] * left[i-1];}right[len-1] = 1;for(int i=len-2;i>=0;i--){right[i] = right[i+1] * nums[i+1];}int[] res = new int[len];for(int i=0;i<len;i++){res[i] = left[i] * right[i];}return res;}
}
134. 加油站
题目
在一条环路上有 n
个加油站,其中第 i
个加油站有汽油 gas[i]
升。
你有一辆油箱容量无限的的汽车,从第 i
个加油站开往第 i+1
个加油站需要消耗汽油 cost[i]
升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas
和 cost
,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1
。如果存在解,则 保证 它是 唯一 的。
示例 1:
输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
输出: 3
解释:
从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。
答案
class Solution {public int canCompleteCircuit(int[] gas, int[] cost) {int currSum = 0;int totalSum = 0;int index = 0;for(int i=0;i<gas.length;i++){totalSum += gas[i] - cost[i];currSum += gas[i] - cost[i];if(currSum<0){currSum = 0;index = (i+1)%gas.length;}}return totalSum<0 ? -1 : index;}
}
135. 分发糖果
题目
n
个孩子站成一排。给你一个整数数组 ratings
表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到
1
个糖果。 - 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
示例 1:
输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
答案
class Solution {public int candy(int[] ratings) {int len = ratings.length;int[] res = new int[len];res[0] = 1;for(int i=1;i<len;i++){if(ratings[i]>ratings[i-1]){res[i] = res[i-1] + 1;}else{res[i] = 1;}}for(int i=len-2;i>=0;i--){if(ratings[i]>ratings[i+1]){res[i] = Math.max(res[i],res[i+1]+1);}}int sum = 0;for(int num : res){sum += num;}return sum;}
}
42. 接雨水
题目
给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
答案
class Solution {public int trap(int[] height) {int len = height.length;int left = 0,right = len - 1;int leftMax = 0,rightMax = 0;int res = 0;while(left<right){leftMax = Math.max(leftMax,height[left]);rightMax = Math.max(rightMax,height[right]);if(height[left]<height[right]){res += leftMax - height[left++];}else{res += rightMax - height[right--];}}return res;}
}
13. 罗马数字转整数
题目
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2
写做 II
,即为两个并列的 1 。12
写做 XII
,即为 X
+ II
。 27
写做 XXVII
, 即为 XX
+ V
+ II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII
,而是 IV
。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX
。这个特殊的规则只适用于以下六种情况:
I
可以放在V
(5) 和X
(10) 的左边,来表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左边,来表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。
示例 1:
输入: s = "III"
输出: 3
答案
class Solution {Map<Character,Integer> map = new HashMap(){{ put('I',1);put('V',5);put('X',10);put('L',50);put('C',100);put('D',500);put('M',1000);}};public int romanToInt(String s) {int res = 0;for(int i=0;i<s.length();i++){int val = map.get(s.charAt(i));if(i<s.length()-1 && val<map.get(s.charAt(i+1))){res -= val;}else{res += val;}}return res;}
}
12. 整数转罗马数字
题目
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II
,即为两个并列的 1。12 写做 XII
,即为 X
+ II
。 27 写做 XXVII
, 即为 XX
+ V
+ II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII
,而是 IV
。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX
。这个特殊的规则只适用于以下六种情况:
I
可以放在V
(5) 和X
(10) 的左边,来表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左边,来表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左边,来表示 400 和 900。
给你一个整数,将其转为罗马数字。
示例 1:
输入: num = 3
输出: "III"
示例 2:
输入: num = 4
输出: "IV"
答案
class Solution {public String intToRoman(int num) {int[] values = {1000,900,500,400,100,90,50,40,10,9,5,4,1};String[] strs = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};StringBuilder sb = new StringBuilder();for(int i=0;i<values.length;i++){while(num>=values[i]){num -= values[i];sb.append(strs[i]);}if(num==0){break;}}return sb.toString();}
}
58. 最后一个单词的长度
题目
给你一个字符串 s
,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。
单词 是指仅由字母组成、不包含任何空格字符的最大
子字符串
示例 1:
输入:s = "Hello World"
输出:5
解释:最后一个单词是“World”,长度为5。
示例 2:
输入:s = " fly me to the moon "
输出:4
解释:最后一个单词是“moon”,长度为4。
答案
class Solution {public int lengthOfLastWord(String s) {int right = 0,left = 0;for(int i=s.length()-1;i>=0;i--){while(i>=0 && s.charAt(i)==' ') i--;right = i;while(i>=0 && s.charAt(i)!=' ') i--;left = i;break;}return right - left;}
}class Solution {public int lengthOfLastWord(String s) {String[] strs = s.split(" ");return strs[strs.length-1].length();}
}