leetCode刷题心得

123 阅读2分钟

优先队列

内部会自动实现排序,按照小根堆的原理实现,可在创建时在构造函数指定排序器,

  • (a,b)->b-a 大根堆
  • (a,b)->a-b 小根堆

leetcode

2530. 执行 K 次操作后的最大分数 - 力扣(LeetCode)

2462. 雇佣 K 位工人的总代价 - 力扣(LeetCode)

下面这是采用优先的写法

// leetcode.2530
class Solution {
    public long maxKelements(int[] nums, int k) {
         long res = 0;
        PriorityQueue<Integer> queue = new PriorityQueue<>((a, b) -> b - a);
        for (int num : nums) {
            queue.offer(num);
        }
        while (k > 0) {
            int t = queue.poll();
            res += t;
            queue.offer((t + 2) / 3);
            k--;
        }
        return res;
    }
}

这个是我自己最开始的

class Solution {
    public long maxKelements(int[] nums, int k) {
        Arrays.sort(nums);
        long res=0;
        for(int i=nums.length-1;k>0;){
            res+=nums[i];
            nums[i]=(int)Math.ceil((double)nums[i]/3);
            k--;
            sink(nums);
        }
        return res;
    }
    // 下沉算法
    public void sink(int[] nums){
        int len=nums.length-1;
        int a=nums[len];
        for(int j=len;j>=0;j--){
            if(j-1>=0&&nums[j]<nums[j-1]){
                int t=nums[j-1];
                nums[j-1]=nums[j];
                nums[j]=t;
            }else{
                break;
            }
        }
    }
}

优先队列的基本语法

PriorityQueue<Integer> queue = new PriorityQueue<>((a, b) -> b - a);
queue.add(2) //添加元素
queue.offer(3) //添加元素
queue.poll(3) //获取堆顶元素,并删除
queue.peek(3)//获取堆顶元素,但不删除
queue.size() //获取队列大小
queue.contains()//判断key是否存在于堆中

DFS剪枝

  • 40. 组合总和 II - 力扣(LeetCode)
  • 主要的思想是先对数组进行排序,使重复的数靠在一起,在进行dfs时,对当前数(j>0)candidates[j]进行判断,判断前一个数是否相同,即candidates[j]==candidates[j-1]是否成立,如果相等,则跳过该层级对该数的dfs.
class Solution { 
int sum = 0; 
LinkedList<Integer> path = new LinkedList<>(); 
List<List<Integer>> res = new ArrayList<>(); 
boolean[] marked; 
public List<List<Integer>> combinationSum2(int[] candidates, int target) { 
marked = new boolean[candidates.length]; 
Arrays.sort(candidates); 
process(candidates, target, 0);
return res;
}
private void process(int[] candidates, int target, int idx) { 
if (target == sum) { 
res.add(new ArrayList<>(path));
return;
}
for (int j = idx; j < candidates.length; j++) {
if (sum + candidates[j] > target) { 
break;
} 
// 判断该层级的当前数是否与前一个数相等
if (j > 0 && candidates[j] == candidates[j - 1] && !marked[j - 1]) { 
continue;
} 
marked[j] = true;
sum += candidates[j];
path.add(candidates[j]);
//选择下一层 
process(candidates, target, j + 1); 
marked[j] = false; 
sum -= candidates[j]; 
//恢复现场
path.removeLast(); 
} 
} 
}