DSA Tracker

DSA Tracker

Beginner path · Java

Updated 2026-10-21

Learn DSA in Java from scratch

Java suits learners who want explicit types, a broad collections library and code close to what production services use. It is more verbose than Python, but that structure makes interfaces and numeric limits visible while you learn.

What you need from Java before DSA

01

Variables and types

Java requires a declared type, and choosing int or long affects overflow in algorithms.

public class Main {
    public static void main(String[] args) {
        int count = 3;
        String label = "items";
        System.out.println(label + " " + count);
    }
}

Output: items 3

02

Conditionals and loops

Scanning arrays and graphs depends on predictable branches and iteration.

public class Main {
    public static void main(String[] args) {
        int total = 0;
        for (int value : new int[]{2, 4, 5})
            if (value % 2 == 0) total += value;
        System.out.println(total);
    }
}

Output: 6

03

Functions

Static methods give each algorithm explicit parameters and a return type.

public class Main {
    static int doubleValue(int value) { return value * 2; }
    public static void main(String[] args) {
        System.out.println(doubleValue(6));
    }
}

Output: 12

04

Recursion

Tree traversal and divide-and-conquer rely on a method calling itself with a smaller case.

public class Main {
    static void countdown(int n) {
        if (n == 0) return;
        System.out.println(n);
        countdown(n - 1);
    }
    public static void main(String[] args) { countdown(3); }
}

Output: 3 2 1

05

Arrays and lists

Arrays are fixed-size indexed storage; ArrayList is the resizable version used in many solutions.

import java.util.*;
public class Main {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>(List.of(3, 1, 2));
        numbers.add(4);
        System.out.println(numbers.get(1) + " " + numbers.size());
    }
}

Output: 1 4

06

Strings

String values are immutable, so comparisons and efficient building need deliberate APIs.

public class Main {
    public static void main(String[] args) {
        String word = "level";
        System.out.println(word.equals(new StringBuilder(word).reverse().toString()));
    }
}

Output: true

07

Hash maps and sets

HashMap and HashSet provide average constant-time lookup for counts and membership.

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Set<Integer> seen = new HashSet<>(Set.of(2, 4));
        Map<String, Integer> counts = Map.of("a", 2);
        System.out.println(seen.contains(4) + " " + counts.get("a"));
    }
}

Output: true 2

08

References and copying

Two array variables can refer to one object; copy when a separate mutable array is required.

import java.util.*;
public class Main {
    public static void main(String[] args) {
        int[] first = {1, 2};
        int[] second = first.clone();
        second[0] = 9;
        System.out.println(Arrays.toString(first) + " " + Arrays.toString(second));
    }
}

Output: [1, 2] [9, 2]

09

Classes or structs

A node class models the fields that connect linked lists and trees.

public class Main {
    static class Node { int value; Node(int value) { this.value = value; } }
    public static void main(String[] args) {
        System.out.println(new Node(7).value);
    }
}

Output: 7

10

Sorting with a custom comparator

Comparator.comparing and lambdas express ordering for records and intervals.

import java.util.*;
public class Main {
    public static void main(String[] args) {
        List<String> words = new ArrayList<>(List.of("bbb", "a"));
        words.sort(Comparator.comparingInt(String::length));
        System.out.println(words);
    }
}

Output: [a, bbb]

11

Reading input

BufferedReader or a token reader handles judge input more efficiently than Scanner for large input.

import java.io.*;
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int a = Integer.parseInt(reader.readLine());
        int b = Integer.parseInt(reader.readLine());
        System.out.println(a + b);
    }
}

Input: 2 4

Output: 6

Java toolbox for data structures

StructureJava typeKey operations
Dynamic arrayArrayListadd at end amortized O(1); get O(1)
String buildingStringBuilderappend pieces, then toString
Hash mapHashMapget/put O(1) average
Hash setHashSetadd/contains O(1) average
StackArrayDequepush/pop at the front
QueueArrayDequeoffer/poll at the ends
DequeArrayDequeadd/remove at both ends
Priority queuePriorityQueueoffer/poll min-heap by default
Ordered mapTreeMapordered get/put O(log n)
SortingArrays.sort / List.sortcomparator for objects

The order to learn DSA

Follow the SDE roadmap order. Each topic starts with two Easy problems from the curated set.

Ready to move on when you can solve both without looking at a solution.

Ready to move on when you can solve both without looking at a solution.

Ready to move on when you can solve both without looking at a solution.

Java mistakes that cost people in DSA

Letting int overflow

Java int is 32-bit and overflows silently. Use long for sums, products and counts that can exceed that range.

Using the legacy Stack class

Prefer ArrayDeque for stack behavior. It is the modern deque implementation for push and pop operations.

Assuming PriorityQueue is a max-heap

PriorityQueue is a min-heap by default. Pass Comparator.reverseOrder() for max-first behavior.

Comparing strings with ==

== compares references. Use .equals for string content, and StringBuilder when constructing many pieces.

Expecting every Arrays.sort to be stable

Arrays.sort on primitives is not stable; the object overload is stable. Pick the overload with that distinction in mind.

Recursing without a depth plan

Deep recursion can throw StackOverflowError. Convert the traversal to an explicit stack when depth is not bounded.

DSA in Java: questions, answered

Should I use Scanner for DSA input in Java?

Scanner is convenient for small examples. BufferedReader with a token parser is usually the safer choice when input is large.

How do I make a max-heap in Java?

Construct PriorityQueue with Comparator.reverseOrder(). Its default ordering is a min-heap.

Why use long in Java DSA solutions?

int is 32-bit and overflow wraps silently. Use long when a sum, product or count can exceed the int range.