算法初学————数组篇

删除排序数组中的重复项

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

双指针法

使用两个指针,右指针始终往右移动,如果右指针指向的值等于左指针指向的值,左指针不动。
如果右指针指向的值不等于左指针指向的值,那么左指针往右移一步,然后再把右指针指向的值赋给左指针。

class Solution {
    public int removeDuplicates(int[] nums) {
    int m = 0;
    for(int n = m +1; n < nums.length;n++){
            if(nums[m] != nums[n]){
                nums[++m] = nums[n];
        }
    }
        return ++m;
    }
}

旋转数组

给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]

如果您是初学者,一般会想到这个方法:

public void rotate(int[] nums, int k) {
        int temp = 0;
        int s = nums.length -1;
        for(int j = 0 ; j < k; j++){
            temp = nums[s];
            for(int i = s; i >0; i--){
                nums[i] = nums[i-1];
            }
            nums[0] = temp;
        }}

这个方法一旦数据量大时候,就会超时,效率比较低,随着学习的深入可以直接PASS

使用临时数组

public void rotate(int nums[], int k) {
        int length = nums.length;
        int temp[] = new int[length];
        //把原数组值放到一个临时数组中,
        for (int i = 0; i < length; i++) {
            temp[i] = nums[i];
        }
        //然后在把临时数组的值重新放到原数组,并且往右移动k位
        for (int i = 0; i < length; i++) {
            nums[(i + k) % length] = temp[i];
        }
    }

存在重复元素

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false

输入:nums = [1,1,1,3,3,4,3,2,4,2]                         输出:true

输入:nums = [1,2,3,4]                                        ​​​​​​​    输出:false

1.先排序在查找是否有重复的数据

 public boolean containsDuplicate(int[] nums) {
        
        Arrays.sort(nums);
        for (int ind = 1; ind < nums.length; ind++) {
            if (nums[ind] == nums[ind - 1]) {
                return true;
            } }
        return false;}

2.使用hashset不会插入重复数据来进行操作

 public boolean containsDuplicate(int[] nums) {

Boolean flag = false;
        HashSet<Integer> set = new HashSet<Integer>();
        for(int i = 0; i <nums.length;i++){
            if(set.add(nums[i]) == false){
                flag = true;
            }
        }
        return flag; }

只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素

输入: [4,1,2,1,2]        ​​​​​​​        ​​​​​​​        输出: 4

1.使用异或运算,将所有值进行异或
异或运算,相异为真,相同为假,所以 a^a = 0 ;0^a = a
因为异或运算 满足交换律 a^b^a = a^a^b = b 所以数组经过异或运算,单独的值就剩下了

public int singleNumber(int[] nums) {

int temp = 0;
        for(int num : nums){
            temp = temp ^ num;
        }
        return temp;}

2.使用集合Set解决

我们遍历数组中的元素,然后在一个个添加到集合Set中,如果添加失败,说明以前添加过,就把他给移除掉。当我们把数组中的所有元素都遍历完的时候,集合Set中只会有一个元素,这个就是我们要求的值。

public int singleNumber(int[] nums) {

HashSet<Integer> hashset = new HashSet<>();
        for(int i = 0; i < nums.length; i++){
            if(hashset.add(nums[i]) == false){
                hashset.remove(nums[i]);
            }else{
                hashset.add(nums[i]);
            } 
        }
        return (int) hashset.toArray()[0];

    }

两个数组的交集 II

给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

输入:nums1 = [1,2,2,1], nums2 = [2,2]        ​​​​​​​        ​​​​​​​    输出:[2,2]
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]        ​​​​​​​        输出:[4,9]

双指针法

先将两个数组排序,每个数组设置一个指针,指针指向数组开始位置

如果两个指针指向的值相同,说明这个值是他们的交集,就把这个值加入到集合list中,然后两个指针在分别往后移一步。
如果两个指针指向的值不同,那么指向的值相对小的往后移一步,相对大的先不动,然后再比较
一直重复上面的操作,直到其中一个指针不能再移动为止,最后再把集合list转化为数组即可      

 public int[] intersect(int[] nums1, int[] nums2) {                 //双指针解法
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        ArrayList<Integer> arraylist = new ArrayList<>();
        int i=0  , j =0;
        while(i<nums1.length && j<nums2.length){
            if(nums1[i] < nums2[j]){ i++;
            }else if(nums1[i] > nums2[j]){ j++;
            }else{
                arraylist.add(nums1[i]);
                i++;
                j++; }   }
       int  index = 0;
        int[] arr = new int[arraylist.size()];
        for(int k = 0; k < arraylist.size(); k++){
            arr[index++] = arraylist.get(k); }
        return arr;}}

学习来源:

链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2y0c2/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值