Arrays 给定一个整数数组,在线性时间和常量空间中查找第一个缺失的正整数

Arrays 给定一个整数数组,在线性时间和常量空间中查找第一个缺失的正整数,arrays,algorithm,sorting,array-algorithms,Arrays,Algorithm,Sorting,Array Algorithms,换句话说,找到数组中不存在的最小正整数。数组也可以包含重复数和负数。 这个问题是Stripe在节目采访中提出的。我设计了一个解决方案,如下所示: #include<bits/stdc++.h> using namespace std; int main(){ int arr[]={1,-1,-5,-3,3,4,2,8}; int size= sizeof(arr)/sizeof(arr[0]); sort(arr, arr+size); int mi

换句话说,找到数组中不存在的最小正整数。数组也可以包含重复数和负数。 这个问题是Stripe在节目采访中提出的。我设计了一个解决方案,如下所示:

#include<bits/stdc++.h>
using namespace std;

int main(){
    int arr[]={1,-1,-5,-3,3,4,2,8};
    int size= sizeof(arr)/sizeof(arr[0]);
    sort(arr, arr+size);
    int min=1;

    for(int i=0; i<size; i++){
        if(arr[i]>min) break;
        if(arr[i]==min) min=min+1;
    }
    cout<<min;
    return 0;
}
#包括
使用名称空间std;
int main(){
int arr[]={1,-1,-5,-3,3,4,2,8};
int size=sizeof(arr)/sizeof(arr[0]);
排序(arr,arr+大小);
int min=1;
对于(int i=0;imin)中断;
如果(arr[i]==min)min=min+1;
}

