算法训练营Day01-数组Part01

DAY01

题目:

704. 二分查找 - 力扣(LeetCode)
27. 移除元素 - 力扣(LeetCode)
977. 有序数组的平方 - 力扣(LeetCode)

704、二分查找

704. 二分查找 - 力扣(LeetCode)

秒了,真秒了。问:为什么这么快?答:做过了。熟稔于心,无需多言。

康复训练第一题,熟练一些vector的用法。

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int low = 0;
        int high = nums.size() - 1;
        int mid;
        while (low <= high) {
            mid = (low + high) / 2;        
            if (target < nums[mid]) {
                high = mid - 1;
            } else if (target > nums[mid]) {
                low = mid + 1;
            } else if (target == nums[mid]) {
                return mid;
            }
        }
        return -1;
    
    }
};

27、移除元素

27. 移除元素 - 力扣(LeetCode)

暴力解法一

自己的暴力解法:最暴力的一集,未看答案使用暴力解法:直接开辟一个新vector,遍历nums一个一个加进去。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        vector<int> temp;
        int i = 0;
        int count = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] != val) {
                temp.push_back(nums[i]); //注意这里本来打算写temp[count++] = nums[i],但是未定义长度的vector这里会编译报错。对于vector还是使用push_back()方法,而不上像数组那样访问。
                count ++;
            }else if (nums[i] == val) {
                continue;
            }
        }
		// 旧版像赋值,但是没
        // memset(nums, 0, nums.size()); //将nums清空
        // 将temp复制给nums
        // for (int i = 0; i < count; i++) {
        //     nums[i] = temp[i];
        // }
        nums = temp; // 将vector赋值可以如此简单
        return count;
    }
};

//时间O(n)
//空间O(n)

暴力解法二

随想录的暴力解法:没次找到符合条件的元素后,对后面的元素进行遍历前移

// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int size = nums.size();
        for (int i = 0; i < size; i++) {
            if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位
                for (int j = i + 1; j < size; j++) {
                    nums[j - 1] = nums[j];
                }
                i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
                size--; // 此时数组的大小-1
            }
        }
        return size;

    }
};

优化解法

双指针解法:快慢指针。个人觉得对暴力解法一的一种优化。

两个指针明面上都是直接对nums数组进行访问,但是由于不开辟新数组,因此都有各自的新含义。

  • 快指针fast:单纯的遍历nums,用于筛选过滤。
  • 慢指针slow:指向nums中属于过滤后的新数组的元素
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        //快慢指针
        int fast = 0; //遍历nums过滤
        int slow = 0; //指向新数组的元素
        for (; fast < nums.size(); fast++) {
            if (nums[fast] != val) { //只有符合条件的元素才能使得slow++
                nums[slow++] = nums[fast];
            } else if (nums[fast] == val) {
                continue;
            }
        }
        return slow;
    }
};

977、有序数组的平方

977. 有序数组的平方 - 力扣(LeetCode)

暴力解法:

本人自己写虽然用了双指针,但感觉也仅仅只是减少了开辟数组的开销。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int fast = 0; 
        int slow = 0;
        for (; fast < nums.size(); fast++) {
            nums[slow++] = nums[fast] * nums[fast]; //将nums所有元素求平方
        }
        //排序
        sort(nums.begin(), nums.end());
        return nums;

    }
};

优化解法:

​ 对于一个”有正负递增“的数组,元素取平方后都为正。且以0值为基准,正值元素和负值元素之间没有什么很好的规律性。但是单就所有正值元素或者负值元素本身内部之间有递增规律性。

​ 因此设置 头指针和尾指针,两个各自代表正值阵营和负值阵营相互比较。

​ 开辟新数组,用k指向末尾元素,从最大开始比较。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int low = 0;
        int high = nums.size() - 1;
        int k = nums.size() - 1; //指向新数组的元素
        vector<int> res(nums.size(), 0); // 定义新数组
        while (low <= high) { //
            int low2 = nums[low] * nums[low];
            int high2 = nums[high] * nums[high];
            if (low2 <= high2) {
                res[k--] = high2;
                high--;
            } else {
                res[k--] = low2;
                low++;
            }
        }
        return res;
    }
};

你可能感兴趣的:(算法,leetcode,职场和发展)