C语言 有效山形阵

4nkexdtk  于 2023-03-01  发布在  其他
关注(0)|答案(8)|浏览(125)

我想知道是否有一种编程的方法来确定一个数组是否具有完美的山的模式,而没有山谷。(图中的示例)
来源:https://leetcode.com/problems/valid-mountain-array/

编辑:
我在C中的尝试:

#include<stdio.h>

int AscOrDes(int a[], int first, int last)
{
    int i;
    for(i=first; i<last; i++)
    {
        if(a[i]>a[i+1])
            return(1);
        else if(a[i]<a[i+1])
            return(2);
    }
    return 0;
}

int main() {
    int a[1000],n,i,big=0,r1,r2;
    scanf("%d",&n);
    for(i=0; i<n; i++)
    {
        scanf("%d",&a[i]);
    }
    for(i=0; i<n; i++)
    {
        if(a[i]>=a[big])
            big=i;
    }
    r1=AscOrDes(a, 0, big);
    r2=AscOrDes(a, big, n);
    if(r1==2 && r2==1 && big!=0 && big!=n-1)
        printf("True");
    else
        printf("False");
    return 0;
}

以上代码不适用于以下输入:

8
1 3 2 5 4 3 2 0

它给出输出:

True

尽管它不是一个完美的山阵。
我在我的程序中所做的是检查哪个元素是最大的(big),并检查最大元素左侧的元素是否按升序排列,右侧的元素是否按降序排列(山应该是什么样的)。

n3schb8v

n3schb8v1#

下面是一个使用itertools.groupby的Python解决方案:

import itertools

def is_mountain(arr):
    return [u for u, _ in itertools.groupby(
        (b - a for a, b in zip(arr, arr[1:])),  # slope as difference
        lambda v: v // abs(v) if v else v       # slope as unit vector
    )] == [1, -1]  # strictly increasing, then decreasing

print(is_mountain([0, 2, 3, 4, 5, 2, 1, 0]))  # True
print(is_mountain([0, 2, 3, 3, 5, 2, 1, 0]))  # False

给定示例输入:

[0, 2, 3, 3, 5, 2, 1, 0]

第一生成器(b - a for a, b in zip(...))减去每对相邻元素以产生高程变化序列(各个斜率):

[2, 1, 0, 2, -3, -1, -1]

用作itertools.groupbykey参数的v // abs(v)lambda表达式通过将每个向量除以其幅值来归一化这些向量,从而生成单位向量序列(1表示增加,-1表示减少):

[1, 1, 0, 1, -1, -1, -1]

itertools.groupby组合相同的相邻元素,产生:

[1, 0, 1, -1]

然后我们可以简单地将“山”定义为一个列表,对于该列表,经过上述过程会得到精确的结果[1, -1](所有的增加都跟随着所有的减少)。

mklgxw1f

mklgxw1f2#

AscOrDes函数工作不正常:它总是在第一次迭代时退出:

int AscOrDes(int a[], int first, int last)
{
    int i;
    printf("Check array from %d to %d\n", first, last);
    for(i=first; i<last; i++)
    {
        if(a[i]>a[i+1]) {
            printf("a[%d]=%d > a[%d]=%d, so return 1\n", i, a[i], i+1, a[i+1]);
            return(1);
        }
        else if(a[i]<a[i+1]) {
            printf("a[%d]=%d < a[%d]=%d, so return 1\n", i, a[i], i+1, a[i+1]);
            return(2);
        }
    }
    return 0;
}

然而,我认为你可以更有效地评估数组,就像这样--

int state = 0;     // 0 = waiting for increase, 1 = incr, 2 = decr

for (i = 1; i < n; i++) {
    if (a[i-1] == a[i]) {
        // Equality is an immediate failure.
        printf("False\n"); exit(0);
    }
    if (a[i-1] < a[i]) {
        // We found an increase. This is valid in states 0 or 1.
        if (2 == state) {
            printf("False\n"); exit(0);
        }
        state = 1;
    } else {
        // Found a decrease. This is valid in state 1 or 2.
        if (0 == state) {
           printf("False\n"); exit(0);
        }
        state = 2;
    }
}
// At the end, we must be in state 2 (decrease after an increase).
if (2 != state) {
    printf("False\n"); exit(0);
}
printf("True\n");
cyej8jka

cyej8jka3#

下面是我在Python中的做法:

array = [3, 4, 5, 6, 9, 10, 11, 19, 6, 3, 2]

def is_strict_mountain(arr: list):
    maxim = 0
    prev = 0
    max_reached = False
    for element in arr:
        if element > maxim:
            maxim = element
        if element <= prev:
            max_reached = True
        if element >= prev and max_reached:
            return False
        prev = element
    return True

print(is_strict_mountain(array))

下面是我在C语言中的做法:

#include <stdio.h>

#define MIN_INT -2147483648

typedef enum {
    false, true
} bool;

bool is_strict_mtn(const int *array, int numElements) {
    if (array == NULL) {
        return false;
    }
    int max = MIN_INT;
    int prev = MIN_INT;
    bool max_reached = false;
    int count = 0;
    while (count++ < numElements) {
        if (*array > max) {
            max = *array;
        }
        if (*array <= prev) {
            max_reached = true;
        }
        if (*array >= prev && max_reached) {
            return false;
        }
        prev = *array++;
    }
    return true;
}

