常见数据结构与算法一

目录

寻找数组的枢轴索引

删除排序数组中的重复项

双指针算法:


寻找数组的枢轴索引

数组中某一个下标,这个索引将数组分成左右两部分,使得左边部分的所有元素之和等于右边部分的所有元素之和,该下标即为枢轴索引

在这个数组中,枢轴索引是 3,因为在索引 3 的左侧(1 + 7 + 3 = 11)和右侧(5 + 6 = 11)的元素之和相等。现在我们使用修正后的 pivotIndex 方法来计算这个数组的枢轴索引,并打印结果。

public class Main {
    public static void main(String[] args) {
        int[] nums = {1, 7, 3, 6, 5, 6};
        System.out.println(pivotIndex(nums)); // 应该打印出 3
    }

    public static int pivotIndex (int[] nums) {
        int sum1 = Arrays.stream(nums).sum();
        int sum2 = 0;
        for (int i = 0; i < nums.length; i++) {
            if (sum1 - nums[i] == sum2) {
                return i;
            }
            sum2 += nums[i];
            sum1 -= nums[i];
        }
        return -1;
    }
}

方法的逻辑如下:

  1. 首先,使用 Arrays.stream(nums).sum() 计算整个数组 nums 的元素之和,将这个总和赋值给变量 sum1。这个总和代表了数组右侧所有元素的初始和。

  2. 然后,初始化一个变量 sum2 来存储数组左侧的元素和,初始值为 0。

  3. 接下来,遍历数组 nums。对于每个索引 i

    • 将当前元素 nums[i] 的值加到 sum2 上,这样 sum2 就是从数组开始到当前元素的所有元素之和,即左侧部分的和。
    • 如果在任何点上 sum1(右侧部分的和)等于 sum2(左侧部分的和),那么当前的索引 i 就是所谓的“枢轴”索引,方法返回这个索引。
    • 如果不相等,那么从 sum1 减去当前元素 nums[i] 的值,因为我们将 i 索引的元素从右侧部分移除,加入到左侧部分。
  4. 如果整个数组遍历完毕后,没有找到这样的“枢轴”索引,方法返回 -1

这个方法的时间复杂度是 O(n),因为它只需要遍历数组一次。空间复杂度是 O(1),因为它只使用了固定数量的额外空间。

删除排序数组中的重复项

从一个已排序的数组 nums 中移除重复的元素,并且返回移除重复元素后的新数组的长度。这个方法是原地算法,也就是说它不使用额外的数组空间来存储结果,而是直接在输入的数组上进行修改。

双指针算法:

public class Main {
    public static void main(String[] args) {
        int[] nums = {1, 1, 2, 2, 3, 3, 3, 4, 4, 5};
        int newLength = removeDuplicates(nums);

        // 打印新数组的长度
        System.out.println("New length: " + newLength); // New length: 5

        // 打印新数组的有效部分 1 2 3 4 5 
        for (int i = 0; i < newLength; i++) {
            System.out.print(nums[i] + " ");
        }
    }

    public static int removeDuplicates(int[] nums) {
        if (nums.length == 0) return 0;
        int i = 0;
        for (int j = 1; j < nums.length; j++) {
            if (nums[j] != nums[i]) {
                i++;
                nums[i] = nums[j];
            }
        }
        return i + 1;
    }
}

方法的逻辑如下:

  1. 首先,检查数组的长度。如果长度为 0,则没有元素可以删除,直接返回 0

  2. 初始化一个指针 i,用来跟踪不重复元素的最新索引位置。初始时,i 设为 0,因为即使数组中只有一个元素,那么这个元素也是不重复的。

  3. 遍历数组,从索引 1 开始,使用另一个指针 j。这是因为我们已经假定了索引 0 处的元素是不重复的,所以从 1 开始检查。

  4. 在遍历过程中,如果 nums[j](当前遍历到的元素)不等于 nums[i](最后一个不重复的元素),则执行以下操作:

    • 将 i 加 1,因为我们发现了一个新的不重复元素,所以需要移动 i 指针。
    • 将 nums[j] 的值赋给 nums[i],这样就在 nums 的前部创建了一个不包含重复元素的子数组。
  5. 遍历完成后,所有不重复的元素都被移动到了数组的前部。

  6. 最后,返回 i + 1,这是因为 i 是最后一个不重复元素的索引,而数组的长度应该是最后一个元素的索引加 1

这个方法的时间复杂度是 O(n),因为它只需要遍历数组一次。空间复杂度是 O(1),因为它没有使用额外的空间来存储数据(除了几个变量之外)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值