Skip to content

Latest commit

Β 

History

History
571 lines (443 loc) Β· 16.1 KB

File metadata and controls

571 lines (443 loc) Β· 16.1 KB

Java Problem Solving Guide πŸš€

Table of Contents

  1. Overview
  2. Practice Package (org.mjtech.pratice)
  3. String Processing Package (org.mjtech.string)
  4. Number Processing Package (org.mjtech.number)
  5. Stream API Package (org.mjtech.stream)
  6. Algorithms Package (org.mjtech.algorithms)
  7. Design Patterns Package (org.mjtech.patterns)
  8. Concurrency Package (org.mjtech.concurrency)
  9. Core Java QA Packages
  10. Best Practices and Tips

Overview

This comprehensive guide covers Java problem-solving approaches across multiple domains, from basic programming concepts to advanced design patterns and concurrency. Each package is organized by specific problem categories with practical examples and multiple solution approaches.

Problem Difficulty Levels

  • 🟒 Beginner: Basic syntax and concepts
  • 🟑 Intermediate: Algorithmic thinking and data structures
  • πŸ”΄ Advanced: Complex algorithms, design patterns, and optimization

Practice Package (org.mjtech.pratice)

🎯 Purpose: Comprehensive problem-solving with real-world scenarios

Problems Covered:

1. Employee Data Processing 🟑

Problem Statement: Process employee data using various operations like sorting, filtering, and aggregation.

Approach:

// Sample Employee Data
List<Employee> employees = List.of(
    new Employee("Jafar", "DEV", 10_000, 26),
    new Employee("Karthik", "DEV", 30_000, 29),
    new Employee("Ismail", "MAG", 50_000, 30)
);

Key Techniques:

  • Sorting: Comparator.comparingDouble(Employee::salary)
  • Filtering: stream().filter(emp -> emp.age() > 30)
  • Grouping: Collectors.groupingBy(Employee::dept)
  • Aggregation: Collectors.averagingDouble(Employee::salary)

Sample Solutions:

  • Find Nth highest salary: sorted().skip(n-1).limit(1)
  • Department-wise average: groupingBy(dept, averagingDouble(salary))
  • Age-based filtering: filter(emp -> emp.age() > threshold)

2. Number Array Operations 🟑

Problem Statement: Find patterns, duplicates, and perform mathematical operations on number arrays.

Approach:

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 10, 8, 9, 10);

// Find second largest (Stream approach)
numbers.stream()
    .distinct()
    .sorted(Comparator.reverseOrder())
    .skip(1)
    .limit(1)
    .findFirst();

// Traditional approach
int first = Integer.MIN_VALUE, second = Integer.MIN_VALUE;
for (int num : array) {
    if (num > first) {
        second = first;
        first = num;
    } else if (num > second && num != first) {
        second = num;
    }
}

3. String Analysis 🟑

Problem Statement: Analyze text for character frequency, word patterns, and text processing.

Key Techniques:

  • Character Frequency: chars().collect(groupingBy(identity(), counting()))
  • Case Handling: toLowerCase() for consistent processing
  • Pattern Matching: Regular expressions for complex patterns

4. Map Operations 🟑

Problem Statement: Work with key-value pairs for ranking, filtering, and transformation.

Sample Code:

Map<String, Integer> languages = Map.of(
    "Java", 50, "Python", 150, "JavaScript", 200
);

// Top N languages by score
String topLanguages = languages.entrySet().stream()
    .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
    .limit(3)
    .map(Map.Entry::getKey)
    .collect(Collectors.joining(", "));

String Processing Package (org.mjtech.string)

🎯 Purpose: Comprehensive string manipulation and analysis

Problem Categories:

1. Character Frequency Analysis 🟒

Problem Statement: Count occurrences of characters in strings with various encoding schemes.

Approaches:

Traditional Method:

Map<Character, Integer> frequencyMap = new HashMap<>();
for (char c : input.toCharArray()) {
    frequencyMap.put(c, frequencyMap.getOrDefault(c, 0) + 1);
}

Stream API Method:

Map<Character, Long> frequency = input.chars()
    .mapToObj(c -> (char) c)
    .collect(Collectors.groupingBy(
        Function.identity(), 
        LinkedHashMap::new, 
        Collectors.counting()
    ));

2. Run-Length Encoding 🟑

Problem Statement: Compress strings by representing consecutive identical characters as character + count.

Example: "aaabbccccaa" β†’ "a3b2c4a2"

Implementation:

public static String runLengthEncoding(String input) {
    StringBuilder result = new StringBuilder();
    int count = 1;
    
    for (int i = 0; i < input.length() - 1; i++) {
        if (input.charAt(i) == input.charAt(i + 1)) {
            count++;
        } else {
            result.append(input.charAt(i)).append(count).append(" ");
            count = 1;
        }
    }
    result.append(input.charAt(input.length() - 1)).append(count);
    return result.toString();
}

3. String Expansion 🟑

Problem Statement: Expand compressed strings where numbers indicate repetition count.

Example: "s3m4A4" β†’ "sssmmmAAAA"

