Nó có phải là một đống tối đa?


14

Một đống , còn được gọi là hàng đợi ưu tiên, là một kiểu dữ liệu trừu tượng. Về mặt khái niệm, nó là một cây nhị phân nơi con của mọi nút nhỏ hơn hoặc bằng chính nút đó. (Giả sử đó là một đống tối đa.) Khi một phần tử được đẩy hoặc bật, heap sắp xếp lại chính nó để phần tử lớn nhất là phần tử tiếp theo được bật lên. Nó có thể dễ dàng được thực hiện như một cây hoặc như một mảng.

Thách thức của bạn, nếu bạn chọn chấp nhận nó, là xác định xem một mảng có phải là một đống hợp lệ hay không. Một mảng ở dạng heap nếu con của mọi phần tử nhỏ hơn hoặc bằng chính phần tử đó. Lấy mảng sau đây làm ví dụ:

[90, 15, 10, 7, 12, 2]

Thực sự, đây là một cây nhị phân được sắp xếp dưới dạng một mảng. Điều này là do mọi yếu tố có con. 90 có hai con, 15 và 10.

       15, 10,
[(90),         7, 12, 2]

15 cũng có con, 7 và 12:

               7, 12,
[90, (15), 10,        2]

10 có con:

                      2
[90, 15, (10), 7, 12,  ]

và yếu tố tiếp theo cũng sẽ là một đứa trẻ 10 tuổi, ngoại trừ việc không có phòng. 7, 12 và 2 tất cả cũng sẽ có con nếu mảng đủ dài. Đây là một ví dụ khác về một đống:

[16, 14, 10, 8, 7, 9, 3, 2, 4, 1]

Và đây là một hình ảnh trực quan của cây mà mảng trước tạo ra:

nhập mô tả hình ảnh ở đây

Chỉ trong trường hợp điều này không đủ rõ ràng, đây là công thức rõ ràng để có được phần tử con của phần tử thứ i

//0-indexing:
child1 = (i * 2) + 1
child2 = (i * 2) + 2

//1-indexing:
child1 = (i * 2)
child2 = (i * 2) + 1

Bạn phải lấy một mảng không trống làm đầu vào và đầu ra một giá trị trung thực nếu mảng đó theo thứ tự heap và một giá trị giả khác. Đây có thể là một heap 0 chỉ mục, hoặc heap 1 chỉ mục miễn là bạn chỉ định định dạng chương trình / chức năng của bạn mong đợi. Bạn có thể cho rằng tất cả các mảng sẽ chỉ chứa các số nguyên dương. Bạn không được sử dụng bất kỳ nội dung heap nào. Điều này bao gồm, nhưng không giới hạn

  • Các hàm xác định nếu một mảng ở dạng heap
  • Các hàm chuyển đổi một mảng thành một đống hoặc thành dạng heap
  • Các hàm lấy một mảng làm đầu vào và trả về cấu trúc dữ liệu heap

Bạn có thể sử dụng tập lệnh python này để xác minh xem một mảng có ở dạng heap hay không (0 được lập chỉ mục):

def is_heap(l):
    for head in range(0, len(l)):
        c1, c2 = head * 2 + 1, head * 2 + 2
        if c1 < len(l) and l[head] < l[c1]:
            return False
        if c2 < len(l) and l[head] < l[c2]:
            return False

    return True

Kiểm tra IO:

Tất cả các đầu vào này sẽ trả về True:

