Given an array of houses find how many segments exists after n queries - algorithm

I recently just encountered a leetcode style programming problem and I was wondering what the most optimal way to solve it is. The question goes like this:
Given an array of houses like houses = [1,2,3,7,8,10,11] and an array of queries like q=[2,10,8], return an array of how many segments exist after each query. Each query indicates the house that will be destroyed and the queries are executed in order.
A segment refers to a consecutive group of houses. There can technically be one house in a segment if there are no other house that are consecutive to it(it doesn't have neighbors), however it is still one segment.
Ex.
houses->[None,house,house,house,None,None,None,house,house,None,house,house]
As can be seen the house indexes match up. Before any queries there are 3 segments(they are bolded)
After the first query, the house at index 2 will be destroyed.
[None,house,None,house,None,None,None,house,house,None,house,house]
Now there are 4 segments, which means res=[4]
After the next query, house 10 is destroyed.
[None,house,None,house,None,None,None,house,house,None,None,house]
There are still 4 segments which. means res=[4,4]
After the last query, house 8 is destroyed.
[None,house,None,house,None,None,None,house,None,None,None,house]
There are still 4 segments which mean res=[4,4,4]
The array returned from this is [4,4,4]
I was wondering what the most optimal way to approach this problem is. My take was to construct a boolean array from 0 to maximum element in houses and make the indices that have a house on them True and the indices which don't have a house False. After this for each query we can just check that index and check how many neighbors it has. If it has 0 neighbors, then the number of segments decreases by 1, if it has 1 neighbor, then it stays the same, and if it has 2 then the number of segment increases by one. This approach allows me to process queries in O(1) but it is not very space efficient since we could have a house that lies at a very large index, Ex. houses=[1,1000000]. Is there a better approach to this problem? Thank you in advance.

Your solution is right but your problem of using enormous amount of space for finding in O(1) can be solved with HashMap
Make a HashMap between the house number to the Index within the array and for each query ask if the HashMap contains the number of the query, if it does just ask for the index and use your neighbor logic on the original array instead of the boolean array.
If you have multiple houses with the same number in the array use HashMap between the numer to a list of indexes with the same logic, just iterate on the list instead of the single house.
this solution has O(|houses| + |queries|) time complexity and O(|houses|) space complexity

Related

Given sequence of data(start location, end location) representing bookings for a single cab, find the optimal non breaking sequence

I have been trying to solve an optimization problem but could not able to think it through for any efficient solution.
Here's the problem
We are given data representing a sequence of bookings on a single car. Each booking data consist of two points (start location, end location). Now given two adjacent bookings b1,b2, we say a relocation is required between those bookings if the end location of b1 not equal to the start location of b2
We have to design an algorithm that takes a sequence of bookings as
input and outputs a single permutation of the input that minimizes the
total number of relocations within the sequence.
Here's my approach
To me, it looks like one of the greedy scheduling problems but I'm not able to derive any good heuristics to solve this problem from any of the existing scheduling problems. At last, I thought of sorting the given sequence on the basis of the minimum difference between start time and end time of the two adjacent sequence using insertion sort.
So, for our given problem
[(23, 42),(77, 45),(42, 77)] will get sorted to
[(23, 42),(42, 77),(77, 45)] thus minimizing end point my start point.
Let's take another example
[(3,1),(1,3),(3,1),(2,2),(3,1),(2,3),(1,3),(1,1),(3,3),(3,2),(3,3)]
now after sorting till index 7 using insertion sort, our array will look like
[(3,1),(1,3),(3,1),(2,2),(2,3),(3,3),(3,1),(1,3),(3,3),(3,2),(3,3)]
Now for placing point (3,3) present at index 8 in the unsorted array we will do the following
The idea is to put each point in its correct location. For the point
(3,3) at index 8 I will search in the already sorted array the first
entry whose endpoint matches 3 i.e. starting point of this new point,
given the condition that adding this point after that first found
entry does not violate the variant that start of next entry should
match the end of this point. So, we inserted (3,3) in between (2,3)
and (3,1) at index. It looks like this
[(3,1),(1,3),(3,1),(2,2),(2,3),(3,3),(3,1),(1,3),(3,3),(3,2),(1,1)]
However, I'm not sure how will I prove that this is the optimal or not optimal solution. Any pointer is highly appreciated. Is there a better way which I'm sure there is which will help us solve this.
You can convert this easily into a graph problem.
[a, b] -> vertices a and b with an edge between a and b. Use DFS to find all connected components in this undirected graph and do some post processing.
It is linear in input size.

Algorithm to assign best value between points based on distance

I am having trouble figuring out an algorithim to best assign values to different points on a diagram based on the distance between the points.
Essentially, I am given a diagram with a block and a dynamic amount of points. It should look something like this:
I am then given a list of values to assign to each point. Here are the rules and info:
I know the Lat,Long values for each point and the central block. In other words, I can get the direct distance from every object to another.
The list of values may be shorter that the total number of points. In this case, values can be repeated multiple times.
In the case where values must be repeated, the duplicate values should be as far away as possible from one another.
Here is an example using a value list of {1,2}:
In reality, this is a very simple example. In truth, there may be thousands of points.
Find out how many values you need to repeat, in your example you have 2 values and 5 points so, you need to have 2 repetition for 2 values, then you will have 2x2=4 positions [call this pNum] (you have to use different pairs as much as possible so that they are far apart from each other).
Calculate a distance array then find the max pNum values in the array, in other words find the greates 4 values in the array in your example.
assigne the repeated values for the the points found most far apart, and assign the rest of the points based on the array distance values.

How to enumerate all states in the 8-puzzle?

I am solving the 8-puzzle. It is a problem which looks like this:
Image courtesy of: https://ece.uwaterloo.ca/~dwharder/aads/Algorithms/N_puzzles/ (you can also see there for a more detailed description of the 8-puzzle). The user can move a square adjacent to the blank into the blank. The task is to restore the arrangement as shown in the picture, starting from some arbitrary arrangement.
Now, of course the state can be described as a permutation of 9 digits. In case of the picture shown, the permutation is:
1 2 3 4 5 6 7 8 0
However, not all permutations are reachable from the shown configuration. Therefore, I have the following questions.
What is the number of permutations obtainable from the shown initial configuration by sliding tiles into the blank?
Call the answer to the above N. Now, I want a 1-1 mapping from integers from 1 to N to permutations. That is, I want to have a function that takes a permutation and returns an appropriate integer as well as a function that takes an integer and returns the permutation. The mapping has to be a bijection (i.e. an imperfect hash is not enough).
181440.
Stick them in an array and sort it, e.g. lexicographically. Then converting integers to permutations is O(1), and going the other way is O(log n).
Well if you just want to enumerate the different possible states that can be reached, you can just depth first search from your initial state. It's very possible to generate the valid next states given a current state, for example: moving a tile down into the empty space is the same as swapping the 0 tile with the tile 3 before it in the permutation if there is one. So you just do a dfs and keep a hashset of all the permutations as your visited array which could be stored as ints or strings. there are only 9! possible states which is only 362880. If you need a 1-1 mapping from the set of integers just make the hashset a hashtable and everytime you find a new state just add it to the hash table at the next index. You could also find the shortest solution by doing a breadth first first instead and just breaking when you find the solved state.

Algorithm for certain permutaion of array elements (parallel sorting by regular sampling) [C++]

I am implementing an parallel sorting by regular sampling algorithm which is described here. I am stuck in a point at which I need to migrate sorted sublists to proper places of the sorted array. The problem can be stated in that way: There is one global array. The array has been divided into p subarrays.Each of those subarrays was sorted. p-1 global pivot elements were determined and each sub-array was divided into p sub-sub arrays (yellow, red, green). Now I need to move those sub-sub-arrays so that sub-sub-arrays with local index i are in the thread i (so they are ordered in such manner at which colors are neighbouring and the order from left to right remains).
Actually serial algorithm will do, but I just have no clever idea how to obtain a proper permutation. The following figure shows a case for p=3 threads. Yellow color denotes a sub-sub-array 0, red - 1, green - 2.
The sub-sub arrays may have different sizes.
Ok Seems like I don't have enough reputation to comment on your question, so I shall take the route of posting the answer.
So let me get this straigh. You are stuck on phase 3 of this algo. Right?
How about this:
Let's have p linkedLists of indexes. Let each process communicate the index ranges to process i; as the indexes are communicated, append the indexes to list of process i. When all the communications are over, you shall have the all the indexes for process i in the list of process i. Node of this list should be a data structre like
Node {
index
valueOfIndex
}
Now as you populate the list, copy its value also in the list.
Once you are through with the process. You can recrate your array for process i using its list i.
????

How can I sort a 10 x 10 grid of 100 car images in two dimensions, by price and speed?

Here's the scenario.
I have one hundred car objects. Each car has a property for speed, and a property for price. I want to arrange images of the cars in a grid so that the fastest and most expensive car is at the top right, and the slowest and cheapest car is at the bottom left, and all other cars are in an appropriate spot in the grid.
What kind of sorting algorithm do I need to use for this, and do you have any tips?
EDIT: the results don't need to be exact - in reality I'm dealing with a much bigger grid, so it would be sufficient if the cars were clustered roughly in the right place.
Just an idea inspired by Mr Cantor:
calculate max(speed) and max(price)
normalize all speed and price data into range 0..1
for each car, calculate the "distance" to the possible maximum
based on a²+b²=c², distance could be something like
sqrt( (speed(car[i])/maxspeed)^2 + (price(car[i])/maxprice)^2 )
apply weighting as (visually) necessary
sort cars by distance
place "best" car in "best" square (upper right in your case)
walk the grid in zigzag and fill with next car in sorted list
Result (mirrored, top left is best):
1 - 2 6 - 7
/ / /
3 5 8
| /
4
Treat this as two problems:
1: Produce a sorted list
2: Place members of the sorted list into the grid
The sorting is just a matter of you defining your rules more precisely. "Fastest and most expensive first" doesn't work. Which comes first my £100,000 Rolls Royce, top speed 120, or my souped-up Mini, cost £50,000, top speed 180?
Having got your list how will you fill it? First and last is easy, but where does number two go? Along the top or down? Then where next, along rows, along the columns, zig-zag? You've got to decide. After that coding should be easy.
I guess what you want is to have cars that have "similar" characteristics to be clustered nearby, and additionally that the cost in general increases rightwards, and speed in general increases upwards.
I would try to following approach. Suppose you have N cars and you want to put them in an X * Y grid. Assume N == X * Y.
Put all the N cars in the grid at random locations.
Define a metric that calculates the total misordering in the grid; for example, count the number of car pairs C1=(x,y) and C2=(x',y') such that C1.speed > C2.speed but y < y' plus car pairs C1=(x,y) and C2=(x',y') such that C1.price > C2.price but x < x'.
Run the following algorithm:
Calculate current misordering metric M
Enumerate through all pairs of cars in the grid and calculate the misordering metric M' you obtain if you swapt the cars
Swap the pair of cars that reduces the metric most, if any such pair was found
If you swapped two cars, repeat from step 1
Finish
This is a standard "local search" approach to an optimization problem. What you have here is basically a simple combinatorial optimization problem. Another approaches to try might be using a self-organizing map (SOM) with preseeded gradient of speed and cost in the matrix.
Basically you have to take one of speed or price as primary and then get the cars with the same value of this primary and sort those values in ascending/descending order and primaries are also taken in the ascending/descending order as needed.
Example:
c1(20,1000) c2(30,5000) c3(20, 500) c4(10, 3000) c5(35, 1000)
Lets Assume Car(speed, price) as the measure in the above list and the primary is speed.
1 Get the car with minimum speed
2 Then get all the cars with the same speed value
3 Arrange these values in ascending order of car price
4 Get the next car with the next minimum speed value and repeat the above process
c4(10, 3000)
c3(20, 500)
c1(20, 1000)
c2(30, 5000)
c5(35, 1000)
If you post what language you are using them it would we helpful as some language constructs make this easier to implement. For example LINQ makes your life very easy in this situation.
cars.OrderBy(x => x.Speed).ThenBy(p => p.Price);
Edit:
Now you got the list, as per placing this cars items into the grid unless you know that there will be this many number of predetermined cars with these values, you can't do anything expect for going with some fixed grid size as you are doing now.
One option would be to go with a nonuniform grid, If you prefer, with each row having car items of a specific speed, but this is only applicable when you know that there will be considerable number of cars which has same speed value.
So each row will have cars of same speed shown in the grid.
Thanks
Is the 10x10 constraint necessary? If it is, you must have ten speeds and ten prices, or else the diagram won't make very much sense. For instance, what happens if the fastest car isn't the most expensive?
I would rather recommend you make the grid size equal to
(number of distinct speeds) x (number of distinct prices),
then it would be a (rather) simple case of ordering by two axes.
If the data originates in a database, then you should order them as you fetch them from the database. This should only mean adding ORDER BY speed, price near the end of your query, but before the LIMIT part (where 'speed' and 'price' are the names of the appropriate fields).
As others have said, "fastest and most expensive" is a difficult thing to do, you ought to just pick one to sort by first. However, it would be possible to make an approximation using this algorithm:
Find the highest price and fastest speed.
Normalize all prices and speeds to e.g. a fraction out of 1. You do this by dividing the price by the highest price you found in step 1.
Multiply the normalized price and speed together to create one "price & speed" number.
Sort by this number.
This ensures that is car A is faster and more expensive than car B, it gets put ahead on the list. Cars where one value is higher but the other is lower get roughly sorted. I'd recommend storing these values in the database and sorting as you select.
Putting them in a 10x10 grid is easy. Start outputting items, and when you get to a multiple of 10, start a new row.
Another option is to apply a score 0 .. 200% to each car, and sort by that score.
Example:
score_i = speed_percent(min_speed, max_speed, speed_i) + price_percent(min_price, max_price, price_i)
Hmmm... kind of bubble sort could be simple algorithm here.
Make a random 10x10 array.
Find two neighbours (horizontal or vertical) that are in "wrong order", and exchange them.
Repeat (2) until no such neighbours can be found.
Two neighbour elements are in "wrong order" when:
a) they're horizontal neighbours and left one is slower than right one,
b) they're vertical neighbours and top one is cheaper than bottom one.
But I'm not actually sure if this algorithm stops for every data. I'm almost sure it is very slow :-). It should be easy to implement and after some finite number of iterations the partial result might be good enough for your purposes though. You can also start by generating the array using one of other methods mentioned here. Also it will maintain your condition on array shape.
Edit: It is too late here to prove anything, but I made some experiments in python. It looks like a random array of 100x100 can be sorted this way in few seconds and I always managed to get full 2d ordering (that is: at the end I got wrongly-ordered neighbours). Assuming that OP can precalculate this array, he can put any reasonable number of cars into the array and get sensible results. Experimental code: http://pastebin.com/f2bae9a79 (you need matplotlib, and I recommend ipython too). iterchange is the sorting method there.

Resources