【力扣刷题】两数求和、移动零、相交链表、反转链表

简介: 【力扣刷题】两数求和、移动零、相交链表、反转链表

一、两数之和

1.1题目描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

1.2思路

这道题我的思路是遍历数组,通过for循环对数组进行遍历,在这个for循环中内嵌一个for循环对数组遍历,内部for循环中判断当前索引值与外部循环当前索引值相加与目标值比较,判断是否相等,若相等,则返回一个数组,数组内元素就是两个for循环当前的索引,若不相等,则继续遍历,数组遍历完后仍未找到,则返回一个空数组。

1.3 代码

public int[] twoSum(int[] nums, int target) {
        int n = nums.length;
        for (int i = 0;i < n;i++) {
            for(int j = i + 1;j < n;j++) {
                if(nums[i] + nums[j] == target) {
                    return new int[]{i,j};
                }
            }
        }
        return new int[]{0};
    }

二、移动零

2.1题目描述

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

2.2思路

我的思路是遍历数组,定义左右指针,初始时两个指针left、right均指向数组0索引处,当right小于数组长度时,开始循环,在循环内判断right索引处的值是否等于0,若等于0则与left索引处的值进行交换,交换后left自增,right也自增,若不等于0,则只需right自增,依次遍历,得出最终数组。

2.3代码

public void moveZeroes(int[] nums) {
        int n = nums.length;
        int left = 0;
        int right = 0;
        while (right < n) {
            if(nums[right] != 0) {
                swap(nums,left,right);
                left++;
            }
            right++;
        }
    }
    public void swap(int[] nums,int left,int right) {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
    }

三、相交链表

3.1题目描述

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交:

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须保持其原始结构 。

3.12思路

这道题可以通过利用Set集合的特性进行求解,分析题目可以看出是要我们在两个单链表中找出两个链表开始相交时的节点,那么我们就可以先将一个链表存入Set集合,再遍历第二个链表利用Set集合的contains()方法判断当前集合中是否包含第二个集合的节点,若包含,则直接返回当前节点,不包含则继续遍历,遍历完仍未找到,则返回null。

3.3代码

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        Set<ListNode> set = new HashSet<ListNode>();
        ListNode temp = headA;
        while (temp != null) {
            set.add(temp);
            temp = temp.next;
        }
        temp = headB;
        while (temp != null) {
            if(set.contains(temp)) {
                return temp;
            }
            temp = temp.next;
        }
        return null;
    }

四、反转链表

4.1题目描述

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

  • 输入:head = [1,2,3,4,5]
  • 输出:[5,4,3,2,1]


4.2思路一

链表反转后顺序跟之前是完全相反的,创建一个空节点n1,初始让n1.next指向null,表示n1是最后一个节点,创建一个节点指针p,p初始指向链表的头,开始遍历链表,当p不为空时,创建新节点,新节点的值为当前节点p的值,新节点的下一个节点为n1,再将这个新节点赋给n1,遍历下一个节点,当遍历完成后,返回n1,此时n1就是新链表的头节点。

4.3代码

public ListNode reverseList(ListNode head) {
        if (head == null) {
             return null;
         }
         ListNode n1 = null;
         ListNode p = head;
         while (p != null) {
             n1 = new ListNode(p.val,n1);
             p = p.next;
         }
         return n1;
    }

这种方式在每次循环时都需要创建一个新的节点,效率太低。

4.4思路二

第二种方式是将这个链表进行重新构造,在这个链表的基础上进行头删,将头删拿到的节点作为新节点进行头插形成新的链表,具体通过创建一个外部类,外部类中有头插和头删得到节点值的方法,创建两个外部类的对象,进行上面的思路操作,返回新链表的头结点即可。

4.5代码

public ListNode reverseList(ListNode head) {
        List list1 = new List(head);
        List list2 = new List(null);
        while (true) {
            ListNode first = list1.removeFirst();
            if (first == null) {
                break;
            }
            list2.addFirst(first);
        }
        return list2.head;
    }
    static class List {
        ListNode head;
        public List(ListNode head) {
            this.head = head;
        }
        public void addFirst(ListNode first) {
            first.next = head;
            head = first;
        }
        public ListNode removeFirst() {
            ListNode first = head;
            if (first != null) {
                head = first.next;
            }
            return first;
        }
    }

4.6思路三

第三种方式是用递归,在反转链表方法中再次调用反转链表方法参数为当前头结点的下一个节点,返回前,将头结点的下一个的下一个指向头head,头的下一个指向null,最后返回最后一个节点。

4.7代码

public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode last = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return last;
    }


相关文章
|
7天前
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
|
3天前
|
Java Python
二刷力扣--链表
二刷力扣--链表
|
4天前
|
算法
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
|
7天前
|
存储 算法 数据可视化
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
|
7天前
|
SQL 算法 数据可视化
LeetCode题目92:反转链表ll 【python 递归与迭代方法全解析】
LeetCode题目92:反转链表ll 【python 递归与迭代方法全解析】
|
1月前
【移除链表元素】LeetCode第203题讲解
【移除链表元素】LeetCode第203题讲解
|
7天前
|
存储 SQL 算法
LeetCode 题目 86:分隔链表
LeetCode 题目 86:分隔链表
|
7天前
|
存储 SQL 算法
LeetCode 83题:删除排序链表中的重复元素【面试】
LeetCode 83题:删除排序链表中的重复元素【面试】
|
7天前
|
存储 SQL 算法
LeetCode 题目 82:删除排序链表中的重复元素 II
LeetCode 题目 82:删除排序链表中的重复元素 II
|
8天前
|
算法 数据挖掘 Python
LeetCode题目25 hard:K个一组翻转链表 【分治策略 Python】
LeetCode题目25 hard:K个一组翻转链表 【分治策略 Python】