双指针使用

双指针-在原来的数组上修改元素(应用于)

左指针不动,右指针移动,当移动到与左指针不同的元素时,左指针移动一位,将那位的元素改为右指针的值;随后,右指针继续移动。

public static int removeDuplicates(int[] nums){
        //双指针
        int num = 0;
        for (int i = 1; i < nums.length; i++) {
            if (nums[num] != nums[i]){
                num++;
                nums[num] = nums[i];
            }
        }

        return num + 1;
    }
  • 利用++left,更简洁

    //双指针解决
    public int removeDuplicates(int[] A) {
        //边界条件判断
        if (A == null || A.length == 0)
            return 0;
        int left = 0;
        for (int right = 1; right < A.length; right++)
            //如果左指针和右指针指向的值一样,说明有重复的,
            //这个时候,左指针不动,右指针继续往右移。如果他俩
            //指向的值不一样就把右指针指向的值往前挪
            if (A[left] != A[right])
                A[++left] = A[right];
        return ++left;
    }

// 作者:数据结构和算法
// 链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/x2gy9m/?discussion=4Zkrel
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 另外一种解法

    public int removeDuplicates(int[] A) {
        int count = 0;//重复的数字个数
        for (int right = 1; right < A.length; right++) {
            if (A[right] == A[right - 1]) {
                //如果有重复的,count要加1
                count++;
            } else {
                //如果没有重复,后面的就往前挪
                A[right - count] = A[right];
            }
        }
        //数组的长度减去重复的个数
        return A.length - count;
    }

// 作者:数据结构和算法
// 链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/x2gy9m/?discussion=4Zkrel
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

扩展

  • 保留插入顺序的集合:LinkedHashSet类

要创建一个保留元素插入顺序的集合,你可以使用 LinkedHashSet 类。LinkedHashSetHashSet 的子类,但它维护了一个运行于所有条目的双重链接列表,这使得迭代顺序与插入顺序相同。下面是使用 LinkedHashSet 创建并操作一个集合的示例:

import java.util.LinkedHashSet;
import java.util.Set;

public class OrderedSetExample {
    public static void main(String[] args) {
        // 创建一个 LinkedHashSet
        Set<String> orderedSet = new LinkedHashSet<>();

        // 添加一些元素
        orderedSet.add("Apple");
        orderedSet.add("Banana");
        orderedSet.add("Cherry");
        orderedSet.add("Banana"); // Banana 已经存在,所以这个调用不会改变集合

        // 集合中的元素将按照插入顺序排列
        System.out.println("LinkedHashSet: " + orderedSet);

        // 向集合中添加一个新元素
        orderedSet.add("Date");

        // 打印更新后的集合,可以看到 Date 被添加到了最后
        System.out.println("Updated LinkedHashSet: " + orderedSet);
    }
}

输出将如下所示:

LinkedHashSet: [Apple, Banana, Cherry]
Updated LinkedHashSet: [Apple, Banana, Cherry, Date]

如你所见,尽管尝试添加了重复的 “Banana”,但 LinkedHashSet 只保存了一个 “Banana” 实例,并且集合中的元素按照它们被插入的顺序列出。

  • HashSet和TreeSet的插入顺序:

HashSetTreeSet 在 Java 中都是 Set 接口的实现,它们都保证了集合中元素的唯一性,但是它们存储和检索元素的方式不同,这影响了元素的顺序:

  • HashSet
    HashSet 是基于哈希表的数据结构。它使用哈希函数将元素映射到哈希表中的特定位置。由于哈希函数的结果可能相同(哈希冲突),HashSet 使用链表或平衡树等数据结构解决冲突,但这并不意味着元素会按照插入顺序保存。因此,HashSet 中元素的顺序是不确定的,通常与元素的哈希值和哈希表的内部结构有关。也就是说,HashSet 不保证元素的任何特定顺序,无论是插入顺序还是其他顺序。

  • TreeSet
    相比之下,TreeSet 是基于红黑树的数据结构。它会根据元素的自然顺序(通过 Comparable 接口)或者用户提供的比较器(通过 Comparator 接口)对元素进行排序。因此,TreeSet 中的元素总是按照某种顺序排列的,这个顺序取决于元素的比较方式。当你向 TreeSet 中添加元素时,元素会被插入到适当的位置以保持树的排序属性。这意味着 TreeSet 不会保留元素的插入顺序,而是按照排序规则自动调整元素的位置。

总结来说:

  • 如果你需要一个快速的、元素唯一的集合,而且元素的顺序无关紧要,那么你应该选择 HashSet
  • 如果你需要一个元素唯一的集合,并且这些元素必须按照一定的顺序(通常是自然顺序或定义的顺序)排列,那么你应该选择 TreeSet

如果你想保留元素的插入顺序,你可以使用 LinkedHashSet,它是 HashSet 的子类,使用链表链接所有的节点,从而在保持元素唯一性的同时,也保留了元素的插入顺序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值