面试经典150题【持续更新】

一、数组 / 字符串

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

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

示例 2:

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


class Solution {
    public int removeDuplicates(int[] nums) {
            return process(nums, 2);
    }
    int process(int[] nums, int k) {
        int u = 0; 
        for(int x : nums) {
            if (u < k || nums[u - k] != x) nums[u++] = x;
        }
        return u;
    }

}

2. 买卖股票的最佳时机

在这里插入图片描述

class Solution {
    public int maxProfit(int[] prices) {
        int cost =Integer.MAX_VALUE, profit = 0;
        for (int price : prices) {
            cost =Math.min(cost, price);
            profit = Math.max(profit, price-cost);
        }
        return profit;
    }

}

3. 跳跃游戏

class Solution {
    public boolean canJump(int[] nums) {
            int n = nums.length;  //数组长度
            int rightmost = 0;    //跳跃到的最远位置
            for (int i = 0; i < n; ++i) {  
                if (i <= rightmost) {  //能够跳,并算出跳后所在位置
                    rightmost = Math.max(rightmost, i + nums[i]);
                    if (rightmost >= n - 1) {  //跳的最大位置是否大于数组长度
                        return true;
                    }
                }
            }
            return false;
    }
}

4.跳跃游戏 II

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/*
示例 1:

输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:

输入: nums = [2,3,0,1,4]
输出: 2
*/

class Solution {
    public int jump(int[] nums) {
    //1.变量定义:
         int length = nums.length;
         int end = 0;
         int maxPosition = 0;
         int steps = 0;
    //2.遍历数组:
         for (int i = 0; i < length - 1; i++) {
    //3.更新maxPosition:
            maxPosition = Math.max(maxPosition, i + nums[i]); 
    //4.检查是否到达当前跳跃的边界:
            if (i == end) {
                end = maxPosition;
                steps++;
            }
        }
    //5.返回结果:
    return steps;
    }
}


 

5. 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) {
        int n = citations.length;
        int[] cnt = new int[n + 1];
        for (int c : citations) {
            cnt[Math.min(c, n)]++; //引用次数 > n,等价于引用次数为 n,cnt[i]将用来存储引用次数为i的论文数量。
        }
        int s = 0;   //因为s是累加所有论文数量的
        for (int i = n; ; i--) { // i=0 的时候,s>=i 一定成立
            s += cnt[i];
            if (s >= i) { // 说明有至少 i 篇论文的引用次数至少为 i
                return i;
            }
        }
    }
}

6.O(1) 时间插入、删除和获取随机元素

/*
示例:

输入
["RandomizedSet", "insert", "remove", "insert", "getRandom", "remove", "insert", "getRandom"]
[[], [1], [2], [2], [], [1], [2], []]
输出
[null, true, false, true, 2, true, false, 2]

解释
RandomizedSet randomizedSet = new RandomizedSet();
randomizedSet.insert(1); // 向集合中插入 1 。返回 true 表示 1 被成功地插入。
randomizedSet.remove(2); // 返回 false ,表示集合中不存在 2 。
randomizedSet.insert(2); // 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
randomizedSet.getRandom(); // getRandom 应随机返回 1 或 2 。
randomizedSet.remove(1); // 从集合中移除 1 ,返回 true 。集合现在包含 [2] 。
randomizedSet.insert(2); // 2 已在集合中,所以返回 false 。
randomizedSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom 总是返回 2 。
*/
 
 class RandomizedSet {

    List<Integer> nums;
    Map<Integer, Integer> indices;
    Random random;


    public RandomizedSet() {
      nums = new ArrayList<Integer>();
      indices = new HashMap<Integer, Integer>();
      random = new Random();
    }
    /*使用 HashMap (indices) 来存储每个元素及其对应的索引。这样,在插入新元素时,可以通过 HashMap 的 containsKey 方法在 O(1) 的时间复杂度内检查元素是否已经存在。
如果元素不存在,直接将元素添加到 ArrayList (nums) 的末尾,并在 HashMap 中记录该元素及其索引。因为 ArrayList 的 add 方法在末尾添加元素的时间复杂度是 O(1),所以这一步也是 O(1) 的。
*/
    public boolean insert(int val) {
       if (indices.containsKey(val)) {
        return false;
       }
       int index =nums.size();
       nums.add(val);
       indices.put(val, index);
       return true;
    }
    /*
    使用 HashMap 来查找要删除元素的索引,这同样是 O(1) 的操作。
找到索引后,将 ArrayList 的最后一个元素移动到要删除元素的位置。
这一步涉及到两个操作:获取最后一个元素和设置新位置的值,都是 O(1) 的。
更新 HashMap 中最后一个元素的索引。
从 ArrayList 和 HashMap 中删除被删除的元素。ArrayList 的 remove 方法在已知索引的情况下删除元素的时间复杂度是 O(n-k),
其中 n 是列表的大小,k 是要删除元素的索引。然而,因为我们总是删除最后一个元素(通过交换),所以这个操作的平均时间复杂度实际上是 O(1)。
  */
    public boolean remove(int val) {
if (!indices.containsKey(val)) {
            return false;
        }
        int index = indices.get(val);
        int last = nums.get(nums.size() - 1);
        nums.set(index, last);
        indices.put(last, index);
        nums.remove(nums.size() - 1);
        indices.remove(val);
        return true;

    }
    /*
    使用 Random 类的 nextInt 方法生成一个随机索引,这个操作是 O(1) 的。
通过随机索引从 ArrayList 中获取元素也是 O(1) 的操作。
*/
    public int getRandom() {
        int randomIndex = random.nextInt(nums.size());
        return  nums.get(randomIndex);

    }
}


7.除自身以外数组的乘积


/*
示例 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;
        if (len == 0) return new int[0];
        int[] ans = new int[len];
        ans[0] = 1;
        int tmp = 1;
        for (int i = 1; i < len; i++) {
            ans[i] = ans[i - 1] * nums[i - 1];
        }
        for (int i = len - 2; i >= 0; i--) {
            tmp *= nums[i + 1];
            ans[i] *= tmp;
        }
        return ans;

    }
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值