Flower Planting With No Adjacent
Problem
You have n gardens, labeled from 1 to n, and an array paths where
paths[i] = [xi, yi] describes a bidirectional path between garden xi to garden yi. In each garden, you want to plant one of 4 types of flowers.
All gardens have at most 3 paths coming into or leaving it.
Your task is to choose a flower type for each garden such that, for any two gardens connected by a path, they have different types of flowers.
Return _any such a choice as an array _answer , whereanswer[i]is the type of flower planted in the(i+1)th garden. The flower types are denoted1 ,2 ,3 , or4 . It is guaranteed an answer exists.
Examples
Example 1
Input: n = 3, paths = [[1,2],[2,3],[3,1]]
Output: [1,2,3]
Explanation:
Gardens 1 and 2 have different types.
Gardens 2 and 3 have different types.
Gardens 3 and 1 have different types.
Hence, [1,2,3] is a valid answer. Other valid answers include [1,2,4], [1,4,2], and [3,2,1].
Example 2
Input: n = 4, paths = [[1,2],[3,4]]
Output: [1,2,1,2]
Example 3
Input: n = 4, paths = [[1,2],[2,3],[3,4],[4,1],[1,3],[2,4]]
Output: [1,2,3,4]
Constraints
1 <= n <= 10^40 <= paths.length <= 2 * 10^4paths[i].length == 21 <= xi, yi <= nxi != yi- Every garden has at most 3 paths coming into or leaving it.
Solution
Method 1 – Greedy Coloring (Graph Coloring)
Intuition
Since each garden has at most 3 neighbors and there are 4 flower types, we can always assign a flower type to each garden such that no two adjacent gardens have the same type. This is a classic greedy coloring problem.
Approach
- Build an adjacency list for all gardens.
- For each garden from 1 to n:
- Check the flower types used by its neighbors.
- Assign the smallest flower type (1-4) not used by its neighbors.
- Return the flower types for all gardens.
Code
C++
class Solution {
public:
vector<int> gardenNoAdj(int n, vector<vector<int>>& paths) {
vector<vector<int>> g(n);
for (auto& p : paths) {
g[p[0]-1].push_back(p[1]-1);
g[p[1]-1].push_back(p[0]-1);
}
vector<int> ans(n, 0);
for (int i = 0; i < n; ++i) {
bool used[5] = {};
for (int v : g[i]) used[ans[v]] = true;
for (int c = 1; c <= 4; ++c) {
if (!used[c]) {
ans[i] = c;
break;
}
}
}
return ans;
}
};
Go
type Solution struct{}
func (Solution) gardenNoAdj(n int, paths [][]int) []int {
g := make([][]int, n)
for _, p := range paths {
g[p[0]-1] = append(g[p[0]-1], p[1]-1)
g[p[1]-1] = append(g[p[1]-1], p[0]-1)
}
ans := make([]int, n)
for i := 0; i < n; i++ {
used := [5]bool{}
for _, v := range g[i] {
used[ans[v]] = true
}
for c := 1; c <= 4; c++ {
if !used[c] {
ans[i] = c
break
}
}
}
return ans
}
Java
class Solution {
public int[] gardenNoAdj(int n, int[][] paths) {
List<Integer>[] g = new List[n];
for (int i = 0; i < n; i++) g[i] = new ArrayList<>();
for (int[] p : paths) {
g[p[0]-1].add(p[1]-1);
g[p[1]-1].add(p[0]-1);
}
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
boolean[] used = new boolean[5];
for (int v : g[i]) used[ans[v]] = true;
for (int c = 1; c <= 4; c++) {
if (!used[c]) {
ans[i] = c;
break;
}
}
}
return ans;
}
}
Kotlin
class Solution {
fun gardenNoAdj(n: Int, paths: Array<IntArray>): IntArray {
val g = Array(n) { mutableListOf<Int>() }
for (p in paths) {
g[p[0]-1].add(p[1]-1)
g[p[1]-1].add(p[0]-1)
}
val ans = IntArray(n)
for (i in 0 until n) {
val used = BooleanArray(5)
for (v in g[i]) used[ans[v]] = true
for (c in 1..4) {
if (!used[c]) {
ans[i] = c
break
}
}
}
return ans
}
}
Python
class Solution:
def gardenNoAdj(self, n: int, paths: list[list[int]]) -> list[int]:
g = [[] for _ in range(n)]
for x, y in paths:
g[x-1].append(y-1)
g[y-1].append(x-1)
ans = [0] * n
for i in range(n):
used = {ans[v] for v in g[i]}
for c in range(1, 5):
if c not in used:
ans[i] = c
break
return ans
Rust
impl Solution {
pub fn garden_no_adj(n: i32, paths: Vec<Vec<i32>>) -> Vec<i32> {
let n = n as usize;
let mut g = vec![vec![]; n];
for p in &paths {
g[(p[0]-1) as usize].push((p[1]-1) as usize);
g[(p[1]-1) as usize].push((p[0]-1) as usize);
}
let mut ans = vec![0; n];
for i in 0..n {
let mut used = [false; 5];
for &v in &g[i] {
used[ans[v] as usize] = true;
}
for c in 1..=4 {
if !used[c] {
ans[i] = c as i32;
break;
}
}
}
ans
}
}
TypeScript
class Solution {
gardenNoAdj(n: number, paths: number[][]): number[] {
const g: number[][] = Array.from({length: n}, () => []);
for (const [x, y] of paths) {
g[x-1].push(y-1);
g[y-1].push(x-1);
}
const ans: number[] = Array(n).fill(0);
for (let i = 0; i < n; i++) {
const used = new Set<number>();
for (const v of g[i]) used.add(ans[v]);
for (let c = 1; c <= 4; c++) {
if (!used.has(c)) {
ans[i] = c;
break;
}
}
}
return ans;
}
}
Complexity
- ⏰ Time complexity:
O(n), since each garden and its neighbors are processed once. - 🧺 Space complexity:
O(n + m), wheremis the number of paths, for the adjacency list and answer array.