算法总结(6)--Duplicate系列查找,删除等

关于重复数字的算法题,主要是判断,查找,删除重复数字,也需要思考数组,链表求解的异同。
有用到hash,二分法, 两点法的,更多的则是一种模拟,需要思路清晰,后面可以考虑代码时空的优化

217. Contains Duplicate

题目地址

https://leetcode.com/problems/contains-duplicate/

求解

采用hash,直接遍历

219. Contains Duplicate II

题目地址

https://leetcode.com/problems/contains-duplicate-ii/

题目描述

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the difference between i and j is at most k.

求解思路

同上,仍然采用hash ,遍历一次,需要判断和修改hash值

220. Contains Duplicate III

题目描述

Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.

求解思路

在上一题的要求上,有加上了条件

ac代码如下, 时间复杂度较高,主要采用结构体,排序,然后按要求判断

typedef struct mdata{
    int pos;
    int val;
    mdata(int m_pos = -1, int m_val = -1){
        pos = m_pos;
        val = m_val;
    }
}mdata;

bool cmp(mdata d1, mdata d2)
{
    if (d1.val < d2.val)
        return true;
    if (d1.val == d2.val)
    {
        if (d1.pos < d2.pos)
            return true;
    }
    return false;
}


class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        int len = nums.size();

        int INF = 0x7fffffff;
        int MIN = -INF - 1;

        vector<mdata> v;

        for (int i = 0; i < len; i++){
            mdata dtmp(i, nums[i]);
            v.push_back(dtmp);
        }

        sort(v.begin(), v.end(),cmp);

        for (int i = 0; i < len-1; i++)
        {
            mdata d1 = v[i];

            for (int j = i + 1; j < len; j++){
                mdata d2 = v[j];

                bool flag = false;

                int m = d2.val;
                int n = d1.val;
                if (m > 0 && n < 0)
                {
                    int tmp = m - n;
                    if (!(tmp == MIN || tmp < 0)){
                        if (tmp <= t)
                            flag = true;
                    }
                }
                else{
                    int tmp = m - n;
                    if (tmp <= t)
                        flag = true;
                }

                if (flag == false)
                    break;

                if (abs(d1.pos - d2.pos) > k)
                    continue;
                else
                    return true;
            }
        }
        return false;
    }
};

287. Find the Duplicate Number

题目地址

https://leetcode.com/problems/find-the-duplicate-number/

题目描述

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Note:

  • You must not modify the array (assume the array is read only).
  • You must use only constant, O(1) extra space.
  • Your runtime complexity should be less than O(n2).
  • There is only one duplicate number in the array, but it could be repeated more than once.

求解思路

根据题目意思,采用了二分法,慢慢逼近重复数字
ac代码

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int len = nums.size();
        int n = len - 1;

        int lVal = 1;
        int rVal = n;
        while (lVal < rVal)
        {
            int midVal = (rVal - lVal) / 2 + lVal;

            int leftCnt = 0;
            int rightCnt = 0;
            for (int i = 0; i < len; i++)
            {
                if (nums[i] < midVal && nums[i] >= lVal)
                {
                    leftCnt++;
                }
                if (nums[i] > midVal && nums[i] <= rVal){
                    rightCnt++;
                }
            }

            if (leftCnt == midVal - lVal && rightCnt == rVal - midVal){
                return midVal;
            }
            else if (leftCnt > midVal - lVal){
                rVal = midVal - 1;
            }
            else if (rightCnt > rVal - midVal){
                lVal = midVal + 1;
            }
            else{
                return midVal;
            }
        }// end while

        return lVal;
    }
};

83. Remove Duplicates from Sorted List

题目地址

https://leetcode.com/problems/remove-duplicates-from-sorted-list/

82. Remove Duplicates from Sorted List II

题目地址

https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/

链表中删除重复数字,都不是很难,直接模拟,需要注意指针的使用(需要判断指针是否是NULL)

27. Remove Element

题目地址

https://leetcode.com/problems/remove-element/

题目描述

Given an array and a value, remove all instances of that value in place and return the new length.

Do not allocate extra space for another array, you must do this in place with constant memory.

The order of elements can be changed. It doesn’t matter what you leave beyond the new length.

Example:
Given input array nums = [3,2,2,3], val = 3

Your function should return length = 2, with the first two elements of nums being 2.

两点法求解

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int len = nums.size();

        int left = 0;
        int right = len - 1;

        while (left <= right){
            while (left < len && nums[left] != val) //找到遇到的第一个val
            {
                left++;
            }

            while (right >= 0 && nums[right] == val) // 从后往前 找到第一个不是val的
            {
                right--;
            }
            if (left > right)
            {
                break;
            }
            // swap 上面的两个位置
            nums[left] = nums[right];
            nums[right] = val;
        }

        return left;
    }
};

316. Remove Duplicate Letters

题目地址

https://leetcode.com/problems/remove-duplicate-letters/

题目描述

Given a string which contains only lowercase letters, remove duplicate letters so that every letter appear once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.

Example:
Given “bcabc”
Return “abc”

Given “cbacdcbc”
Return “acdb”

求解思路

思路一

采用hash,栈结构
参考 http://blog.csdn.net/mawu_1014/article/details/51457293
ac代码

class Solution {
public:
    string removeDuplicateLetters(string s) {

        string res = ""; // 维持一个字符串栈

        int len = s.size();
        int mp_cnt[256] = { 0 };
        bool mp_vis[256] = { false };
        int i;
        for (i = 0; i < len; i++){
            mp_cnt[s[i]] ++;
        }

        for (i = 0; i < len; i++)
        {
            mp_cnt[s[i]]--;
            if (mp_vis[s[i]])
                continue;
            // 当前字符 与先前入栈了的字符比较 ,是否栈中的元素可以出栈
            while (res != "" && mp_cnt[res.back()] != 0 && s[i] < res.back()){
                mp_vis[res.back()] = 0;
                res.pop_back(); // 字符出栈
            }
            mp_vis[s[i]] = true;
            res += s[i];
        }

        return res;
    }
};

#

    原文作者:查找算法
    原文地址: https://blog.csdn.net/qq_26437925/article/details/52851934
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