随想录一刷·数组part2
  u2Z9rysK9yXu 2023年11月19日 29 0


随想录一刷·数组part2_面试

你好,我是安然无虞。


文章目录

  • 1. 有序数组的平方
  • 2. 长度最小的最数组
  • 3. 螺旋数组II


1. 有序数组的平方

有序数组的平方

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) 
    {
        int n = nums.size();

        // 以0为分割线的话,可以将该数组分成两个子数组,并且都是有序的
        // 直接将双指针分别初始化在 nums 的开头和结尾,相当于合并两个从大到小排序的数组
        // 这时我们就可以利用合并两个有序数组的方法解决本题了
        int i = 0, j = n - 1; // 头和尾
        int p = n - 1;
        vector<int> res(n);
        
        while(i <= j)
        {
            // 比较绝对值大小
            if(abs(nums[i]) < abs(nums[j]))
            {
                res[p] = nums[j] * nums[j];
                j--;
            }
            else
            {
                res[p] = nums[i] * nums[i];
                i++;
            }
            p--;
        }

        return res;
    }
};

类似题目:

  1. 合并两个有序数组
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) 
    {
        // 从后向前遍历,因为需要将结果存放到nums1中,从前向后会覆盖原始数据
        int i = m - 1, j = n - 1; 
        int p = nums1.size() - 1;

        while(i >= 0 && j >= 0)
        {
            // 此时有点类似合并两个有序链表的思路
            if(nums1[i] > nums2[j])
            {
                nums1[p] = nums1[i];
                i--;
            }
            else
            {
                nums1[p] = nums2[j];
                j--;
            }
            p--;
        }

        // 因为本身就是将结果存放到nums1中的,所以只需要考虑nums2中剩余的元素
        while(j >= 0)
        {
            nums1[p] = nums2[j];
            j--;
            p--;
        }
    }
};
  1. 合并两个有序链表
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) 
    {
        // 因为合并两个有序链表会生成一条新链表,所以定义虚拟头节点会更简单
        ListNode* newnode = new ListNode(-1), *p = newnode;
        ListNode* p1 = list1, *p2 = list2;

        while(p1 != nullptr && p2 != nullptr)
        {
            if(p1->val < p2->val)
            {
                p->next = p1;
                p1 = p1->next;
            }
            else
            {
                p->next = p2;
                p2 = p2->next;
            }

            p = p->next;
        }    

        if(p1 != nullptr)
            p->next = p1;

        if(p2 != nullptr)
            p->next = p2;

        return newnode->next;
    }
};
  1. 分隔链表
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* partition(ListNode* head, int x) 
    {
        // 相当于生成了两条链表,一条中元素都小于x,另一条元素都不小于x
        ListNode* newnode1 = new ListNode(-1), *p1 = newnode1;
        ListNode* newnode2 = new ListNode(-1), *p2 = newnode2;
        ListNode* p = head;

        while(p != nullptr)
        {
            if(p->val < x)
            {
                p1->next = p;
                p1 = p1->next;
            }
            else
            {
                p2->next = p;
                p2 = p2->next;
            }
            
            p = p->next;
        }

        // 将链表2链接到链表1的末尾,记住别忘了将链表2的尾指向空
        p1->next = newnode2->next;
        p2->next = nullptr;

        return newnode1->next;
    }
};

2. 长度最小的最数组

长度最小的子数组

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) 
    {
        // 因为是正整数数组,没有负数,所以本题可以采用滑动窗口解题
        int left = 0, right = 0;
        int windowSum = 0; // 滑动窗口内的子数组和
        int res = INT_MAX;

        while(right < nums.size())
        {
            windowSum += nums[right];

            right++;

            // 判断左侧窗口什么时候收缩
            while(windowSum >= target && left < right)
            {
                // 更新结果
                res = min(res, right - left);

                windowSum -= nums[left];

                left++;
            }
        }

        return res == INT_MAX ? 0 : res;
    }
};

3. 螺旋数组II

螺旋数组II

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) 
    {
        vector<vector<int>> res(n, vector<int>(n));
        int num = 1;
        int upper_bound = 0, lower_bound = n - 1; // 上下边界
        int left_bound = 0, right_bound = n - 1;  // 左右边界

        while(num <= n * n) // num
        {
            // 上边界,从左往右遍历比较
            if(upper_bound <= lower_bound)
            {
                for(int i = left_bound; i <= right_bound; i++)
                {
                    res[upper_bound][i] = num++; // 后置++
                }
                // 上边界下移
                upper_bound++;
            }

            // 右边界,从上向下遍历比较
            if(left_bound <= right_bound)
            {
                for(int i = upper_bound; i <= lower_bound; i++)
                {
                    res[i][right_bound] = num++;
                }
                // 右边界左移
                right_bound--;
            }

            // 下边界,从右往左遍历比较
            if(upper_bound <= lower_bound)
            {
                for(int i = right_bound; i >= left_bound; i--)
                {
                    res[lower_bound][i] = num++;
                }
                // 下边界上移
                lower_bound--;
            }

            // 左边界,从下向上遍历比较
            if(left_bound <= right_bound)
            {
                for(int i = lower_bound; i >= upper_bound; i--)
                {
                    res[i][left_bound] = num++;
                }
                // 左边界右移
                left_bound++;
            }
        }

        return res;
    }
};


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月19日 0

暂无评论

推荐阅读
u2Z9rysK9yXu