int main() {

    int arr[] = {5, 6, 7, 9, 12, 67, 56, 44, 23, 11, 5, 3, 1};

    if (is_strict_mtn(arr, 13)) {
        printf("The array is a mountain.\n");
        return 0;
    }
    printf("The array is not a mountain.\n");

    return 0;
}
7tofc5zh

7tofc5zh4#

你需要跟踪增量和减量我使用了名为delta的数组如果有增量赋值delta[i]=1如果有减量赋值delta[i]=-1 count 1 s如果它们等于last-1那么这部分有增量count -1 s如果它们等于last-1那么这部分有增量

#include<stdio.h>
 int delta[1000];

 int AscOrDes (int a[], int first, int last) 
{
 for (int i=0;i<1000;i++)  delta[i]=0;
 int r = 0;
  
 int i;  
     
int c = 0;
           
for (i = first; i <= last && (i + 1) <= last; i++)
       
  {
      
 if((a[i+1] - a[i]) > 0){
     
     delta[i]=1;
 }
 else{
 delta[i]=-1;
     
 }

 
}
  
 
for (i = first; i <= last && (i + 1) <= last; i++)
    
  {
      
 if (delta[i] > 0)
    
 {

c++;
    
}
  
      else if (delta[i] < 0)
    
    {
      
 
c--;
    
 
}
 
}
  
if (c  >= (last - first))
    
return 1;
  
if (c*-1 >= (last - first))

return 2;
  
return 0;

 
}

int main () 
{
  
int a[1000], n, i, big = 0, r1, r2;
  
scanf ("%d", &n);
  
for (i = 0; i < n; i++)
    
    {
   
scanf ("%d", &a[i]);
    
}
  
for (i = 0; i < n; i++)
    
    {
     
if (a[i] >= a[big])
    
big = i;
    
 
}
  
r1 = AscOrDes (a, 0, big);
  
 
r2 = AscOrDes (a, big, n - 1);
  
if (r1 == 1 && r2 == 2 && big != 0 && big != n - 1)
    
 
printf ("True");
  
  else
    
printf ("False");
  
return 0;

}
y3bcpkx1

y3bcpkx15#

from numpy import sign

a = [1, 3, 4, 6, 5, 7, 2, 0]

trend = [sign(a[i+1]-a[i]) for i in range(len(a)-1)]
change = [trend[i+1]-trend[i] for i in range(len(trend)-1)]
print(f'{a} is a mountain: {(trend[0] == 1) and (0 not in trend) and (2 not in change)}')
  • trend[0] == 1以确保列表以升序开始。
  • 0 not in trend以排除具有平稳段的列表。
  • 2 not in change以排除先下降后上升。

示例:

  • a:1, 3, 3, 4, 3, 5, 4, 2
  • 趋势:1, 0, 1, -1, 1, -1, -1
  • 变更:-1, 1, -2, 2, -2, 0
brvekthn

brvekthn6#

面向国家的方案拟订:状态从"up"开始,并且在a < b第一次为假时变为"down"

from itertools import pairwise, starmap

def is_mountain(a):
    def p(a,b):
        return (p.going == "up" and a < b) or setattr(p, 'going', "down") or a > b
    p.going = "up"
    return all(starmap(p,pairwise(a)))

print(is_mountain([0, 2, 3, 4, 5, 3, 1])) # True
print(is_mountain([0, 2, 3, 4, 5, 2, 4])) # False
print(is_mountain([0, 2, 3, 4, 5, 2, 1, 0]))  # True
print(is_mountain([0, 2, 3, 3, 5, 2, 1, 0]))  # False
print(is_mountain([2, 1]))  # True
iqjalb3h

iqjalb3h7#

dropwhile消耗上升的一半,然后用all消耗下降的一半。

from itertools import dropwhile, pairwise

def is_mountain(a):
    return all(a>b for a,b in dropwhile(lambda x: x[0]<x[1], pairwise(a)))

print(is_mountain([0, 2, 3, 4, 5, 3, 1])) # True
print(is_mountain([0, 2, 3, 4, 5, 2, 4])) # False
print(is_mountain([0, 2, 3, 4, 5, 2, 1, 0]))  # True
print(is_mountain([0, 2, 3, 3, 5, 2, 1, 0]))  # False
print(is_mountain([2, 1]))  # True
cedebl8k

cedebl8k8#

会尝试这种方式:

def is_moutain(A):
    i = 1

    N = len(A)
    
    while i < N and A[i] > A[i-1]:   # go on if ascending, and more items existing 
        i += 1
        
    if i == 1 or i == N:
        return False
    
       
    while N > i and A[i] < A[i-1]:   # at the descending point...
        i += 1

    return i == N
 
if __name__ == '__main__':

    print(is_moutain([0, 2, 3, 4, 5, 3, 1]))    # True
    print(is_moutain([0, 2, 3, 4, 5, 2, 4]))    # False

相关问题