Alohaaa! Buat yang belum kenal aku, salam kenal namaku Ali Zul!
Nah di kesempatan kali ini aku mau sedikit sharing seputar implementasi depth first search atau dfs di problem menghitung jumlah pulau menggunakan java nih! Well, sebenernya ini merupakan problem dari leetcode tapi di sini aku mau coba breakdown step by step supaya temen — temen juga bisa paham :)
Sebenernya sekalian ngenalin ke temen — temen tentang competitive programming + how to think the algorithm supaya bisa solve suatu problem itu sendiri. Oke daripada berlama — lama, lets crack this problem!
Depth First Search atau DFS merupakan sebuah algoritma untuk melakukan pencarian secara depth atau dalam dari sebuah titik start secara berurutan.
Jadi kalau dipahamin definisi dasar dari soalnya, kita diberikan sebuah grid sebesar m x n (2 Dimensi) yang berisi sebuah karakter 0 dan 1 yang mengrepresentasikan daratan (‘1’) dan laut (‘0’).
Pemahaman kata kunci yang kedua adalah, sebuah daratan akan terhitung satu kesatuan pulau apabila daratan dikelilingi oleh laut dan daratan berdekatan satu sama lain secara horizontal maupun vertikal (tidak secara miring)
Bingung? Oke kita lihat contohnya, yuk!
Contoh 1
grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
Output: 1
Wah kenapa ini bisa jadi 1 pulau? padahal itu kan 1-nya ada banyak, well kalau kita lihat kembali ke definisi dasar bahwa “Sebuah pulau adalah daratan yang terkoneksi dan dikelilingi laut yang terhubung secara horizontal maupun vertikal”
Oke mari kita visualisasikan supaya temen — temen makin paham sama konsepnya
Nah, karena yang ditanya adalah “Jumlah pulau” bukan “Jumlah daratan” dan ada definisi bahwa pulau merupakan daratan yang berdekatan atau terkoneksi secara horizontal maupun vertikal maka apabila ada sebuah daratan ke-1 dan ke-2 yang bersebelahan akan dianggap menjadi satu pulau. Kita coba ke contoh yang kedua ya!
Input: grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
Output: 3
Kalau kita visualisasikan akan menjadi seperti ini 👇
Kenapa kok terhitung 3 padahal kalau divisualkan itu seperti tersambung satu sama lain? Kembali ke definisi bahwa pulau merupakan gabungan dari daratan yang terkoneksi secara HORIZONTAL maupun VERTIKAL. Jadi, kalau di luar itu akan terhitung 1 pulau tersendiri
That’s the reason why terhitung menjadi 3 pulau aja :) Oke, idenya sudah dapat, kan? Sekarang, gimana caranya untuk solve problem di atas? Lets go to the next chapter!
Oke sekarang kita masuk ke dalam part yang penting banget, yaitu pemahaman logika untuk menyelesaikan soal di atas
Pertama — tama untuk menyelesaikan soal ini kita perlu membuat kerangka logika seperti ini :
public static int dfsSolve(char[][] grid, int baris, int kolom) {
}
Kode di atas merupakan deklarasi function di bahasa pemrograman java yang menerima 3 buah argumen, yaitu :
public static int dfsSolve(char[][] grid, int baris, int kolom){
if ( baris >= grid.length || kolom >= grid[0].length || baris < 0 || kolom < 0 || grid[baris][kolom] == '0' || grid.length == 0) return 0;
}
Di awal kita memberikan base case, yaitu kita melakukan check terhadap 5 jenis kondisi, mulai dari :
Langkah ke-2
`java
public static int dfsSolve(char[][] grid, int baris, int kolom){
if ( baris >= grid.length || kolom >= grid[0].length || baris < 0 || kolom < 0 || grid[baris][kolom] == '0' || grid.length == 0) {
return 0;
}
if (grid[baris][kolom] == '1') {
grid[baris][kolom] = '0';
ERROR Rendering Code Block
}
return 1;
}
`
Di tahap berikutnya kita akan melakukan pengecekan terhadap grid baris ke-i dan kolom ke-j, apakah dia bernilai ‘1’ ? Jika iya, maka akan kita melakukan step :
Step di atas merupakan sebuah step secara rekursif, jadi dia akan memanggil fungsinya sendiri dan akan melakukan logika dari awal lagi.
public int numIslands(char[][] grid) {
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
res += dfsSolve(grid, i, j);
}
}
return res;
}
Nah di sini sebenernya simple2 aja, di awal kita inisialisasikan sebuah variable result dengan tipe data integer dan memiliki nilai awal 0
Setelah itu kita lakukan nested loop dan kita beri nilai tambah ke dalam variable res dengan memanggil fungsi yang berisi dfsSolve(grid, i, j)
class Solution {
public int numIslands(char[][] grid) {
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
res += dfsSolve(grid, i, j);
}
}
return res;
}
public static int dfsSolve(char [][] grid, int baris, int kolom) {
if ( baris >= grid.length || kolom >= grid[0].length || baris < 0 || kolom < 0 || grid[baris][kolom] == '0' || grid.length == 0) return 0;
if (grid[baris][kolom] == '1') {
grid[baris][kolom] = '0';
dfsSolve(grid, baris + 1, kolom);
dfsSolve(grid, baris - 1, kolom);
dfsSolve(grid, baris, kolom + 1);
dfsSolve(grid, baris, kolom - 1);
}
return 1;
}
}
Yuhuu! Gimana, seru gak sih nyelesaiin soal yang beginii? Eits, tapi kalo temen — temen ngerasa “kok susah ya?”, “kok kurang paham ya?” jangan takut! Sebenernya temen — temen bukan “ngga paham”, tapi “belum dapet ide”-nya aja! Nah caranya gimana sih biar bisa paham sama soal — soal yang competitive, tentu dengan dilatih setiap hari secara konsisten.
Kalian bisa belajar melalui hackerrank, leetcode, codeforces, tlx toki, ataupun website lainnya. Lalu yang kedua, kalian bisa nih dengan belajar lebih dalam konsep dasar dari algoritma dan struktur data! So, pemahaman kalian akan jauuuh lebih matang :)