Learnitweb

LeetCode Problem 468: Validate IP Address

Problem Overview

You are given a string queryIP, and you need to determine whether it is a valid IPv4 address, a valid IPv6 address, or neither.

Return:

  • "IPv4" if it is a valid IPv4 address.
  • "IPv6" if it is a valid IPv6 address.
  • "Neither" if it is invalid.

Example 1

Input: queryIP = "172.16.254.1"
Output: "IPv4"
Explanation: Each segment is a valid number between 0 and 255.

Example 2

Input: queryIP = "2001:0db8:85a3:0:0:8A2E:0370:7334"
Output: "IPv6"
Explanation: Each group is a valid 16-bit hexadecimal number.

Example 3

Input: queryIP = "256.256.256.256"
Output: "Neither"
Explanation: Each segment must be between 0 and 255.

Understanding IP Formats

IPv4 Rules

  1. Must contain 4 decimal segments separated by dots (.).
  2. Each segment must:
    • Contain only digits.
    • Have a value between 0 and 255.
    • Not contain leading zeros unless the value is exactly 0.
  3. Examples of valid IPv4: 192.168.0.1 127.0.0.1 0.0.0.0
  4. Examples of invalid IPv4: 192.168.01.1 → invalid (leading zero) 256.100.1.1 → invalid (256 > 255) 192.168.1 → invalid (only 3 parts)

IPv6 Rules

  1. Must contain 8 groups separated by colons (:).
  2. Each group must:
    • Be a hexadecimal string (0–9, a–f, A–F).
    • Have 1 to 4 characters.
  3. Examples of valid IPv6: 2001:0db8:85a3:0000:0000:8A2E:0370:7334 2001:db8:85a3:0:0:8A2E:370:7334
  4. Examples of invalid IPv6: 2001:0db8:85a3::8A2E:0370:7334 → invalid (double colon not allowed) 2001:0db8:85a3:0000:0000:8A2E:0370:733400 → invalid (group too long)

Approach

We’ll check both formats separately:

  1. If the input contains a dot (.), check for IPv4 validity.
  2. If it contains a colon (:), check for IPv6 validity.
  3. Otherwise, return "Neither".

To simplify:

  • Use split() to break the string into segments.
  • Validate segment rules strictly.
  • If any segment fails, return "Neither".

Algorithm Steps

  1. If the string contains ., validate as IPv4:
    • Split by . (must have exactly 4 parts).
    • For each part:
      • Check if numeric only.
      • Check no leading zeros (unless single ‘0’).
      • Convert to integer and ensure it’s 0 ≤ value ≤ 255.
  2. Else if the string contains :, validate as IPv6:
    • Split by : (must have exactly 8 parts).
    • For each part:
      • Length must be between 1 and 4.
      • Check all characters are hexadecimal (0–9, a–f, A–F).
  3. If neither format matches, return "Neither".

Java Code Implementation

public class Solution {

    public String validIPAddress(String queryIP) {
        if (queryIP.chars().filter(ch -> ch == '.').count() == 3) {
            return validateIPv4(queryIP);
        } else if (queryIP.chars().filter(ch -> ch == ':').count() == 7) {
            return validateIPv6(queryIP);
        } else {
            return "Neither";
        }
    }

    private String validateIPv4(String ip) {
        String[] parts = ip.split("\\.", -1);
        if (parts.length != 4) return "Neither";

        for (String part : parts) {
            if (part.length() == 0 || part.length() > 3) return "Neither";
            if (part.charAt(0) == '0' && part.length() > 1) return "Neither"; // no leading zeros
            for (char c : part.toCharArray()) {
                if (!Character.isDigit(c)) return "Neither"; // only digits allowed
            }
            int num = Integer.parseInt(part);
            if (num < 0 || num > 255) return "Neither";
        }
        return "IPv4";
    }

    private String validateIPv6(String ip) {
        String[] parts = ip.split(":", -1);
        if (parts.length != 8) return "Neither";

        String hexDigits = "0123456789abcdefABCDEF";
        for (String part : parts) {
            if (part.length() == 0 || part.length() > 4) return "Neither";
            for (char c : part.toCharArray()) {
                if (hexDigits.indexOf(c) == -1) return "Neither";
            }
        }
        return "IPv6";
    }
}

Example Dry Run

Input:

queryIP = "172.16.254.1"

Step 1: Count dots → 3 dots → try IPv4.
Split into: ["172", "16", "254", "1"]

  • "172" → numeric, within range.
  • "16" → valid.
  • "254" → valid.
  • "1" → valid.

Output → "IPv4"


Input:

queryIP = "2001:0db8:85a3:0000:0000:8A2E:0370:7334"

Step 1: Count colons → 7 colons → try IPv6.
Split into 8 groups, all length ≤ 4 and valid hex.
Output → "IPv6"


Input:

queryIP = "256.256.256.256"

Step 1: Dots = 3 → try IPv4.
"256" → invalid (out of range).
Output → "Neither"


Complexity Analysis

AspectAnalysis
Time ComplexityO(n) where n is the length of the input string
Space ComplexityO(1) (constant auxiliary space)

Key Takeaways

  1. IPv4 requires 4 numeric segments within [0,255] and no leading zeros.
  2. IPv6 requires 8 hexadecimal segments (1–4 chars each).
  3. Careful validation is crucial—simple string splitting and character checks are enough.
  4. Using split("\\.", -1) ensures even empty parts are detected (helps catch "1..1.1").
  5. Both chars().filter() and split() count checks prevent invalid segmentation.