算法设计与应用基础-第一周题目

(1) Search InsertPosition

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You may assume no duplicates in the array.

Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0 

在这道题目中,我们需要在一组给定且有序的数组中,查找一个目标键值判断是否存在以及存在的位置。

关于查找,我们有线性查找、二分查找、哈希查找等方式,在这道题目中,我选择了综合二分查找以及lower_bound的用法。

代码中,当nums[middle] < target时,first 指向middle的下一个位置,而下一个位置可能等于或者大于target;因此该函数是返回一个非递减序列[first, last)中的第一个大于等于值target的位置。即可以查找是否存在目标键值也可以给出目标位置。

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

(2)Merge Sorted Array

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:
You may assume that nums1 has enough space (size that is greater or equal tom +n) to hold additional elements from nums2. The number of elements initialized innums1 andnums2 are m and n respectively.

在这道题目中,合并两个有序数组可以考虑使用归并排序来实现。我们从后往前来归并两个固定长度的vector,只需通过每次见到max_index即可,若是从头往后则还需不断把nums1原来的数据往后挪。

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) 
    {
        int all=m+n-2;
        m--;
        n--;
        while(m>=0&n>=0)
        {
            if(nums1[m]>nums2[n])
            {
                nums1[all]=nums1[m];
                m--;
                all--;
            }
            else if(nums1[m]<=nums2[n])
            {
                nums1[all]=nums2[n];
                n--;
                all--;
            }
        }
    }
};

(3)Remove Duplicates from Sorted List

Given a sorted linked list, delete all duplicates such that each element appear only once.

For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3

在这道题目中,我们可以通过改变该有序链表的链接来实现删除重复元素。

pre指针和nex指针用于实现重链链表,pre指针决定curr指针位置,nex指针决定curr指针后继元素。

当pre和nex指向的元素相同时,nex后移再次比较,若相同则nex继续后移,若不同则pre和nex同时后移,curr更新到pre的位置。

/**
 * 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==NULL)
            return head;
        else if(head!=NULL)
        {
            ListNode* curr=head;
            ListNode* pre=curr;
            ListNode* nex=pre->next;
            while(curr!=NULL)
            {
                while(nex!=NULL)
                {
                    if(pre->val==nex->val)
                    {
                        nex=nex->next;
                        free(nex);
                        nex=NULL;
                        pre->next=nex;
                    }
                    if(pre->val!=pre->val)
                    {
                        pre=nex;
                        nex=nex->next;
                    }
                }
                curr=pre;
            }
            return head;
        }
    }
};


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值