[90, 15, 10, 7, 12, 2]
[93, 15, 87, 7, 15, 5]
[16, 14, 10, 8, 7, 9, 3, 2, 4, 1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[100, 19, 36, 17, 3, 25, 1, 2, 7]
[5, 5, 5, 5, 5, 5, 5, 5]

Và tất cả các đầu vào này sẽ trả về Sai:

[4, 5, 5, 5, 5, 5, 5, 5]
[90, 15, 10, 7, 12, 11]
[1, 2, 3, 4, 5]
[4, 8, 15, 16, 23, 42]
[2, 1, 3]

Như thường lệ, đây là môn đánh gôn, vì vậy các sơ hở tiêu chuẩn được áp dụng và câu trả lời ngắn nhất bằng byte sẽ thắng!



Có đúng không nếu có các yếu tố lặp đi lặp lại, có thể không thể tạo thành một đống theo định nghĩa này?
frageum

@feersum [3, 2, 1, 1]thì sao?
Neil

@feersum Đó là một điểm tuyệt vời, tôi đã không nghĩ về điều đó. Tôi đã cập nhật mô tả của một đống và thêm một số ví dụ với các yếu tố trùng lặp. Cảm ơn bạn!
DJMcMayhem

5
Một đống không còn được gọi là hàng đợi ưu tiên. Một hàng đợi ưu tiên là loại dữ liệu trừu tượng. Heap là cấu trúc dữ liệu đôi khi được sử dụng để thực hiện hàng đợi ưu tiên (Bản thân heap được triển khai trên các cấu trúc dữ liệu tài trợ thậm chí nhiều hơn, nhưng đó là bên cạnh điểm). Hàng đợi ưu tiên có thể được triển khai trên đầu các cấu trúc dữ liệu khác - như danh sách được liên kết.
Lyndon White

Câu trả lời:


7

Thạch, 11 9 5 byte

x2:ḊṂ

Xóa 4 byte nhờ Dennis!

Hãy thử nó ở đây.

Giải trình

x2          Duplicate each element.
:Ḋ          Each element divided by the input with the first element removed,
            as integer, so there is a 0 only if some element in the duplicated
            list is less than the corresponding element in the other.
            There are also elements left unchanged, but it doesn't matter as
            the input is all positive.
Ṃ           Minimum in the list.

10

JavaScript (ES6), 34 30 byte

a=>!a.some((e,i)=>e>a[i-1>>1])

Chỉnh sửa: Sửa mã của tôi để làm rõ thông số chi phí 1 byte, do đó, xin cảm ơn @ edc65 để lưu 4 byte.


Nó thất bại testcase 2 [93, 15, 87, 7, 15, 5]và 6[5, 5, 5, 5, 5, 5, 5, 5]
edc65

Điều này hoạt động tốt hơn và ngắn hơn 3 chara=>!a.some((e,i)=>e>a[i-1>>1])
edc65

1
@ edc65 Những cái cặp đó đã được thêm vào sau khi tôi viết câu trả lời.
Neil

5

Haskell, 33 byte

f(a:b)=and$zipWith(<=)b$a:b<*"xx"

hoặc là

and.(zipWith(<=).tail<*>(<*"xx"))

4

J, 24 byte

*/@:<:]{~0}:@,<.@-:@i.@#

Giải trình

*/@:<:]{~0}:@,<.@-:@i.@#  Input: s
                       #  Count of s
                    i.@   Create range [0, 1, ..., len(s)-1]
                 -:@      Halve each
              <.@         Floor each
         0   ,            Prepend a zero to it
          }:@             Remove the last value to get the parent indices of each
      ]                   Identity function to get s
       {~                 Take the values from s at the parent indices
    <:                    For each, 1 if it is less than or equal to its parent else 0
*/@:                      Reduce using multiplication and return

3

MATL , 13 12 byte

ttf2/k)>~4L)

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Một mảng là trung thực nếu nó không trống và tất cả các mục của nó là khác không. Nếu không thì đó là giả. Đây là một số ví dụ .

Giải trình

t     % Take input implicitly. Duplicate
tf    % Duplicate and push indices of nonzero entries. This gives [1 2 ... n] where n
      % is input size
2/k   % Divide by 2 and round down
)     % Index into input. Gives array of parents, except for the first entry
>~    % True for entries of the input that don't exceed those in the array of parents
4L)   % Discard first entry

2

Python 2, 45 byte

f=lambda l:l==[]or l[len(l)/2-1]/l.pop()*f(l)

Đầu ra 0 cho Falsy, nonzero cho Truthy.

Kiểm tra xem phần tử cuối cùng nhỏ hơn hoặc bằng cha mẹ của nó tại chỉ mục len(l)/2-1. Sau đó, đệ quy để kiểm tra xem điều đó có đúng không với phần tử cuối cùng của danh sách bị xóa, và cứ thế cho đến khi danh sách trống.


48 byte:

f=lambda l,i=1:l==l[:i]or l[~-i/2]/l[i]*f(l,i+1)

Kiểm tra xem tại mỗi chỉ mục i, phần tử có nhiều nhất là cha mẹ của nó tại chỉ mục(i-1)/2 . Bộ phận sàn tạo ra 0 nếu đây không phải là trường hợp.

Làm trường hợp cơ sở như i/len(l)orcho chiều dài tương tự. Tôi đã thử nén lúc đầu, nhưng có mã dài hơn (57 byte).

lambda l:all(map(lambda a,b,c:b<=a>=c,l,l[1::2],l[2::2]))

1

R, 97 88 82 byte

Hy vọng tôi đã hiểu điều này một cách chính xác. Bây giờ để xem liệu tôi có thể thoát khỏi một số byte nữa không. Đã bỏ rbind và đưa vào một cách khéo léo và đối phó với vector dựa trên 1 đúng cách.

Được thực hiện như một chức năng chưa được đặt tên

function(Y)all(sapply(1:length(Y),function(X)Y[X]>=Y[X*2]&Y[X]>=Y[X*2+1]),na.rm=T)

Với một vài trường hợp thử nghiệm

