初识Leetcode----学习(九)【删除排序链表中的重复元素、合并两个有序数组】

删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例 1:

输入: 1->1->2
输出: 1->2

示例 2:

输入: 1->1->2->3->3
输出: 1->2->3

1.基本思路就是定义一个指针指向链表的第一个元素,将该元素与下一个元素比较,如果相等,则删除下一元素,否则将指针指向下一元素,遍历完整个链表,则整个链表九不存在重复项:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if (!head || !(head->next))
            return head;
        ListNode* p = head;   //令一指针指向链表
        while (p && p->next)  //当未达到链表末尾时继续遍历
        {
            if (p->val == p->next->val)    //如果当前元素与下一元素相等,则删除下一元素
            {
                ListNode* q = p->next;
                p->next = q->next;
                free(q);
            }
            else                        //否则将该指针指向下一元素
            {
                p = p->next;
            }
        }
        return head;
    }
};

合并两个有序数组

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 使得 num1 成为一个有序数组。

说明:

  • 初始化 nums1 和 nums2 的元素数量分别为 m 和 n
  • 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。

示例:

输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3

输出: [1,2,2,3,5,6]

1.先创建一个大小为m+n的数组,然后从头比较两个数组,将两者中的较小值存入新数组中,然后再处理nums1数组有剩余和nums2数组有剩余的情况,最后将新数组的值赋給nums1数组:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        if (m <= 0 && n <= 0) return;
        int a = 0, b = 0;
        int C[m + n];                 //创建新数组存储排序的元素
        for (int i = 0; i < m + n; ++i) {
            if (a < m && b < n) {     //处理两个数组都有元素的情况
                if (nums1[a] < nums2[b]) {   //将两个数组中较小元素存入新数组中
                    C[i] = nums1[a];
                    ++a;
                }
                else {
                    C[i] = nums2[b];
                    ++b;
                }
            }
            else if (a < m && b >= n) {   //处理nums1数组有剩余的情况,将nums1数组剩余元素存入新数组
                C[i] = nums1[a];
                ++a;
            }
            else if (a >= m && b < n) {  //处理nums2数组有剩余的情况,将nums2数组剩余元素存入新数组
                C[i] = nums2[b];
                ++b;
            }
            else return;
        }
        for (int i = 0; i < m + n; ++i) nums1[i] = C[i];  //将新数组的值赋給目标数组nums1
    }
};

2.从数组尾元素往前判断,将两个数组中较大值放入目标数组nums1中,再依次往前推。如果如果A中所有的元素都比B小,那么前m个还是A原来的内容,没有改变。如果A中的数组比B大的,当A循环完了,B中还有元素没加入A,直接用个循环把B中所有的元素覆盖到A剩下的位置:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        if (!nums2.empty())
        {
             int i = m + n -1;
             --m,--n;
             while (m >= 0 && n >= 0)
              {
                   nums1[i--] = nums1[m] > nums2[n] ? nums1[m--] : nums2[n--];   //比较两个数组的尾元素,将较大的元素插入到目标数组nums1中    
              }
              while (n >= 0)   //如果数组nums2中还存有元素,则将这些元素依次插入到nums1中的剩余位置中
              {
                   nums1[i--] = nums2[n--];
              }
         }
    }
};

猜你喜欢

转载自blog.csdn.net/qq_38790716/article/details/83046267