Key Techniques:

  • Character parsing with Character.isAlphabetic() and Character.isDigit()
  • Multi-digit number handling
  • String repetition with String.repeat(count)

4. Advanced String Problems πŸ”΄

  • Palindrome Detection: Case-insensitive with special character handling
  • Anagram Check: Character frequency comparison
  • Longest Substring Without Repeating Characters: Sliding window technique
  • First Non-Repeating Character: LinkedHashMap for insertion order

Number Processing Package (org.mjtech.number)

🎯 Purpose: Number theory, digit manipulation, and mathematical algorithms

Problem Categories:

1. Digit Sorting Operations 🟑

Problem Statement: Sort digits within numbers in ascending or descending order.

Multiple Approaches:

Traditional Array Sorting:

public static int sortDigitsAscending(int number) {
    char[] digits = String.valueOf(number).toCharArray();
    Arrays.sort(digits);
    return Integer.parseInt(String.valueOf(digits));
}

Stream API Approach:

public static int sortDigitsWithStreams(int number) {
    String sorted = String.valueOf(number).chars()
        .sorted()
        .mapToObj(c -> String.valueOf((char) c))
        .collect(Collectors.joining());
    return Integer.parseInt(sorted);
}

2. Number Analysis 🟑

Problem Statement: Extract meaningful information from numbers.

Key Operations:

  • Min/Max Digits: chars().map(Character::getNumericValue).min()/max()
  • Digit Frequency: Character counting with TreeMap for sorted output
  • Unique Digit Check: distinct().count() == length
  • Number Reversal: StringBuilder reverse

3. Array Number Operations πŸ”΄

Problem Statement: Sort and analyze arrays based on number properties.

Advanced Techniques:

// Sort by digit sum
public static int[] sortArrayByDigitSum(int[] numbers) {
    return Arrays.stream(numbers)
        .boxed()
        .sorted(Comparator.comparingInt(NumberSort::calculateDigitSum))
        .mapToInt(Integer::intValue)
        .toArray();
}

// Calculate digit sum
public static int calculateDigitSum(int number) {
    return String.valueOf(Math.abs(number)).chars()
        .map(Character::getNumericValue)
        .sum();
}

4. Special Number Types πŸ”΄

Problem Statement: Identify numbers with special mathematical properties.

Implementations:

Armstrong Numbers:

public static boolean isArmstrongNumber(int number) {
    String numStr = String.valueOf(number);
    int numDigits = numStr.length();
    
    int sum = numStr.chars()
        .map(Character::getNumericValue)
        .map(digit -> (int) Math.pow(digit, numDigits))
        .sum();
    
    return sum == number;
}

Perfect Numbers: Sum of proper divisors equals the number Happy Numbers: Digit square sum eventually reaches 1 Prime Numbers: Sieve of Eratosthenes for efficient generation


Stream API Package (org.mjtech.stream)

🎯 Purpose: Mastering Java 8+ Stream API operations

Problem Levels:

1. Easy Stream Problems 🟒

Focus: Basic stream operations and transformations

Sample Problems:

  • Group strings by length
  • Find duplicates in collections
  • Convert to uppercase
  • Filter and sum operations
  • Character frequency counting

Key Patterns:

// Grouping pattern
Map<Integer, List<String>> grouped = strings.stream()
    .collect(Collectors.groupingBy(String::length));

// Filtering and collecting
List<String> duplicates = list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet().stream()
    .filter(entry -> entry.getValue() > 1)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

2. Medium Stream Problems 🟑

Focus: Complex aggregations and multi-step operations

Advanced Patterns:

  • Nested Grouping: Department and age-based grouping
  • Partitioning: Split data based on predicates
  • Custom Collectors: Specialized collection strategies
  • Statistical Operations: Average, max, min with grouping

Complex Example:

// Multi-level grouping and aggregation
Map<String, Double> avgSalaryByDept = employees.stream()
    .collect(Collectors.groupingBy(
        Employee::dept, 
        Collectors.averagingDouble(Employee::salary)
    ));

3. Hard Stream Problems πŸ”΄

Focus: Complex business logic with streams

Advanced Scenarios:

  • Moving Averages: Sliding window calculations
  • Complex Filtering: Multi-criteria filtering with all/any conditions
  • Data Transformation: Flat mapping and complex projections

Algorithms Package (org.mjtech.algorithms)

🎯 Purpose: Fundamental computer science algorithms and data structures

Core Categories:

1. Array Algorithms 🟑

Essential Problems:

Two Sum Problem:

public static int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement)) {
            return new int[]{map.get(complement), i};
        }
        map.put(nums[i], i);
    }
    return new int[0];
}