> f=
+ function(Y)all(sapply(1:length(Y),function(X)Y[X]>=Y[X*2]&Y[X]>=Y[X*2+1]),na.rm=T)
> f(c(90, 15, 10, 7, 12, 2))
[1] TRUE
> f(c(93, 15, 87, 7, 15, 5))
[1] TRUE
> f(c(10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
[1] TRUE
> f(c(5, 5, 5, 5, 5, 5, 5, 5))
[1] TRUE
> f(c(4, 5, 5, 5, 5, 5, 5, 5))
[1] FALSE
> f(c(90, 15, 10, 7, 12, 11))
[1] FALSE
> f(c(4, 8, 15, 16, 23, 42))
[1] FALSE

Bạn có thể sử dụng seq(Y)thay vì 1:length(Y).
rturnbull


1

Bình thường, 8 byte

.AgV.i+h

       hQ      first element of input
      +  Q     plus input
    .i    Q    interleaved with input
  gV       Q   vectorized greater-than-or-equal comparison with input
.A             check if all results are true

Dùng thử trực tuyến



0

C ++ 14, 134 105 byte

#define M(d) (2*i+d<c.size()&&(c[i]<c[2*i+d]||f(c,2*i+d)==0))
int f(auto&c,int i=0){return!(M(1)||M(2));}

Đòi hỏi c phải là một container hỗ trợ .operator[](int).size(), như thế std::vector<int>.

Ung dung:

int f(auto& c, int i=0) {
    if (2*i+1<c.size() && c[i] < c[2*i+1]) return 0;
    if (2*i+2<c.size() && c[i] < c[2*i+2]) return 0;
    if (2*i+1<c.size() && (f(c,2*i+1) == 0)) return 0;
    if (2*i+2<c.size() && (f(c,2*i+2) == 0)) return 0;
    return 1;
}

Có thể nhỏ hơn nếu Truthy = 0và falsy = 1sẽ được cho phép.


0

R, 72 byte

Một cách tiếp cận hơi khác với câu trả lời R khác .

x=scan();all(diff(x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)],l=N*2)<1,na.rm=T)

Đọc đầu vào từ stdin, tạo một vectơ của tất cả các cặp so sánh, trừ chúng với nhau và kiểm tra xem kết quả là số âm hay bằng 0.

Giải trình

Đọc đầu vào từ stdin:

x=scan();

Tạo cặp của chúng tôi. Chúng tôi tạo các chỉ số của 1...N(trong đó Nlà độ dài x) cho các nút cha. Chúng tôi thực hiện điều này hai lần vì mỗi phụ huynh có (tối đa) hai con. Chúng tôi cũng đưa trẻ em, (1...N)*2(1...N)*2+1. Đối với các chỉ số vượt quá độ dài x, R trả về NA, 'không khả dụng'. Đối với đầu vào 90 15 10 7 12 2, mã này cung cấp cho chúng tôi 90 15 10 7 12 2 90 15 10 7 12 2 15 7 2 NA NA NA 10 12 NA NA NA NA.

                  x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)]

Trong vectơ cặp này, mỗi phần tử có đối tác của nó ở khoảng cách N*2xa. Ví dụ: đối tác của mục 1 nằm ở vị trí 12 (6 * 2). Chúng tôi sử dụng diffđể tính toán sự khác biệt giữa các cặp này, chỉ định lag=N*2để so sánh các mục với các đối tác chính xác của chúng. Bất kỳ hoạt động trên NAcác yếu tố chỉ đơn giản là trở lại NA.

             diff(x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)],l=N*2)

Cuối cùng, chúng tôi kiểm tra rằng tất cả các giá trị được trả về này nhỏ hơn 1(tức là số thứ nhất, cha mẹ, lớn hơn số thứ hai, con), không bao gồm NAcác giá trị được xem xét.

         all(diff(x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)],l=N*2)<1,na.rm=T)

0

Thực ra , 16 byte

Câu trả lời này phần lớn dựa trên câu trả lời Jelly của jimmy23013 . Gợi ý chơi golf chào mừng! Hãy thử trực tuyến!

;;2╟┬Σ1(tZ`i<`Mm

Ungolfing

         Implicit input a.
;;       Duplicate a twice.
2╟       Wrap two of the duplicates into a list.
┬        Transpose the duplicates.
Σ        Sum all of the columns to get a flat list like this:
           [a_0, a_0, a_1, a_1, ..., a_n, a_n]
         This gets the parent nodes of the heap.
1(t      Get a[1:] using the remaining duplicate of a.
         This is a list of the child nodes of the heap.
Z`i<`M   Check if every child node is less than its parent node.
m        Get the minimum. This returns 1 if a is a max-heap, else 0.
         Implicit return.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.