Returning array
In Java, the shorthand array initializer syntax ({...}) is restricted by the language grammar to variable declarations only.
Why Assignment Works
When you write:
int[] arr = {-1, -1};This is a variable declaration with initialization. The Java compiler uses the type declared on the left side (int[]) to understand and build the array directly from the shorthand curly braces.
Why Return (and Later Assignment) Fails
If you try to write:
return {-1, -1}; // Compile erroror
int[] arr;
arr = {-1, -1}; // Compile errorExpression
Java’s grammar does not treat
{...}as a standalone expression. It only recognizes it during initial declaration. Because areturnstatement expects a full expression, the compiler throws a syntax error.
The Role of new int[]
Using new int[]{-1, -1} explicitly creates an anonymous array expression. Because it is a valid expression, Java can evaluate it anywhere an expression is expected—including inside a return statement or a late assignment.
Returning after assigning
return int[] arr = {-1, -1}; causes a compile-time syntax error in Java.
Why It Fails
- Expressions vs. Statements: A
returnstatement expects an expression (a piece of code that evaluates to a value). - Declarations:
int[] arr = {-1, -1}is a statement (specifically, a variable declaration). Java’s grammar does not allow you to declare a new named variable inline inside areturnexpression.
How to Write It If You Need a Variable
If you want to assign the array to a variable first and then return it, you must split it into two separate lines:
int[] arr = {-1, -1};
return arr;Summary
- Use either the direct anonymous array expression (
return new int[]{-1, -1};) or separate the declaration and return into two lines to successfully compile your fallback block.
char
char temp= ''; // error: empty character literal
In Java, there is no such thing as an “empty” character literal like ''. Single quotes must contain something.
In Java, the distinction between an uninitialized variable and an “empty” value comes down to syntax rules, memory allocation, and compilation checks.
1. The Differences
-
Uninitialized Variable (
char temp;)- What it means: You are telling Java, “I am going to use a variable named
tempof typechar, but I haven’t assigned a value to it yet.” - Java’s Behavior: Java’s compiler is very strict about local variables. If you try to read or use an uninitialized local variable before giving it a value (e.g.,
System.out.println(temp);), the compiler will throw avariable temp might not have been initializederror. - When it works: It is completely legal to declare it without initialization as long as you assign a value to it later before you ever try to read it (which is exactly what your
temp = s[i];line does inside the loop).
- What it means: You are telling Java, “I am going to use a variable named
-
“Empty” Character (
char temp = ' ';or\u0000)- What it means: This is an actual value assigned to the variable. In Java, there is no such thing as an “empty” character literal like
''. Single quotes must contain something. - The Space Alternative (
' '): If you writechar temp = ' ';, you are initializing it with a blank space (ASCII value 32). It is a valid character, but it takes up memory space as a literal blank character. - The Null/Zero Alternative (
'\u0000'): In Java, the default value for primitivecharfields in a class is the null character, represented as'\u0000'(integer value 0).
- What it means: This is an actual value assigned to the variable. In Java, there is no such thing as an “empty” character literal like
2. When to Use Which?
- Use Uninitialized (
char temp;) when:- You need a temporary holding variable (like in a swap algorithm) where you are **guaranteed** to assign a value to it before reading it.
- Why: It avoids unnecessary overhead of assigning a dummy value (
' 'or'\u0000') that you are just going to overwrite immediately anyway.
- Use Initialized (
char temp = 'a';orchar temp = '\u0000';) when:- Your code logic requires the variable to have a fallback or default state right from the start, especially if it might be read before a new value is assigned (e.g., inside a conditional
ifstatement that might get skipped). - You are declaring an instance variable (field) in a class, where Java automatically gives primitives like
chara default value of'\u0000'if you don’t provide one.
- Your code logic requires the variable to have a fallback or default state right from the start, especially if it might be read before a new value is assigned (e.g., inside a conditional
If, else if and else
If, else if, else
- is
else if()only invoked if firstif()fails- Will
secondelse ifalso run iffirstfails andfirst else if is true- Are all else if evaluated ?
- Is
else ifonly invoked if the firstiffails?- Yes. An
else ifis completely skipped if the precedingif(orelse if) condition evaluates totrue.
- Yes. An
- Will the second
else ifrun if the firstiffails and the firstelse ifis true?- No. Java evaluates an
if-else ifchain from top to bottom and stops at the very first true condition. Once a branch executes, the rest of the chain is bypassed entirely for that iteration.
- No. Java evaluates an
- Are all
else ifbranches evaluated?- No. As soon as one condition matches, Java short-circuits and ignores all subsequent
else ifandelseblocks in that chain.
- No. As soon as one condition matches, Java short-circuits and ignores all subsequent
Note
Java evaluates
if-else ifchains sequentially from top to bottom and short-circuits at the very firsttruecondition.
Control Flow, Loops
Use a for Loop When:
- You are iterating through a fixed-length structure (like arrays or strings) from index
0ton. - The step increment (
i++) is uniform, predictable, and tied directly to index traversal. - Example: Linear scans, array rankings, and static index lookups.
// Fixed linear scan
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}Use a while Loop When:
- The number of iterations is unknown beforehand and depends on dynamic runtime conditions.
- Pointers move at variable rates or conditionally based on logic inside the loop (e.g., left pointer moves sometimes, right pointer moves others).
- Example: Two-pointer convergence, binary search, sliding window expansion/contraction, and linked list traversals.
// Dynamic pointer convergence
int left = 0, right = arr.length - 1;
while (left < right) {
if (arr[left] == target) {
break;
}
left++; // Conditional movement
}Critical Pitfalls to Watch Out For in Loops
When writing algorithms, always double-check these four high-risk areas:
Off-by-One Errors (< vs <=)
- Using
<=witharr.lengthcauses anArrayIndexOutOfBoundsException. Always use< arr.lengthfor standard zero-indexed array scans.
Infinite Loops
- In a
whileloop, ensure every code path updates your tracking variables or pointers. If a condition gets stuck without movingleft,right, ori, the loop will run forever.
Modifying Collections During Iteration
- Never add or remove elements from an active collection (like an
ArrayList) using a standard index loop without adjusting your index, or using an explicit iterator, to avoid skipping elements or throwing runtime exceptions.
State Leakage
- If a loop or helper function uses running totals, flags, or tracking variables, ensure they are cleanly reset or initialized inside the outer method scope before execution begins.
Loop Control: continue vs. break
continue
- In a loop (
for,while), thecontinuekeyword instantly terminates the current iteration right where it is. - It skips all remaining lines of code inside the loop body for that specific element and
- jumps straight to the next loop step (incrementing
i).
The Upfront Bouncer Pattern
- In some algorithm,
continueacts as an **upfront bouncer/filter - Use
continueat the very top of your loop body as an explicit duplicate filter or guard clause. - Weed out invalid or duplicate values early so your core logic only processes clean data.
int[] nums = {2, 2, 3, 1};
Integer max1 = null;
for (int i = 0; i < nums.length; i++) {
// Upfront filter: skip processing if duplicate exists
if (max1 != null && nums[i] == max1) {
continue;
}
if (max1 == null || nums[i] > max1) {
max1 = nums[i];
}
}break
- Instantly terminates the entire loop altogether, exiting execution immediately.
- Use it when you have
- found your target or
- met a termination condition and
- no further scanning is required.
Code Example: Using break for Early Exit
int[] nums = {10, 20, 30, 40, 50};
int target = 30;
int targetIndex = -1;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == target) {
targetIndex = i;
break; // Stop scanning once found, saving CPU cycles
}
}The Shadowing Rule
Broader conditions must never precede stricter ones. Always place the most restrictive, highest-threshold condition at the top of the chain to prevent wide nets from blocking valid specific checks.
Incorrect - condition bypassed
int x = 15;
if (x > 20) {
// Skipped (15 > 20 is false)
} else if (x > 10) {
// This is TRUE! Executes this block.
} else if (x > 5) {
// Bypassed entirely, even though 15 > 5 is also true.
} else {
// Skipped because an earlier condition matched.
}Correct
int x = 25;
// Correct: Strictest condition is checked first
if (x > 20) {
System.out.println("Greater than 20"); // Executes for 25
} else if (x > 15) {
System.out.println("Between 16 and 20");
} else {
System.out.println("15 or below");
} else { // Skipped because an earlier condition matched. }Tree
Is a Tree interface always sorted in insertion order?
Question after reading this solution of LC 414
- No.
LinkedHashMaporLinkedListare sorted by insertion order,Linkedbeing the keyword here. - Tree-based collections in Java (like
TreeSetandTreeMap, which implementSortedSetandNavigableSet) are always by natural sorting order or a custom Comparator (backed by a Red-Black Tree). They completely discard the sequence in which insert items. - If you need a structure that preserves insertion order, use
LinkedHashSetorLinkedHashMap.