2017-03-06 33 views
4

我尝试解决CodeFights上的这个挑战,但它不起作用。我最好的解决方案得到了25/26(最后一次测试超出了时间限制),但我删除了,因为我昨天试过了(这是O(n^2))。现在我尝试了一个新的O(n)。我非常疲倦,我很想今天完成这个任务,所以请帮助我。增加序列C++

下面是语句: 给定一个整数序列作为数组,确定是否可以通过从数组中删除不多于一个元素来获得严格增加的序列。

For sequence = [1, 3, 2, 1], the output should be 
almostIncreasingSequence(sequence) = false; 

There is no one element in this array that can be removed in order to get a strictly increasing sequence. 

For sequence = [1, 3, 2], the output should be 
almostIncreasingSequence(sequence) = true. 

You can remove 3 from the array to get the strictly increasing sequence [1, 2]. Alternately, you can remove 2 to get the strictly increasing sequence [1, 3]. 

这里是我的代码,到现在为止......(可怜的代码):

#include <iostream> 
#include <vector> 

#include <algorithm> 

bool almostIncreasingSequence(std::vector<int> sequence) 
{ 
    int count = 0; 


    for(int i = 0; i < sequence.size()-1; i++) 
    { 
     if(sequence[i] > sequence[i+1]) 
     { 
      count++; 
      sequence.erase(sequence.begin(), sequence.begin() + i); 
      i--; 
     } 
     if(count == 2) 
      return false; 
    } 
    return true; 
} 

int main() 
{ 
    std::cout << std::endl; 
    return 0; 
} 
+0

此代码现在没有(几乎)没有调用'almostIncreasingSequence'函数。 – ForceBru

+0

这在挑战中并不重要,我必须只写功能,main和header会自动添加:)我写主+标题是因为我想将这些文件保存在我的电脑中 – Vader

+0

请不要链接到需要登录或导航的网站你的代码。这个问题陈述是什么意思? – ThomasMcLeod

回答

2

这里是一个C++ 11溶液O(N)运行时:

constexpr auto Max = std::numeric_limits<std::size_t>::max(); 
bool is_sorted_but_skip(const std::vector<int>& vec, std::size_t index = Max){ 
    auto Start = index == 0 ? 1 : 0; 
    auto prev = vec[Start]; 
    for(std::size_t i = Start + 1; i < vec.size(); i++){ 
     if(i == index) continue; 
     if(prev >= vec[i]) return false; 
     prev = vec[i]; 
    } 
    return true; 
} 

bool almostIncreasingSequence(std::vector<int> v) 
{ 
    auto iter = std::adjacent_find(v.begin(), v.end(), [](int L, int R){ return L >= R; }); 
    if(is_sorted_but_skip(v, std::distance(v.begin(), iter))) 
     return true; 
    return is_sorted_but_skip(v, std::distance(v.begin(), std::next(iter))); 
} 

我们使用std::adjacent_find找到的第一个元素,比iter大于或等于它的下一个元素。然后我们检查序列是否严格排序,同时跳过iter的位置。

否则,我们检查,虽然我们跳过iter+1的位置

更糟糕的情况下,复杂的顺序是严格分类:3的线性扫描

Demo

+0

只需要一个步骤:你说“找到更大的第一个元素”,但我们需要“找到第一个元素大于或等于” – Vader

+0

如何在此代码上添加相同的值? – Vader

+0

@Vader,我没有读到你的问题中“严格增加”的部分。这将需要对此代码进行重大更改。给我几分钟 – WhiZTiM

0

这仍然是O(N^2),因为你删除的第一要素在每次迭代中的向量。不要删除循环中的第一个元素,也不要删除i--

如果你必须删除数字(你不,但仍然),至少从列表的末尾做它。这种方式擦除一个数字是可能 O(1)操作(我不是100%确定这是如何执行std :: vector)。

你真的不需要擦除数字。

+0

但是如果我不擦除,那么我该如何检查序列是否良好? – Vader

+2

你会擦除列表如果你用铅笔和纸做了这个?或者你是否会记录遇到了“坏数字”,跳过它,并继续前进,直到你再次遇到另一个“坏数字”? – PaulMcKenzie

0

这里有一个提示(当然,几乎解决方案真的):

如果您看到一个元素与下一个元素之间的减少,那么您必须删除其中的一个元素(*)。

现在,如果在两个不相交的元素对之间找到两个减少值?这是正确的:-)

记住这一点,你应该能够解决你的问题,使用线性扫描和一些恒定时间的工作。

(*)不包括第一对和最后一对元素。

+0

For 2 decrease =>返回false,因为我们只能删除一个元素 – Vader

+0

@Vader:是的 - 重点是通过线性扫描可以限制您的可以排除这一点,并且同时标记很少的地方潜在的清除。然后你检查出来。 – einpoklum