简体   繁体   中英

Divide a list into sublists such that difference between any 2 elements in a sublist should not exceed k

Can anyone provide an approach for this.

Divide a list into sublists such that the absolute difference between any 2 elements in a sublist should not exceed a 'k' value.sublists can be formed irrespective of order. A sublist can be of any number of elements. The number of sublists should be minimal

Example:
arr=[1,5,4,6,8,9,2]
k=3

sublists generated are [[2,1],[5,4,6],[8,9]]

Example 2:
arr=[1,13,6,8,9,3,5]
k=4

sublists generated are [[1,3,5],[6,8],[13,9]]

We need to return the minimal number of sublist where the difference between 2 lists must not exceed k. an element can be in only 1 sublist

I have tried my best to solve it, but couldn't. Any help is appreciated

Thanks

# easier version
arr = sorted(arr)
lst = []
sublist = [arr.pop(0)]
while len(arr) > 0:
    item = arr.pop(0)
    if item - sublist[0] >= k:
        lst.append(sublist)
        sublist = [item]
    else:
        sublist.append(item)
lst.append(sublist)
print(lst)

# shorter version
arr = sorted(arr)
lst = [[arr.pop(0)]]
while len(arr) > 0:
    item = arr.pop(0)
    lst.append([item]) if item - lst[-1][0] >= k else lst[-1].append(item)
print(lst)

Here is a simple approach using the sorted array:

NB. I used a strict threshold here, update the code to use "<=" if equality is accepted.

def split(arr, k):
    out = []
    for i in sorted(arr):
        if not out:
            out = [[i]]
            continue
        if out[-1] and i-out[-1][0] < k:  # use <= to accept equality
            out[-1].append(i)
        else:
            out.append([i])
    return out

example:

split([1,5,4,6,8,9,2], 3)
# [[1, 2], [4, 5, 6], [8, 9]]

split([1,13,6,8,9,3,5], 4)
# [[1, 3], [5, 6, 8], [9], [13]]
def ex(arr, k):
    arr = sorted(arr)
    new_lst = []
    sub_lst = [arr[0]]
    for i in range(1, len(arr)):
        if arr[i] - sub_lst[0] < k:
            sub_lst.append(arr[i])
        else:
            new_lst.append(sub_lst)
            sub_lst = [arr[i]]
    new_lst.append(sub_lst)
    return new_lst


arr = [1, 13, 6, 8, 9, 3, 5]
k = 4
print(ex(arr, k))

Little explanation: We are sorting the list. Than we check for the first element the matching items. Because the list is sorted, they will be right next to him in the list. If the next element isnt matching, we can "close" this sub_lst, append it to the new_lst, and than initialize the sub_lst with the next item. Once we finished, we need to append sub_lst to new_lst because we didn't get in the if statement there.

Example:

import random                                                                                                                                                                                 
                                                                                                                                                                                              
k=10                                                                                                                                                                                          
random.seed(10)                                                                                                                                                                               
randomList = []                                                                                                                                                                               
listOfSublist = []                                                                                                                                                                            
for i in range(0,10):                                                                                                                                                                         
    n = random.randint(1,100)                                                                                                                                                                 
    randomList.append(n)
print(randomList)   
# uncomment this to test with the example
# randomList = [1,13,6,8,9,3,5]
# k = 4                                                                                                                                             
randomList.sort()                                                                                                                                                                             
print(randomList)                                                                                                                                                                             
                                                                                                                                                                                              
n = 0                                                                                                                                                                                         
for i in range(len(randomList)-1):                                                                                                                                                            
    if randomList[i+1] - randomList[n] >= k: # when difference exceed k, create sublist                                                                                                        
        listOfSublist.append( randomList[n:i+1])                                                                                                                                              
        n=i+1                                                                                                                                                                                 
                                                                                                                                                                                              
listOfSublist.append( randomList[n:len(randomList)]) # handle the end of the list                                                                                                                                          
print(listOfSublist)

I believe there is a solution without sorting, and you can improve this by deleting the numbers you pick from randomList at each step, in case memory is an issue.

output:

[74, 5, 55, 62, 74, 2, 27, 60, 63, 36]
[2, 5, 27, 36, 55, 60, 62, 63, 74, 74]
[[2, 5], [27, 36], [55, 60, 62, 63], [74, 74]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM