2463. Minimum Total Distance Traveled (Hard)

Topic sharing to help you maintain your daily (31/10/2024) coding streak! ??

https://leetcode.com/problems/minimum-total-distance-traveled/

There are some robots and factories on the X-axis. You are given an integer array?robot?where?robot[i]?is the position of the?ith?robot. You are also given a 2D integer array?factory?where?factory[j] = [positionj, limitj]?indicates that?positionj?is the position of the?jth?factory and that the?jth?factory can repair at most?limitj?robots.

The positions of each robot are?unique. The positions of each factory are also?unique. Note that a robot can be?in the same position?as a factory initially.

All the robots are initially broken; they keep moving in one direction. The direction could be the negative or the positive direction of the X-axis. When a robot reaches a factory that did not reach its limit, the factory repairs the robot, and it stops moving.

At any moment, you can set the initial direction of moving for?some?robot. Your target is to minimize the total distance traveled by all the robots.

Return?the minimum total distance traveled by all the robots. The test cases are generated such that all the robots can be repaired.

Note that

  • All robots move at the same speed.
  • If two robots move in the same direction, they will never collide.
  • If two robots move in opposite directions and they meet at some point, they do not collide. They cross each other.
  • If a robot passes by a factory that reached its limits, it crosses it as if it does not exist.
  • If the robot moved from a position?x?to a position?y, the distance it moved is?|y - x|.

Given an integer array?nums, return?the?minimum?number of elements to remove to make?nums?a?mountain array.

Input: robot = [0,4,6], factory = [[2,2],[6,2]]
Output: 4        

?? Solution Overview: Optimizing Robot Movements

??Step 1:?Sort the list of robots and factories, removing any factories with a capacity of 0. This helps streamline our factory list and enhances efficiency.

??Step 2:?Calculate the distance constraints where Robot 0 cannot move left and Robot n-1 cannot move right. This allows us to minimize our robot list effectively.

??Step 3:?Allow each robot (from index 0 to n-1) to move left or right, comparing distances to determine the optimal direction for each robot.

???Pro tip:?Implement caching! This approach will save you from recalculating values multiple times, improving performance significantly.

Happy coding! ??

#Coding #Algorithms #DataStructures #Go

package main

import (
	"fmt"
	"sort"
)

