代码随想录二刷总结复盘 day02

69.x的平方根

. - 力扣(LeetCode)

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

本题的核心在于找到第一个平方数大于x的数

1. 二分法:找到第一个平方数大于x的数

注意点是:mid*mid需要转成(long long)

class Solution {
public:
    int mySqrt(int x) {
        int left = 0;
        int right = x;
        int ans;
        while(left <= right) {
            int mid = left + (right - left) / 2;
            if((long long)mid * mid <= x) {
                ans = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return ans;

    }
};

367.有效的完全平方数

. - 力扣(LeetCode)

给你一个正整数 num 。如果 num 是一个完全平方数,则返回 true ,否则返回 false 。

完全平方数 是一个可以写成某个整数的平方的整数。换句话说,它可以写成某个整数和自身的乘积。

注意点:mid*mid需要转成(long long)

1. 双指针:类似于     704.二分查找

class Solution {
public:
    bool isPerfectSquare(int num) {
        int left = 0;
        int right = num;
        while(left <= right) {
            int mid = left + (right - left) / 2;
            if((long long)mid * mid > num) {
                right = mid - 1;
            } else if((long long)mid * mid < num) {
                left = mid + 1;
            } else {
                return true;
            }
        }
        return false;

    }
};

27.移除元素

. - 力扣(LeetCode)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

1. 暴力解法:暴力解法首先一层for循环遍历数组,找到与val相等的数,然后用该数的下一个数把这个数覆盖掉。关键点在于:覆盖不能只覆盖一个数,必须把后面完整的所有的剩余数组全部左移

class Solution {
public:
    int removeElement(vector& nums, int val) {
        int size = nums.size();
        for(int i = 0; i < size; i++) {
            if(val == nums[i]) {
                for(int j = i + 1; j < size; j++) {
                    nums[j - 1] = nums[j];
                }
                i--;
                size--;
            }
        }
        return size;
    }
};

2. 双指针:快慢指针,快指针遍历整个数组,找到与val值不相等的数,将其存入慢指针指向的数组

class Solution {
public:
    int removeElement(vector& nums, int val) {
        int slowIndex = 0;
        for(int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
            if(val != nums[fastIndex]) {
                nums[slowIndex++] = nums[fastIndex];
            }
        }
        return slowIndex;

    }
};

26. 删除数组中的重复项

. - 力扣(LeetCode)

给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

  • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
  • 返回 k 。

1. 暴力解法:首先一层for循环遍历数组,找到前后相等的两个数,然后用相等数后一个的下一个数把该数覆盖掉,要用后面整个完整数组覆盖该点的数组

class Solution {
public:
    int removeDuplicates(vector& nums) {
        int size = nums.size();
        for(int i = 0; i < size - 1; i++) {
            if(nums[i] == nums[i + 1]) {
                for(int j = i + 2; j < size; j++) {
                    nums[j - 1] = nums[j];
                }
                i--;
                size--;
            }
        }
        return size;

    }
};

2. 双指针:细节点在于不需要完整遍历整个数组,因为最后一个数,在比较前后项的时候已经比较过了,而且赋值的时候也是赋值相等项的后一个

class Solution {
public:
    int removeDuplicates(vector& nums) {
        if (nums.empty()) return 0; // 别忘记空数组的判断
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < (nums.size() - 1); fastIndex++){
            if(nums[fastIndex] != nums[fastIndex + 1]) { // 发现和后一个不相同
                nums[++slowIndex] = nums[fastIndex + 1]; //slowIndex = 0 的数据一定是不重复的,所以直接 ++slowIndex
            }
        }
        return slowIndex + 1; //别忘了slowIndex是从0开始的,所以返回slowIndex + 1
    }
};

3. 将vector转化为set  哈希表可以进行去重操作,再从set转到vector(我只能说,看了题解这个老哥,确实牛逼,真有想法吧)

class Solution {
public:
    int removeDuplicates(vector& nums) {
        set s;
        int len = nums.size();
        for(int i = 0; i < len; i++) {
            s.insert(nums[i]);
        }
        len = s.size();
        nums.clear();
        for(const int & element : s) {
            nums.push_back(element);
        }
        return len;

    }
};

283.移动零

. - 力扣(LeetCode)

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

1.暴力解法:遇到0就交换0和不为0的数

class Solution {
public:
    void moveZeroes(vector& nums) {
        int j = 0;
        for(int i = 0; i < nums.size(); i++) {
            if(nums[i]) swap(nums[i], nums[j++]);
        }

    }
};

2. 双指针:将不为0的数存入慢指针数组,传入完毕后,将数组最后补0

class Solution {
public:
    void moveZeroes(vector& nums) {
        int slow = 0;
        for(int fast = 0; fast < nums.size(); fast++) {
            if(0 != nums[fast]) {
                nums[slow++] = nums[fast];
            }
        }
        for(int i = slow; i < nums.size(); i++) {
            nums[i] = 0;
        }

    }
};

977.有序数组的平方

. - 力扣(LeetCode)

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

1. 暴力+排序:先将所有元素的平方存入新数组,在进行sort快排

class Solution {
public:
    vector sortedSquares(vector& nums) {
        vector vec(nums.size());
        for(int i = 0; i < nums.size(); i++) {
            vec[i] = nums[i] * nums[i];
        }
        sort(vec.begin(), vec.end());
        return vec;

    }
};

2. 双指针:比较头指针的平方和尾指针的平方,将大的那一个存入新数组的尾部,从新数组的尾部一直慢慢添加到新数组的头部

class Solution {
public:
    vector sortedSquares(vector& nums) {
        int left = 0;
        int right = nums.size() - 1; 
        vector vec(nums.size());
        int i = nums.size() - 1;
        while(left <= right) {
            if(nums[left] * nums[left] > nums[right] * nums[right]) {
                vec[i--] = nums[left] * nums[left];
                left++;
            } else {
                vec[i--] = nums[right] * nums[right];
                right--;
            }
        }
        return vec;

    }
};

感谢代码随想录,感谢Carl神

你可能感兴趣的:(算法,leetcode)