面试经典150题(10-13)

leetcode 150道题 计划花两个月时候刷完,今天(第四天)完成了4道(10-13)150:
10. (45. 跳跃游戏 II)题目描述:

给定一个长度为 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]

第一版(这个和昨天是一样的,就还是那样,只是多加了一个计数器,我没有看最优解,这个我能记住。。最优解记不住)

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;
    }
}
  1. (274. H 指数)题目描述:
给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。
根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且每篇论文 至少 被引用 h 次。如果 h 有多种可能的值,h 指数 是其中最大的那个。

这个题我真的做了至少四遍了,每次都做不出来,是真的理解不了他说的,然后我去查了维基百科上的,上面就有算法(我感觉这个好理解,最优的二分法感觉记不住。。):
可以按照如下方法确定某人的H指数:
1、将其发表的所有SCI论文按被引次数从高到低排序;
2、从前往后查找排序后的列表,只要当前的引用量大于当前的索引值,则H指数加1,最后得到的结果即为最终的H指数

第一版(按照这个维基百科算法去写的)

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;
    }
}
  1. (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 {
    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));
    }
}
  1. (238. 除自身以外数组的乘积)题目描述:
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。
题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在  32 位 整数范围内。
请 不要使用除法,且在 O(n) 时间复杂度内完成此题。

第一版(当然是暴力求解了,但是我加了一些优化以为是最优解,没想到超时了。。)

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;
    }
}

第二版(看的解析,人家还是厉害啊!!)

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;
    }
}

早日跳槽,跳槽!!!!!
真的现在待的公司感觉一点前途都没有。。看不到未来啊。

你可能感兴趣的:(面试经典,150,题,面试,算法,java)