cout假设数组可以修改

  • 我们将数组分成两部分,第一部分仅由正数组成。假设起始索引为
    0
    ,结束索引为
    end
    (独占)

  • 我们从索引
    0
    end
    遍历数组。我们取该索引处元素的绝对值-假设值为
    x

  • 如果
    x>end
    我们什么也不做
  • 如果不是,我们将索引
    x-1
    处元素的符号设为负值。(澄清:我们不切换符号。如果值为正,它将变为负。如果值为负,它将保持为负。在伪代码中,这类似于
    If(arr[x-1]>0)arr[x-1]=-arr[x-1]
    而不是
    arr[x-1]=-arr[x-1]
  • 最后,我们再次从索引
    0
    end
    遍历数组。如果在某个索引处遇到正元素,我们将输出
    index+1
    。这就是答案。但是,如果我们没有遇到任何正元素,则表示数组中出现整数
    1
    end
    。我们输出
    end+1

  • 也可能是所有数字都是非正数,使得
    end=0
    。输出
    end+1=1
    保持正确

    所有步骤都可以在
    O(n)
    时间和
    O(1)
    空间中完成

    示例:

    Initial Array:            1 -1 -5 -3 3 4 2 8
    Step 1 partition:         1 8 2 4 3 | -3 -5 -1, end = 5
    
    在步骤2中,我们更改正数的符号,以跟踪哪些整数已经出现。例如,这里
    array[2]=-2<0
    ,它表明
    2+1=3
    已经在数组中出现。基本上,如果
    i+1
    在数组中,我们将索引为
    i
    的元素的值更改为负值

    Step 2 Array changes to: -1 -8 -2 -4 3 | -3 -5 -1
    
    在步骤3中,如果某个值
    array[index]
    为正,则表示在步骤2中没有找到任何值
    index+1
    的整数

    Step 3: Traversing from index 0 to end, we find array[4] = 3 > 0
            The answer is 4 + 1 = 5
    

    PMCarpan的算法有效

    我认为您的方法是可行的,但是您应该指定您正在执行的排序类型,以便很清楚它是线性排序,而不一定是整个数组的完整排序。这将导致O(N)时间,而不使用任何空间

    在扫描数组时,如果当前索引中的值小于数组的长度,请扫描数组,然后将其与该索引中当前的值交换。您必须继续交换,直到在每个索引处交换不再有意义为止。然后在最后再进行一次扫描,直到找到不正确的索引

    这里有一些可以工作的python代码,尽管python不是做这类事情的地方,哈哈

    def sortOfSort(arr) :
        for index in range(len(arr)) :
            checkValue = arr[index]
    
            while(checkValue > 0 and checkValue != index and checkValue < len(arr) and arr[checkValue] != checkValue) :
                arr[index] = arr[checkValue]
                arr[checkValue] = checkValue
                checkValue = arr[index]
    
        return arr[1:] + [arr[0]]
    
    def findFirstMissingNumber(arr) :
        for x in range(len(arr)) :
            if (x+1 != arr[x]) :
                return x+1
        return len(arr) + 1
    
    def排序(arr):
    对于范围内的索引(len(arr)):
    checkValue=arr[索引]
    而(checkValue>0和checkValue!=索引和checkValue

    返回arr[1:]部分是因为根据您的描述,我们没有将零作为起点。

    这里是一个C实现
    输入


    /*
    如何工作:
    [if(abs(arr[i])-10)
    arr[abs(arr[i])-1]=-arr[abs(arr[i])-1];]
    before:arr={7,3,4,5,5,3,2}
    i==0:arr[0]=7
    arr[7-1]为2>0~>否定
    arr={7,3,4,5,5,3,-2}
    i==1:arr[1]=3
    arr[3-1]为4>0~>否定
    arr={7,3,-4,5,5,3,-2}
    i==2:arr[2]是用于索引的-4~>abs
    arr[4-1]为5>0~>否定
    arr={7,3,-4,-5,5,3,-2}
    i==3:arr[3]是用于索引的-5~>abs
    arr[5-1]为5>0~>否定
    arr={7,3,-4,-5,-5,3,-2}
    i==4:arr[4]是用于索引的-5~>abs
    arr[5-1]为-5<0~>将abs(-5)打印为副本
    i==5:arr[5]是3
    arr[3-1]为-4<0~>将abs(3)打印为副本
    i==6:arr[6]是用于索引的-2~>abs
    arr[2-1]为3>0~>否定
    arr={7,-3,-4,-5,-5,3,-2}
    正项索引:0、5~>1和6不在原始数组中
    负项索引:原始数组中的1,2,3,4,6~>2,3,4,5,7
    */
    
    #返回包含正数的片段
    def FindPositiveSubar(arr):
    负指数=0
    如果i在范围内(len(arr)):
    如果arr[i]0:
    正耳环[索引]*=-1
    对于范围(l)中的i:
    如果正耳环[i]>0:
    返回i+1
    返回l+1
    如果名称=“\uuuuu main\uuuuuuuu”:
    arr=[input().strip().split()中x的int(x)]
    positiveSubArr=FindPositiveSubArr(arr)
    打印(findmisingpositive(positiveSubArr))
    
    我使用python3中的set解决了这个问题。它非常简单。 时间复杂度:O(n)

    记住:成员签入集为O(1)


    我并没有详细测试它,但对于排序数组,这里是我将如何处理它的,欢迎任何改进。 约束:

    Initial Array:            1 -1 -5 -3 3 4 2 8
    Step 1 partition:         1 8 2 4 3 | -3 -5 -1, end = 5
    
    • 线性时间
    • 恒定空间

      solution:
      start with lowest positive integer (i.e. lpi <- 1)
      while parsing the array, if lpi is already in the array, increment it
      
      如果数组i
       /*
              How work :
              [if(abs(arr[i]) - 1 < size && arr[ abs(arr[i]) - 1] > 0)
              arr[ abs(arr[i]) - 1] = -arr[ abs(arr[i]) - 1];]
              before: arr = { 7, 3, 4, 5, 5, 3, 2}
          i == 0: arr[0] = 7
                  arr[7-1] is 2 > 0 ~> negate
                  arr = { 7, 3, 4, 5, 5, 3, -2}
          i == 1: arr[1] = 3
                  arr[3-1] is 4 > 0 ~> negate
                  arr = { 7, 3, -4, 5, 5, 3, -2}
          i == 2: arr[2] is -4 ~> abs for indexing
                  arr[4-1] is 5 > 0 ~> negate
                  arr = { 7, 3, -4,-5, 5, 3, -2}
          i == 3: arr[3] is -5 ~> abs for indexing
                  arr[5-1] is 5 > 0 ~> negate
                  arr = { 7, 3, -4, -5, -5, 3, -2}
          i == 4: arr[4] is -5 ~> abs for indexing
                  arr[5-1] is -5 < 0 ~> print abs(-5) as duplicate
          i == 5: arr[5] is 3
                  arr[3-1] is -4 < 0 ~> print abs(3) as duplicate
          i == 6: arr[6] is -2 ~> abs for indexing
                  arr[2-1] is 3 > 0 ~> negate
                  arr = { 7, -3, -4, -5, -5, 3, -2}
      
                  indices of positive entries: 0, 5 ~> 1 and 6 not in original array
                  indices of negative entries: 1, 2, 3, 4, 6 ~> 2, 3, 4, 5, 7 in original array
      */
      
      #Returns a slice containing positive numbers
      def findPositiveSubArr(arr):
          negativeIndex = 0
      
          if i in range(len(arr)):
              if arr[i] <=0:
                  arr.insert(negativeIndex, arr.pop(i))
                  negativeIndex += 1
          return arr[negativeIndex:]
      
      #Returns the first missing positive number
      def findMissingPositive(positiveArr):
          l = len(positiveArr)
          for num in positiveArr:
              index = abs(num) - 1
              if index < 1 and positiveArr[index] > 0:
                  positiveArr[index] *= -1
      
          for i in range(l):
              if positiveArr[i] > 0:
                  return i+1
      
          return l+1
      
      if __name__ == "__main__":
          arr = [int(x) for x in input().strip().split()]
          positiveSubArr = findPositveSubArr(arr)
          print(findMissingPositive(positiveSubArr))
      
      def first_missing_positive_integer(arr):
          arr = set(arr)
          for i in range(1, len(arr)+2):
              if i not in arr:
                  return i
      
      solution:
      start with lowest positive integer (i.e. lpi <- 1)
      while parsing the array, if lpi is already in the array, increment it
      
      def find_lpi(arr):
          lpi = 1
          for i in arr:
              if lpi == i:
                  lpi += 1
          return lpi
      
      def find_lpi(arr):
          x = [0 for x in range(max(arr)+1)]
           for i in arr:
               x[i] = 1 
           for i in range(1,len(x)):
               if x[i] ==0:
                   return i
           return len(x)
      
      public static int Missing(int[] a)
      {
          // the idea is to put all values in array on their ordered place if possible
          for (int i = 0; i < a.Length; i++)
          {
              CheckArrayAtPosition(a, i);
          }
      
          for (int i = 0; i < a.Length; i++)
              if (a[i] != i + 1)
                  return i + 1;
          return a.Length + 1;
      }
      
      private static void CheckArrayAtPosition(int[] a, int i)
      {
          var currentValue = a[i];
          if (currentValue < 1) return; // do not touch negative values because array indexes are non-negative
          if (currentValue > a.Length) return; // do not touch values that are bigger than array length because we will not locate them anyway
          if (a[currentValue - 1] == currentValue) return; // do not need to change anything because index contain correct value already
          Swap(a, i, currentValue - 1);
          CheckArrayAtPosition(a, i); // now current position value is updated so we need to check current position again
      }
      
      private static void Swap(int[] a, int i, int j)
      {
          int temp = a[i];
          a[i] = a[j];
          a[j] = temp;
      }
      
      public int FindMissing(){
          var list = new int[] { 6, -6, 4, 5 };
          list = list.OrderBy(x => x).ToArray();
          var maxValue = 0;
          for (int i = 0; i < list.Length; i++)
          {
              if (list[i] <= 0)
              {
                  continue;
              }
              if (i == list.Length - 1 ||
                  list[i] + 1 != list[i + 1])
              {
                  maxValue = list[i] + 1;
                  break;
              }
          }
          return maxValue;
      }
      
      def missing_int(nums: MutableSequence[int]) -> int:
          # If empty array or doesn't have 1, return 1
          if not next((x for x in nums if x == 1), 0):
              return 1
      
          lo: int = 0
          hi: int = len(nums) - 1
          i: int = 0
          pivot: int = 1
      
          while i <= hi:
              if nums[i] < pivot:
                  swap(nums, i, hi)
                  hi -= 1
              elif nums[i] > pivot:
                  swap(nums, i, lo)
                  i += 1
                  lo += 1
              else:
                  i += 1
      
          x = 0
          while x <= hi:  # hi is the index of the last positive number
              y: int = abs(nums[x])
              if 0 < y <= hi + 1 and nums[y - 1] > 0:  # Don't flip sign if already negative
                  nums[y - 1] *= -1
              x += 1
      
          return next((i for i, v in enumerate(nums[:hi + 1]) if v >= 0), x) + 1
      
      def test_missing_int(self):
          assert func.missing_int([1, 2, 1, 0]) == 3
          assert func.missing_int([3, 4, -1, 1]) == 2
          assert func.missing_int([7, 8, 9, 11, 12]) == 1
          assert func.missing_int([1]) == 2
          assert func.missing_int([]) == 1
          assert func.missing_int([0]) == 1
          assert func.missing_int([2, 1]) == 3
          assert func.missing_int([-1, -2, -3]) == 1
          assert func.missing_int([1, 1]) == 2
          assert func.missing_int([1000, -1]) == 1
          assert func.missing_int([-10, -3, -100, -1000, -239, 1]) == 2
          assert func.missing_int([1, 1]) == 2
      
      def segregate(arr):
          length = len(arr)
          neg_index = length
          for i, value in enumerate(arr):
              if(value < 1 and neg_index == length):
                 neg_index = i
              if(neg_index != length and value >= 1):
                 temp = arr[i]
                 arr[i] = arr[neg_index]
                 arr[neg_index] = temp
                 neg_index += 1
          return arr[:neg_index]
      
      def missingPositiveNumber(arr):
          arr = segregate(arr)
          length = len(arr)
          for i, value in enumerate(arr):
              if(value - 1 < l):
                 arr[abs(value) - 1] = -(abs(arr[abs(value) - 1]))
          for i, value in enumerate(arr):
              if(value > 0):
                 return i + 1
          return length + 1
      
      
      print(missingPositiveNumber([1, -1, 2, 3]))
      
      private static int minimum_positive_integer(int[] arr) {
              int i = 0;
              int j = arr.length - 1;
      
              //splitting array
              while (i < j) {
                  if (arr[i] > 0) {
                      i++;
                  }
      
                  if (arr[j] <= 0) {
                      j--;
                  }
      
                  if (arr[i] <= 0 && arr[j] > 0) {
                      int t = arr[i];
                      arr[i] = arr[j];
                      arr[j] = t;
      
                      i++;
                      j--;
                  }
              }
              int len_positive = i;
      
              if (arr[i] > 0) len_positive++;
      
              for (i = 0; i < len_positive; i++) {
                  int abs = Math.abs(arr[i]);
                  if (abs <= len_positive) {
                      int index = abs - 1;
                      arr[index] = -abs;
                  }
              }
      
              for (i = 0; i < len_positive; i++) {
                  if(arr[i] > 0) return  i + 1;
              }
      
              return len_positive + 1;
          }
      
      def lowest_positive(lista):
      
      result = 0
      dict = {}
      
      for i in lista:
      
          if i <= 0:
              continue
      
          if i in dict:
              continue
          else:
              dict[i] = i
      
              if result == 0:
                  result = result +1
      
              if result < i: 
                  continue
      
              result = result +1
      
              while result in dict:
                  result = result +1
      
      return result
      
      lista = [5, 3, 4, -1, 1, 2]
      lista = [1,2,3,4,5]
      lista = [3, 4, -1, 1]
      lista = [2, 3, 4, 1]
      lista = [1,0]
      lowest_positive(lista)
      
      def missing_positive_integer(my_list):
          max_value = max(my_list)
          my_list = [num for num in range(1,max(my_list)) if num not in my_list]
          if len(my_list) == 0:
              my_list.append(max_value+1)
      
          return min(my_list)
      
      my_list = [1,2,3,4,5,8,-1,-12,-3,-4,-8]
      missing_positive_integer(my_list)