Problem Statement: Write a function that reverses a string. The input string is given as an array of characters s. You must do this by modifying the input array in-place with O(1) extra memory. (LeetCode 344) Solution: So the approach I have applied in this problem is very very simple. We initialize a pointer start with 0 and another pointer end with ch.length-1, the start pointer points to first position of the array at the beginning and the end pointer points to the end of the array at the beginning . We swap the elements at start position with the element at end position and then we do start++ and end-- to move the start pointer to the next position and end pointer to the previous position (the second last position in the second iteration, third last in the third iteration and so on). We continue iteration until the condition (start <= end) fails. This simply reverse the array with character elements. Time Complexity : O(n) Space Complexity: O(1) Below is the Java Code for the following problem: public static void reverse(char []ch) { int start = 0; int end = ch.length-1; while(start <= end) { char temp = ch[start]; ch[start] = ch[end]; ch[end] = temp; start ++; end --; } }
Reverse String in-place with O(1) extra memory
More Relevant Posts
-
𝐓𝐡𝐢𝐬 𝐜𝐨𝐝𝐞 𝐬𝐧𝐢𝐩𝐩𝐞𝐭 𝐢𝐬 𝐞𝐧𝐨𝐮𝐠𝐡 𝐭𝐨 𝐜𝐨𝐧𝐟𝐮𝐬𝐞 𝐬𝐨𝐦𝐞𝐨𝐧𝐞 𝐰𝐢𝐭𝐡 𝐉𝐚𝐯𝐚. 😁 Let me introduce you to the concept of wrapper classes and autoboxing first. 𝐖𝐑𝐀𝐏𝐏𝐄𝐑 𝐂𝐋𝐀𝐒𝐒𝐄𝐒: These are classes used to wrap primitive values so we can treat them like objects. This is essential for the Collection framework (like ArrayList), which only works with objects. 𝐀𝐔𝐓𝐎𝐁𝐎𝐗𝐈𝐍𝐆: The process of converting primitive values to wrapper objects is implicit. We don't need the new keyword. Now let's discuss the code: 𝐂𝐎𝐃𝐄 1: 𝘪𝘯𝘵 𝘢 = 100; 𝘪𝘯𝘵 𝘣 = 100; These are primitive values. For primitives, the == operator compares the actual values. Since both are 100, the output is 𝐭𝐫𝐮𝐞. 𝐂𝐎𝐃𝐄 2: Integer wrapper classes have an Integer Cache. By default, Java caches all Integer objects in the range of -128 to 127. 𝘐𝘯𝘵𝘦𝘨𝘦𝘳 𝘱 = 100; 𝘐𝘯𝘵𝘦𝘨𝘦𝘳 𝘲 = 100; Since 100 is in the cache, Java points both variables to the same object memory location. The output is 𝐭𝐫𝐮𝐞. 𝐂𝐎𝐃𝐄 3: 𝘐𝘯𝘵𝘦𝘨𝘦𝘳 𝘺 = 128; 𝘐𝘯𝘵𝘦𝘨𝘦𝘳 𝘻 = 128; Because 128 is outside the cache range, Java creates two distinct objects in memory. Since == compares memory references for objects, the output is 𝐟𝐚𝐥𝐬𝐞. ~Anuprash Gautam 🍵 𝘒𝘦𝘦𝘱 𝘭𝘦𝘢𝘳𝘯𝘪𝘯𝘨 𝘢𝘯𝘥 𝘣𝘳𝘦𝘸𝘪𝘯𝘨 𝘤𝘰𝘧𝘧𝘦𝘦.😊 #Java #programming #autoboxing #oops
To view or add a comment, sign in
-
-
Let’s have some fun : product(bool, DontCompileHugeMethods, true, \ "Do not compile methods > HugeMethodLimit") \ \ develop(intx, HugeMethodLimit, 8000, \ "Don't compile methods larger than this if " \ "+DontCompileHugeMethods") What is this 🧐 ? These are some compiler configurations from hotspot/share/compiler/compiler_globals.hpp. What do they stand for? They basically say that if your method has more than 8000 bytes of bytecode, it is no longer eligible for compiling. let’s try to get an approximation of how much 8000 bytes of bytecode is : As far as I know, each bytecode instruction ranges from 1 to 5 bytes in size (probably more in some cases). Let’s go with an average of 3 bytes per instruction: 8000/3 ~= 2666 bytecode instructions However, mapping Java instructions to bytecode instructions is hard and highly variable, but usually a Java instruction boils down to one or more bytecode instructions, let’s say 4 on average : 2666 bytecode instructions/4 = 666 instructions ”line” of Java code. Which means if you write more than 666 lines of code in your hot methods, they will rot in the interpreter 😹 , which is sloooooowwww as hell, and they will never get the honor of meeting the JIT. So don't write 666 lines methods 😂 Safe harbor: This is just a playground, don’t take these computations for granted! #HotspotVM
To view or add a comment, sign in
-
🚀 𝗔𝗿𝗿𝗮𝘆𝗟𝗶𝘀𝘁 𝘃𝘀 𝗟𝗶𝗻𝗸𝗲𝗱𝗟𝗶𝘀𝘁 — 𝗪𝗵𝗶𝗰𝗵 𝗢𝗻𝗲 𝗦𝗵𝗼𝘂𝗹𝗱 𝗪𝗲 𝗨𝘀𝗲? While revising the Java Collection Framework, I realized something important. We often use ArrayList by default. But do we really understand when to use LinkedList instead? Both implement the List interface, but internally they are completely different. 🔹 𝗔𝗿𝗿𝗮𝘆𝗟𝗶𝘀𝘁 ArrayList is backed by a dynamic array. That means: • Accessing elements using index is very fast • But inserting or deleting in the middle requires shifting elements So it works best when: ✔ We mostly read data ✔ Random access is frequent 🔹 𝗟𝗶𝗻𝗸𝗲𝗱𝗟𝗶𝘀𝘁 LinkedList is backed by a doubly linked list. That means: • Insertion and deletion are faster • Accessing elements by index is slower So it works best when: ✔ We frequently add/remove elements ✔ We modify data often 𝗦𝗶𝗺𝗽𝗹𝗲 𝗖𝗼𝗱𝗲 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 ->List<Integer> list1 = new ArrayList<>(); ->List<Integer> list2 = new LinkedList<>(); Same interface. Different internal working. Different performance behavior. 💡 𝗪𝗵𝗮𝘁 𝗜 𝗟𝗲𝗮𝗿𝗻𝗲𝗱 Choosing the right data structure is not about syntax. It’s about understanding the use case. The more I revise Collections, the more I realize that fundamentals matter more than memorizing methods. #Java #CollectionFramework #ArrayList #LinkedList #Programming #DSA #LearningJourney
To view or add a comment, sign in
-
-
𝐃𝐚𝐲 𝟗 – 𝐑𝐞𝐯𝐢𝐬𝐢𝐭𝐢𝐧𝐠 𝟐-𝐃 𝐀𝐫𝐫𝐚𝐲𝐬 𝐢𝐧 𝐉𝐚𝐯𝐚 One important realization: 👉 In Java, a 2-D array is NOT actually a “matrix”. It is an array of arrays. That means: Each row is a separate array object. Rows can have different lengths. Memory is not necessarily continuous like in C/C++ Example: int[][] arr = new int[3][]; arr[0] = new int[2]; arr[1] = new int[4]; arr[2] = new int[3]; This is called a 𝑱𝒂𝒈𝒈𝒆𝒅 𝑨𝒓𝒓𝒂𝒚. Many beginners assume: arr.length == total elements ❌ But actually: arr.length → number of rows arr[i].length → number of columns in that specific row This small understanding prevents many traversal bugs. The deeper you understand memory structure, the cleaner your logic becomes. 🔹 Beginner Level 2-D Array Problems : These are simple but build strong fundamentals. 1️⃣ Print a 2D array----> Traverse and print all elements. 2️⃣ Find the sum of all elements 3️⃣ Row-wise sum-----> Print sum of each row separately. 4️⃣ Column-wise sum---->This helps understand traversal direction change. 5️⃣ Find the largest element----> Simple scanning problem. #Java #DataStructures #LearningInPublic #dailyChallenge
To view or add a comment, sign in
-
🔹 Problem 1: Second Smallest Element in an Array 📌 Input: Integer n (size of array), Array of n elements 📌 Output: Second smallest element in the array 🧠 Algorithm Steps: 1. Read the array elements. 2. Assume first element as first_min and second element as second_min. 3. If first_min is greater than second_min, swap them. 4. Traverse the array from index 2. 5. If current element < first_min → second_min = first_min and first_min = current element. 6. Else if current element > first_min and < second_min → update second_min. 7. If both minimum values are equal, print "No second smallest element", otherwise print second_min. 💡 Example: Input: [5, 2, 8, 1, 3] Output: 2 🔹 Problem 2: First Non-Repeating Character in a String 📌 Input: String s 📌 Output: First character that appears only once 🧠 Algorithm Steps: 1. Read the string. 2. Traverse each character. 3. For each character, count its frequency using another loop. 4. If count == 1, print that character and stop. 5. If no such character found, print -1. 💡 Example: Input: "swiss" Output: w 🔹 Problem 3: Hashad Number 📌 Input: Integer n 📌 Output: Check whether the number is Hashad or not 🧠 Algorithm Steps: 1. Store original number. 2. Find sum of digits using loop. 3. Check if original number % sum == 0. 4. If true, print "Hashad Number". 5. Otherwise, print "Not Hashad Number". 💡 Example: Input: 18 Output: Hashad Number Consistent practice of these problems is helping me improve my logical thinking, loop handling, and core Java fundamentals. 🚀 #Java #CodingPractice #ProblemSolving #CoreJava #LearningJourney
To view or add a comment, sign in
-
-
Stop writing boilerplate. Let the compiler do the heavy lifting. In modern Java, you can replace a verbose data class with a single line: public record Car(String name) {} Behind the scenes, Java automatically generates: ✅ Private final fields (Immutability by default). ✅ Canonical constructor (State initialization). ✅ Accessor methods (e.g., car.name()). ✅ equals() and hashCode() (Value-based equality). ✅ toString() (Readable output). // What the JVM actually sees: public final class Car extends java.lang.Record { privatefinal String name; public Car(String name) { this.name = name; } public String name() { returnthis.name; } @Overridepublic boolean equals(Object o) { ... } @Overridepublic int hashCode() { ... } @Overridepublic String toString() { ... } } The Result? Cleaner code, fewer bugs, and zero "boilerplate fatigue." Are you still using traditional POJOs, or have you switched to Records? 👇 #Java #CleanCode #SoftwareEngineering #ProgrammingTips #ModernJava
To view or add a comment, sign in
-
In CTCI Book | Question 2.5, there is a follow-up to the problem discussed in my previous post. We are given two linked lists where the digits are stored in forward order, and we must return their sum as a linked list. Example: 5 -> 4 -> 7 7 -> 4 This problem is more challenging than the reverse-order version. When the digits are stored in reverse order, you can simply add the numbers as you traverse the lists from head to tail. However, when the digits are in forward order, you must process the lists from the end, which naturally leads to a recursive solution that behaves like a stack. Approach 1. Check the lengths of the two lists. 2. Pad the shorter list with zeros so that both lists have equal length. This makes the addition easier to handle. 3. Recursively perform the addition using a helper function addLists, which processes the nodes from the tail to the head. 4. Return the resulting list, handling any remaining carry at the end. NB: PartialSum is a clever way to return two values from the recursive function. Since Java methods can return only one object, PartialSum acts as a wrapper that contains: - the resulting node - the carry value generated during addition This allows the recursive calls to propagate both pieces of information up the call stack. Time Complexity: O(n) | Space Complexity: O(n) - due to the recursion stack.
To view or add a comment, sign in
-
-
🚀 Understanding Arrays in Java – Strengths & Drawbacks 📍Arrays are one of the most fundamental data structures in Java. They allow us to store multiple values under a single variable name, making code cleaner and more efficient. But like every tool, arrays come with limitations that every developer should know. 🔑 Key Points: 📌Homogeneous Data Only: Arrays can store only one type of data (e.g., all integers, all strings). 📌Fixed Size: Once declared, the size of an array cannot be changed. Adding or removing elements dynamically isn’t possible. 📌Contiguous Memory Requirement: Arrays need continuous memory blocks. If RAM cannot allocate enough contiguous space, array creation may fail. 📌 Real-Time Example: Imagine you’re building an online shopping cart system. If you use an array to store items, you must decide the cart size in advance (say 10 items). What if a customer wants to add the 11th item? ❌ The array won’t allow it. Also, you can’t mix data types (e.g., product name + price + quantity) in a single array. 👉 That’s why developers often prefer ArrayLists or Collections in Java, which overcome these limitations by allowing dynamic resizing and heterogeneous data storage. 💡 Takeaway: Arrays are great for fixed-size, homogeneous data storage, but for real-world applications where flexibility is key, Collections are the way forward. TAP Academy #Java #CoreJava #ProgrammingBasics #JavaDeveloper #LearningJourney #SoftwareDevelopment #Coding
To view or add a comment, sign in
-
✨ Good day.... Developers! Creating and traversing arrays is important… But how do we find an element inside an array? 🤔 That’s where Searching comes in 🔍 1️⃣ Linear Search (Sequential Search) 👉 Checks each element one by one 👉 Works on both sorted & unsorted arrays int[] arr = {10, 20, 30, 40}; int key = 30; for(int i = 0; i < arr.length; i++){ if(arr[i] == key){ System.out.println("Element found at index: " + i); break; } } ==> ⏱ Time Complexity: O(n) ✔ Simple ✔ Beginner-friendly ✔ No sorting required 2️⃣ Binary Search 👉 Works only on sorted arrays 👉 Divides the array into halves import java.util.Arrays; int[] arr = {10, 20, 30, 40, 50}; int key = 30; int index = Arrays.binarySearch(arr, key); System.out.println("Element found at index: " + index); ==> ⏱ Time Complexity: O(log n) ✔ Faster than linear search ✔ Requires sorted data 🔥 Interview Insight 📌 When array is small → Linear search is fine 📌 When array is large & sorted → Binary search is better 📌 Binary search on unsorted array → ❌ Wrong logic #Java #DSA #Programming #CodingInterview #LearningJourney #SoftwareDevelopment
To view or add a comment, sign in
-
-
The Hidden Mechanism Behind ThreadLocal in Java ThreadLocal is often explained simply as: “Data stored per thread.” That’s true — but the interesting part is how it actually works internally. Most developers think the data lives inside ThreadLocal. It doesn’t. How ThreadLocal Works Internally Each Thread object maintains its own internal structure: Thread └── ThreadLocalMap ├── ThreadLocal → Value ├── ThreadLocal → Value The important detail: The map belongs to the Thread, not to ThreadLocal. ThreadLocal simply acts as a key. Basic Flow When you call: ThreadLocal.set(value) Internally: Copy code thread = currentThread map = thread.threadLocalMap map.put(ThreadLocal, value) When you call: ThreadLocal.get() It retrieves the value from the current thread’s map. Each thread therefore has its own independent copy. Where This Is Used in Real Systems You’ll find ThreadLocal used in many frameworks: • Spring Security → SecurityContextHolder • Transaction management → TransactionSynchronizationManager • Logging correlation IDs • Request scoped context It allows frameworks to store request-specific data without passing it through every method. The Hidden Danger If you forget to call: Copy code ThreadLocal.remove() You can create memory leaks. Why? Because thread pools reuse threads. Old values may remain attached to long-lived threads. ThreadLocal is simple conceptually. But its internal design is what makes many Java frameworks work efficiently. Have you used ThreadLocal in production code? #Java #CoreJava #Multithreading #ThreadLocal #SpringBoot #BackendEngineering #InterviewPreparation
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development