LeetCode刷题(448,21,83,141,142,160)

448. 找到所有数组中消失的数字icon-default.png?t=M0H8https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/

难度简单886

给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。

解法一:利用数组存储元素信息

class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        //方法一我们采用一个数组对原有数组中的元素进行存储
        Integer[] arr=new Integer[nums.length];
        HashSet<Integer> hashSet=new HashSet<>();
        List<Integer> list=new ArrayList<>();
        for (int i=0;i<nums.length;i++){
            arr[nums[i]-1]=1;//把已经出现位置了的元素改为1
        }
        for (int i=0;i<arr.length;i++){//把数组中元素为null的下标加入到list中
            if (arr[i]==null){
                list.add(i+1);
            }
        }
        return list;

    }
}

解法二:

 

public List<Integer> findDisappearedNumbers(int[] nums) {
        //我们把数组中元素的下标的元素加上一个数组长度,当然,再下一次循环使用的时候要将其变回来,否则会导致数组越界
        int n=nums.length;
        for (int i:nums){
            int x=(i-1)%n;//真正的可以使用的下标
            nums[x]+=n;
        }
        List<Integer> list=new ArrayList<>();
        for (int i=0;i<n;i++){//如果那个下标的元素对应的值小于n,则说明它的值没有被更改,也就是要返回的元素
            if(nums[i]<=n){
                list.add(i+1);
            }
        }
        return list;
    }

 

21. 合并两个有序链表

难度简单2163

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

解法一:

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
    ListNode fakeHead=new ListNode(0);
            ListNode last=fakeHead;
            ListNode cur1=list1;
            ListNode cur2=list2;
            while (cur1!=null&&cur2!=null){//谁的值小把谁插入到新的链表中
                if (cur1.val<cur2.val){
                    last.next=cur1;
                    cur1=cur1.next;
                }else {
                    last.next=cur2;
                    cur2=cur2.next;
                }
                last=last.next;
            }
            //已经有一个链表遍历完了
            if (cur1==null){
                last.next=cur2;
            }
            if (cur2==null){
                last.next=cur1;
            }
            return fakeHead.next;
    }
}

 解法二:

public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if (list1==null){
            return list2;
        }
        if (list2==null){
            return list1;
        }
        if (list1.val<list2.val){
            list1.next=mergeTwoLists(list1.next,list2);
            return list1;
        }else {
            list2.next=mergeTwoLists(list1,list2.next);
            return list2;
        }
    }

83. 删除排序链表中的重复元素

难度简单720

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

public ListNode deleteDuplicates(ListNode head) {
        ListNode cur=head;
        while (cur!=null&&cur.next!=null){
            if (cur.val==cur.next.val){
                cur.next=cur.next.next;
            }else {
                cur=cur.next;
            }
        }
        return head;
    }

 

 

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode cur=head;//解法一,利用hashset进行存储,若出现相同元素直接返回false
        HashSet hashSet=new HashSet();
        while (cur!=null){
            if (hashSet.contains(cur)){
                return true;
            }
            hashSet.add(cur);
            cur=cur.next;
        }
        return false;//不是循环链表
    }
}

 

 

public boolean hasCycle(ListNode head) {
        //使用快慢指针
        ListNode cur1=head;//快指针,一次走两步
        ListNode cur2=head;//慢指针,一次走一步
        while (cur1!=null&&cur1.next!=null){
            cur1=cur1.next.next;
            cur2=cur2.next;
            if (cur1==cur2){
                return true;
            }
        }
        return false;
    }

 

 

public ListNode detectCycle(ListNode head) {
        //使用快慢指针
        ListNode cur1=head;//快指针,一次走两步
        ListNode cur2=head;//慢指针,一次走一步
        while (cur1!=null&&cur1.next!=null){
            cur1=cur1.next.next;
            cur2=cur2.next;
            if (cur1==cur2){
                cur1=head;//此处涉及一部分数学推导,建议去leetcode查看,将快指针置为慢指针,下一次相遇便是环形节点
                while (cur1!=cur2){
                    cur1=cur1.next;
                    cur2=cur2.next;
                }
                return cur1;
            }
        }
        return null;

    }

 

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        //解法一:利用hashset不可重复存储的特型
        HashSet hashSet=new HashSet();
        //双指针,分别遍历添加至hashset
        ListNode cur1=headA;
        ListNode cur2=headB;
        while (cur1!=null){
            hashSet.add(cur1);//遍历添加链表1中的元素
            cur1=cur1.next;
        }
        while(cur2!=null){
            if (!hashSet.add(cur2)){//链表2中的元素添加不进去,说明此元素是相交节点
                return cur2;
            }
            cur2=cur2.next;
        }
        return null;
    }

 

 

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        //解法二,遍历长度设置为两条链表长度之和,那么在相交的地方他们就会相等
        ListNode cur1=headA;
        ListNode cur2=headB;
        while (cur1!=cur2){
            cur1=cur1==null?headB:cur1.next;
            cur2=cur2==null?headA:cur2.next;
        }
        return cur1;

    }

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        //解法三:可以先计算链表的长度,让长的链表先走
        ListNode cur1=headA;
        ListNode cur2=headB;
        int length1=getLength(headA);
        int length2=getLength(headB);
        if (length1>length2){
            for (int i=0;i<length1-length2;i++){
                cur1=cur1.next;
            }
        }else {
            for (int i=0;i<length2-length1;i++){
                cur2=cur2.next;
            }
        }
        while (cur1!=null){//此时需要遍历的次数相同
            if (cur1==cur2){
                return cur1;
            }
            cur1=cur1.next;
            cur2=cur2.next;
        }
        return null;
        
    }
    public int getLength(ListNode node){
        ListNode cur=node;
        int len=0;
        while (cur!=null){
            len++;
            cur=cur.next;
        }
        return len;
    }

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值