Maximum Subarray (Kadane's Algorithm):

public static int maxSubarraySum(int[] nums) {
    int maxSoFar = nums[0];
    int maxEndingHere = nums[0];
    
    for (int i = 1; i < nums.length; i++) {
        maxEndingHere = Math.max(nums[i], maxEndingHere + nums[i]);
        maxSoFar = Math.max(maxSoFar, maxEndingHere);
    }
    return maxSoFar;
}

2. Stack and Queue Problems 🟑

Key Concepts:

  • Balanced Parentheses: Stack-based validation
  • Next Greater Element: Monotonic stack technique
  • Queue using Stacks: Dual-stack implementation

3. Sorting and Searching πŸ”΄

Fundamental Algorithms:

Merge Sort Implementation:

  • Time Complexity: O(n log n)
  • Space Complexity: O(n)
  • Stable sorting algorithm

Binary Search:

  • Time Complexity: O(log n)
  • Prerequisite: Sorted array

Quick Sort:

  • Average Time: O(n log n)
  • Worst Case: O(nΒ²)
  • In-place sorting

Design Patterns Package (org.mjtech.patterns)

🎯 Purpose: Essential design patterns for robust software architecture

Pattern Categories:

1. Creational Patterns 🟑

Singleton Pattern:

public class DatabaseConnection {
    private static volatile DatabaseConnection instance;
    private static final Object lock = new Object();
    
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            synchronized (lock) {
                if (instance == null) {
                    instance = new DatabaseConnection();
                }
            }
        }
        return instance;
    }
}

Builder Pattern:

  • Flexible object construction
  • Method chaining
  • Immutable object creation

Factory Pattern:

  • Object creation abstraction
  • Type-based instantiation

2. Structural Patterns 🟑

Adapter Pattern: Interface compatibility Decorator Pattern: Dynamic behavior addition Observer Pattern: Event notification system

3. Behavioral Patterns πŸ”΄

Strategy Pattern: Algorithm family encapsulation Command Pattern: Request encapsulation Template Method: Algorithm skeleton definition


Concurrency Package (org.mjtech.concurrency)

🎯 Purpose: Multi-threading and concurrent programming mastery

Concurrency Topics:

1. Basic Threading 🟑

Thread Creation and Management:

// Thread creation approaches
Thread thread1 = new Thread(() -> {
    // Task implementation
});

// ExecutorService approach
ExecutorService executor = Executors.newFixedThreadPool(3);
Future<Integer> result = executor.submit(() -> {
    return computeValue();
});

2. Synchronization πŸ”΄

Race Condition Prevention:

  • Synchronized methods: Method-level synchronization
  • Atomic operations: Lock-free programming
  • ReadWrite locks: Concurrent read access

3. Advanced Concurrency πŸ”΄

Producer-Consumer Problem:

BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);

// Producer
queue.put(item); // Blocks if queue is full

// Consumer
int item = queue.take(); // Blocks if queue is empty

Dining Philosophers: Deadlock prevention strategies


Core Java QA Packages

BNP Package (org.mjtech.bnp)

  • Method Overloading: Parameter type resolution
  • Employee Processing: Data aggregation patterns
  • Singleton Implementation: Thread-safe instantiation

PCL Package (org.mjtech.pcl)

  • Character Frequency: Traditional vs Stream approaches
  • TreeMap Usage: Sorted output generation

Company-Specific Packages

  • Incedo: Top N elements selection
  • TVS: Duplicate separation algorithms
  • J2V: Employee service patterns

Best Practices and Tips

πŸ”§ Performance Optimization

  1. Stream vs Traditional Loops:

    • Streams for readability
    • Traditional loops for performance-critical code
  2. Memory Management:

    • Use appropriate collection sizes
    • Consider primitive collections for large datasets
  3. Concurrency Best Practices:

    • Prefer concurrent collections
    • Use thread-safe operations
    • Avoid nested locks

πŸ“š Learning Path Recommendations

Beginner Level:

  1. Start with string and number packages
  2. Master basic Stream API operations
  3. Understand fundamental algorithms

Intermediate Level:

  1. Deep dive into algorithms package
  2. Learn design patterns
  3. Practice complex Stream operations

Advanced Level:

  1. Master concurrency concepts
  2. Implement custom solutions
  3. Optimize for performance

🎯 Interview Preparation

Common Interview Topics:

  1. Data Structures: Arrays, Lists, Maps, Sets
  2. Algorithms: Sorting, searching, dynamic programming
  3. Object-Oriented Design: SOLID principles, design patterns
  4. Concurrency: Thread safety, deadlock prevention
  5. Stream API: Complex transformations and aggregations

Practice Strategy:

  1. Implement each problem multiple ways
  2. Analyze time and space complexity
  3. Practice explaining your approach
  4. Handle edge cases and error conditions

Conclusion

This guide provides a comprehensive foundation for Java problem-solving across multiple domains. Each package builds upon previous concepts, creating a structured learning path from basic programming to advanced software engineering principles.

πŸ“ˆ Next Steps:

  1. Implement each problem in multiple ways
  2. Focus on understanding the underlying concepts
  3. Practice with real-world scenarios
  4. Contribute additional problems and solutions

πŸ”— Related Topics for Further Study:

  • Spring Framework patterns
  • Database connectivity and JPA
  • RESTful API design
  • Microservices architecture
  • Performance tuning and profiling

Happy Coding! πŸš€