Data Structures and Algorithms (DSA) in Java. This repository is a collection of my self-study projects in DSA, where I explore and implement various algorithms and data structures independently. I am a BCA student pursuing this as a personal learning effort, beyond my college curriculum. Authored by Azharuddin Ali
Completed 13 pattern printing programs in Java, including triangles, rectangles, pyramids, hollow shapes, and a butterfly pattern. These programs focused on nested loops, conditionals, and symmetry concepts. Added all files to the day1 folder in the Git repo with clear naming conventions for easy reference.
focused on strengthening problem-solving skills through array-based questions, patterns, and basic algorithm implementations. We started with pattern problems to enhance logical thinking using nested loops, followed by exploring functions with different parameter and return type combinations to understand their behavior in Java. Number system conversions (binary to decimal and vice versa) deepened our understanding of modular arithmetic. We also explored parameter passing in Java, differentiating between pass-by-value and pass-by-reference using array modifications. Searching algorithms like linear and binary search introduced the basics of element lookup. Array manipulation tasks included reversing arrays (both normally and memory-efficiently), finding the largest and smallest elements, generating pairs, and working with subarrays. Optimization problems like maximum subarray sum and trapping rainwater introduced performance considerations and auxiliary data structures. We concluded with a dummy stock trading problem, calculating maximum profit by identifying optimal buy and sell days. The day provided a comprehensive foundation in arrays and problem-solving logic, preparing us for more advanced challenges.
Today, I worked on a series of 13 Java programs, covering various essential concepts like user-defined packages, method overloading, constructor overloading, applets, and virtual environments. I started by creating a user-defined package to better organize classes, followed by setting up a virtual environment to run applets, ensuring the programs run smoothly without interfering with the system configuration. I explored method overloading, where I created multiple methods with the same name but different parameters to handle various input types. I also worked on constructor overloading by defining multiple constructors in a class to initialize objects in different ways. I implemented multithreading with three threads (A, B, and C) running concurrently to perform different tasks. Additionally, I practiced exception handling, managing errors such as array index out-of-bounds, and demonstrated method overriding and inheritance by creating subclasses that provide specific implementations of methods from the parent class. I also worked on single-level inheritance, where one class extended another to inherit its properties and methods. I manipulated strings using various methods like indexOf, substring, toLowerCase, and replace, and sorted an array using the bubble sort algorithm. I wrote programs to calculate the factorial of numbers and check if they are prime, using command-line arguments for input.
For my environment setup, I used a virtual workspace to ensure a clean and isolated environment for running applets and other Java programs. The workspace is configured with all necessary Java tools and libraries, and I created a dedicated folder structure for organizing my projects. I used an IDE (Integrated Development Environment) to write, compile, and test my code efficiently. By leveraging version control with Git and uploading my work to GitHub, I ensured my code was properly tracked and easily accessible for review and collaboration. This setup allowed me to work with different Java features and ensured that the applet and virtual environment ran seamlessly, keeping everything organized and functional.
On Day 4, we focused on developing sorting algorithms and related concepts to strengthen our understanding of data manipulation and algorithm efficiency. The session started with the implementation of the bubble sort algorithm, followed by selection sort and insertion sort, which provided insight into different sorting techniques.
We then explored the use of in-built functions to sort arrays, emphasizing Java's utility libraries. The session concluded with the implementation of the counting sort algorithm, which introduced a non-comparative sorting approach.
Today, I worked on 2D arrays in Java. I implemented basic input/output operations, searched for elements in unsorted and sorted matrices, found the largest and smallest elements, calculated diagonal sums, and traversed a spiral matrix. I also optimized search in a sorted matrix using a top-right corner approach. These programs improved my understanding of 2D array operations and algorithms.
On Day 6, we focused on solving various string-related problems using Java, enhancing our understanding of string manipulation and logic-building. We began with a program demonstrating essential string operations such as finding length, comparing strings (both case-sensitive and case-insensitive), extracting substrings, replacing characters, and concatenating strings. Next, we checked whether a given string is a palindrome using a two-pointer approach. Moving forward, we tackled a problem to compute the shortest path to a destination based on directional instructions. Additionally, we found the largest string lexicographically from a given set of strings using the compareTo() method. We also implemented a program to capitalize the first letter of each word in a string while preserving the remaining text. Lastly, we created a string compression program that replaces consecutive occurrences of characters with their counts, providing a more compact representation. These exercises improved our problem-solving skills and deepened our understanding of Java's string handling capabilities.
Today is Day 7 of my DSA journey, and I started learning Bit Manipulation. In this, I explored various bitwise operations and their applications in problem-solving. I began with basic bitwise operators (&, |, ^, ~, <<, >>), which are essential for bitwise calculations. Then, I implemented a program to check if a number is odd or even using the bitwise AND operator. Next, I worked on retrieving, setting, and clearing a specific bit (i-th bit) using bitwise shifting and masking techniques. After that, I implemented updating a specific bit by first clearing it and then setting it to a new value. I also learned how to clear the last i bits and clear a range of bits from i to j, which are useful for modifying specific parts of a binary number. Then, I implemented a program to check if a given number is a power of 2 using the property (n & (n-1)) == 0. After that, I wrote a program to count the number of set bits (1s) in a binary representation, which is useful in various bitwise algorithms. Finally, I learned Fast Exponentiation, a powerful technique to compute a^n efficiently in O(log n) time using bitwise operations.
Overall, today’s learning was insightful, and bit manipulation seems like a powerful tool for optimizing DSA problems.