21年11月第一周 力扣每日一题记录

本周每日一题 题目

  • lc575. 分糖果
  • lc237. 删除链表中的节点
  • lc367. 有效的完全平方数
  • lc1218. 最长定差子序列
  • lc268. 丢失的数字

11-01 lc575. 分糖果

  • 数组的长度就是糖果的数量
  • 然后数量是平均分配的
  • 题目是希望妹妹能够获得更多种类的糖果(数量一定)
  • 那么对于妹妹来说,尽量是一个种类获得一种 。那么统计种类数x,如果大于n/2,那么就是n/2,否则就是x
class Solution {
    
    
    public int distributeCandies(int[] candyType) {
    
    
        //统计种类数
        Set<Integer> set = new HashSet<>();
        for(int num:candyType) set.add(num);
        return Math.min(candyType.length/2,set.size());
    }
}

11-02 lc237. 删除链表中的节点

  • 这题一看挺简单的,仔细看了,也挺简单
  • 不给头结点,只给需要删除的节点,那么直接将下一个值复制过来,然后跳过下一个就OK了
  • 然后这里因为不能处理要删除节点是最终节点的情况,除非给头节点
class Solution {
    
    
    //奥,不给头节点,只给要删除的节点
    //这样,把下一个节点的数值复制过来,然后删除下一个点就好
    //因为不是末尾节点,所以无所谓
    public void deleteNode(ListNode node) {
    
    
        node.val = node.next.val;
        node.next = node.next.next;
    }
}

11-04 lc367. 有效的完全平方数

  • 二分,没啥好说的
  • 看评论,好多老哥骚操作一个接一个,对不起,我没想到。。。就二分把,也凑合
class Solution {
    
    
    //从num开始二分,直到找到为止
    //不一定会有
    public boolean isPerfectSquare(int num) {
    
    
        long l = 1, r = num;
        while(l<r){
    
    
            long mid = (l+r)/2;
            if(mid*mid>num) r = mid-1;
            else if(mid*mid<num) l = mid+1;
            else return true;
        }
        return l*l==num;
    }
}

11-05 lc1218. 最长定差子序列

  • 这个子序列是不考虑连续的
  • 思路是用map记录前面的数,和前面的数的长度位置,那么我在遍历时,只要看看map中是否有当前数-diff存在即可,在的话,自己的长度就是前面数+1
class Solution {
    
    
    //这个可以不连续的
    //记录下previous的数字的长度,然后后面直接连上,感觉也会好很多
    public int longestSubsequence(int[] arr, int diff) {
    
    
        Map<Integer,Integer> map = new HashMap<>();
        int res = 0;
        for(int a:arr){
    
    
            int cnt = map.getOrDefault(a-diff,0) + 1;
            res = Math.max(cnt,res);
            map.put(a,cnt);
        }
        return res;
    }
}

11-06 lc268. 丢失的数字

  • 给定一个长度为n的数组,其中数字满足0-n,不重复,则必然缺少一个,求缺少的那个,时间O(n),空间O(1)
  • 这种题一看就是swap
  • 然后因为给的数组不够大,所以java这里没有办法,你n+1个数swap会越界的,所以我这里直接舍弃0,只考虑1-n,将1-n放到数组的0~n-1的位置上
  • 具体的逻辑是,0忽略,不swap。最终看哪个位置上是0,如果没有0,则缺失0
  • 这样做的理由是:如果缺失0,那么剩下的所有数必然满足1~n,刚好能放的下;如果缺失的不是0,则其他的也放的下,0就占一个位置不动
  • (当然还可以求1~n的累加和-sum(nums)也可以,这个要考虑溢出)
class Solution {
    
    
    //n个数,范围是n+1,每个数字只出现一次,求缺少的那个
    //要求时间O(n),空间O(1)
    public int missingNumber(int[] nums) {
    
    
        int n = nums.length;
        for(int i=0; i<n; i++){
    
    
            while(nums[i]!=0&&nums[i]!=i+1) swap(nums,i,nums[i]-1);//交换过来的不一定准确
        } 
        for(int i=0; i<n; i++){
    
    
            if(nums[i]==0) return i+1;
        }
        return 0;
    }

    private void swap(int[] nums, int i, int j){
    
    
        int t = nums[i];
        nums[i] = nums[j];
        nums[j] = t;
    }
}

Guess you like

Origin blog.csdn.net/qq_34687559/article/details/121073888