func minimumTotalDistance(robot []int, factory [][]int) int64 {
	totalRobot := len(robot)
	capacity := 0
	factory2 := make([][]int, 0)
	for _, v := range factory {
		capacity += v[1]
		if v[1] != 0 {
			factory2 = append(factory2, v)
		}
	}
	factory = factory2
	if capacity < totalRobot {
		return -1
	}
	sort.Slice(robot, func(i, j int) bool {
		return robot[i] < robot[j]
	})
	sort.Slice(factory, func(i, j int) bool {
		return factory[i][0] < factory[j][0]
	})
	mapRs := make(map[string]int64)
	for factory[len(factory)-1][1] == 0 {
		factory = factory[:len(factory)-1]
	}
	for factory[0][1] == 0 {
		factory = factory[1:]
	}
	var rm int64
	//robot len(robot)-1 can't move right
	for len(robot) > 0 && robot[len(robot)-1] >= factory[len(factory)-1][0] {
		factory[len(factory)-1][1]--
		rm += int64(robot[len(robot)-1] - factory[len(factory)-1][0])
		robot = robot[:len(robot)-1]
		capacity--
		for len(factory) > 0 && factory[len(factory)-1][1] == 0 {
			factory = factory[:len(factory)-1]
		}
	}
	return rm + minimumTotalDistanceSorted(robot, factory, capacity, mapRs)

}
func minimumTotalDistanceSorted(robot []int, factory [][]int, capacity int, mapRs map[string]int64) int64 {
	if len(robot) == 0 {
		return 0
	}
	if len(factory) == 0 {
		return -1
	}
	if capacity < len(robot) {
		mapRs[fmt.Sprintf("%d_%d_%d", len(robot), len(factory), capacity)] = -1
		return -1
	}
	var rm int64
	var rmi int
	rm, ok := mapRs[fmt.Sprintf("%d_%d_%d", len(robot), len(factory), capacity)]
	if ok {
		return rm
	}
	if capacity == len(robot) {
		i := 0
		j := 0
		for i < len(robot) {
			for factory[j][1] == 0 {
				j++
			}
			if factory[j][0] > robot[i] {
				rm += int64(factory[j][0] - robot[i])
			} else {
				rm += int64(robot[i] - factory[j][0])
			}
			rmi++
			factory[j][1]--
			i++
		}
		mapRs[fmt.Sprintf("%d_%d_%d", len(robot)+rmi, len(factory), capacity)] = rm
		return rm
	}
	if len(robot) == 1 {
		rm += minimumTotalDistance1(robot, factory)
		mapRs[fmt.Sprintf("%d_%d_%d", len(robot)+rmi, len(factory), capacity)] = rm
		return rm
	}

	//robot 0 can't move left
	for len(robot) > 0 && robot[0] <= factory[0][0] {
		factory[0][1]--
		rm += int64(factory[0][0] - robot[0])
		robot = robot[1:]
		rmi++
		capacity--
		for factory[0][1] == 0 {
			factory = factory[1:]
		}
	}
	if len(robot) == 0 {
		mapRs[fmt.Sprintf("%d_%d_%d", len(robot)+rmi, len(factory), capacity)] = rm
		return rm
	}
	if len(robot) == 1 {
		rm += minimumTotalDistance1(robot, factory)
		mapRs[fmt.Sprintf("%d_%d_%d", len(robot)+rmi, len(factory), capacity)] = rm
		return rm
	}
	//try robot 0 at factory 0
	//try robot 0 at factory > 0
	robot2 := make([]int, len(robot))
	factory2 := make([][]int, len(factory)-1)
	copy(robot2, robot)
	for i := range factory2 {
		factory2[i] = make([]int, 2)
		copy(factory2[i], factory[i+1])
	}
	r2Try := minimumTotalDistanceSorted(robot2, factory2, capacity-factory[0][1], mapRs)
	r0 := int64(robot[0] - factory[0][0])
	if r2Try != -1 && r2Try <= r0 {
		mapRs[fmt.Sprintf("%d_%d_%d", len(robot)+rmi, len(factory), capacity)] = rm + r2Try
		return rm + r2Try
	}
	robot1 := make([]int, len(robot)-1)
	factory1 := make([][]int, len(factory))
	copy(robot1, robot[1:])
	for i := range factory {
		factory1[i] = make([]int, 2)
		copy(factory1[i], factory[i])
	}
	factory1[0][1]--
	for factory1[0][1] == 0 {
		factory1 = factory1[1:]
	}
	r1Try := minimumTotalDistanceSorted(robot1, factory1, capacity-1, mapRs)

	if r1Try == -1 && r2Try == -1 {
		mapRs[fmt.Sprintf("%d_%d_%d", len(robot)+rmi, len(factory), capacity)] = -1
		return -1
	}
	var min int64 = -1
	if r1Try != -1 {
		min = r1Try + r0
	}
	if r2Try != -1 && (r2Try < min || min == -1) {
		min = r2Try
	}
	mapRs[fmt.Sprintf("%d_%d_%d", len(robot)+rmi, len(factory), capacity)] = rm + min
	return rm + min
}
func minimumTotalDistance1(robot []int, factory [][]int) int64 {
	min := -1
	for _, v := range factory {
		if v[1] == 0 {
			continue
		}
		if min == -1 || v[0] == robot[0] || ((v[0] > robot[0] && v[0]-robot[0] < min) || (v[0] < robot[0] && robot[0]-v[0] < min)) {
			if v[0] >= robot[0] {
				min = v[0] - robot[0]
			} else {
				min = robot[0] - v[0]
			}
		}
		if min != -1 && v[0] < robot[0] && robot[0]-v[0] > min {
			break
		}
	}
	return int64(min)
}
func main() {
	fmt.Println(minimumTotalDistance([]int{-785116950, 989862795, -894859426, -781626140, 672589313, -941317336, 989421436, 174986851, -264848203, 713675411, -244816575, -52030457, -371084440, -715835641, 326827033, -931928762, -84629082, -308854322, -770052083, 90773530}, [][]int{{-964121556, 20}}))

}        
Nh?t An ?inh

Head of Site Reliability Engineer Cum App Security Senior Manager

4 个月

??

回复

要查看或添加评论,请登录

Danh Hieu Luu的更多文章

社区洞察

其他会员也浏览了