leetcode 150道题 计划花两个月时候刷完,今天(第四天)完成了4道(10-13)150:
- (45. 跳跃游戏 II)题目描述:
bash
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。
每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:
0 <= j <= nums[i]
i + j < n
返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。
第一版(这个和昨天是一样的,就还是那样,只是多加了一个计数器,我没有看最优解,这个我能记住。。最优解记不住)
java
class Solution {
public int jump(int[] nums) {
// 和上一个跳跃 是一样的
//如果跳不到终点就尽可能跳到最远
int len=nums.length;
int index=0;
int res=0;
while(index<len-1){
int temp=nums[index]+index;
if(temp>=len-1){
return res+1;
}
int max=0;
for(int i=index+1;i<=temp;i++){
if(nums[i]==0){
continue;
}
if(nums[i]+i>=max){
index=i;
max=nums[i]+i;
}
}
// 这个应该可以不加判断,题目应该会保证给的测试例子都可以跳到终点的。。
if(max==0)
return 0;
res++;
}
return res;
}
}
- (274. H 指数)题目描述:
bash
给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。
根据维基百科上 h 指数的定义:h 代表"高引用次数" ,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且每篇论文 至少 被引用 h 次。如果 h 有多种可能的值,h 指数 是其中最大的那个。
这个题我真的做了至少四遍了,每次都做不出来,是真的理解不了他说的,然后我去查了维基百科上的,上面就有算法(我感觉这个好理解,最优的二分法感觉记不住。。):
可以按照如下方法确定某人的H指数:
1、将其发表的所有SCI论文按被引次数从高到低排序;
2、从前往后查找排序后的列表,只要当前的引用量大于当前的索引值,则H指数加1,最后得到的结果即为最终的H指数
第一版(按照这个维基百科算法去写的)
java
class Solution {
public int hIndex(int[] citations) {
int hNum=0;
int len=citations.length;
Arrays.sort(citations);
for(int i=len-1;i>=0;i--){
if(citations[i]>len-i-1)
hNum++;
}
return hNum;
}
}
- (380. O(1) 时间插入、删除和获取随机元素)题目描述:
bash
实现RandomizedSet 类:
RandomizedSet() 初始化 RandomizedSet 对象
bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false 。
bool remove(int val) 当元素 val 存在时,从集合中移除该项,并返回 true ;否则,返回 false 。
int getRandom() 随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。
你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1) 。
第一版(代码比较长,就只放一版,这个确实人家在删除时候处理很巧妙,值得学习)
java
class RandomizedSet {
ArrayList<Integer> list;
Random random;
Map<Integer,Integer> map;
public RandomizedSet() {
list=new ArrayList<Integer>();
random = new Random();
map=new HashMap<Integer,Integer>();
}
public boolean insert(int val) {
if(map.keySet().contains(val))
return false;
list.add(val);
map.put(val,list.size()-1);
return true;
}
public boolean remove(int val) {
if(!map.keySet().contains(val))
return false;
int index=map.get(val);
int lastValue=list.get(list.size()-1);
map.put(lastValue,index);
list.set(index,lastValue);
list.remove(list.size()-1);
map.remove(val);
return true;
}
public int getRandom() {
int size=list.size();
return list.get(random.nextInt(size));
}
}
- (238. 除自身以外数组的乘积)题目描述:
bash
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。
题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请 不要使用除法,且在 O(n) 时间复杂度内完成此题。
第一版(当然是暴力求解了,但是我加了一些优化以为是最优解,没想到超时了。。)
java
class Solution {
public int[] productExceptSelf(int[] nums) {
int len=nums.length;
int[] res=new int[len];
for(int i=0;i<len;i++){
if(nums[i]==0){
// 其他为 0
res[i]=getNum(nums,i);
return res;
}
}
for(int i=0;i<len;i++){
res[i]=getNum(nums,i);
}
return res;
}
public int getNum(int[] nums,int i){
int temp=1;
for(int j=0;j<nums.length;j++){
if(j==i){
continue;
}
if(nums[j]==0){
temp=0;
break;
}
temp*=nums[j];
}
return temp;
}
}
第二版(看的解析,人家还是厉害啊!!)
java
class Solution {
public int[] productExceptSelf(int[] nums) {
int len=nums.length;
int[] res=new int[len];
int[] lAnswer=new int[len];
int[] rAnswer=new int[len];
lAnswer[0]=1;
for(int i=1;i<len;i++){
lAnswer[i]=nums[i-1]*lAnswer[i-1];
}
rAnswer[len-1]=1;
for(int i=len-2;i>=0;i--){
rAnswer[i]=nums[i+1]*rAnswer[i+1];
}
for(int i=0;i<len;i++){
res[i]=lAnswer[i]*rAnswer[i];
}
return res;
}
}
早日跳槽,跳槽!!!!!
真的现在待的公司感觉一点前途都没有。。看不到未来啊。