Monday, March 3, 2025

 A previous article explained just the extractive summary with Azure REST APIs. This is about producing summaries for entire manuscripts:

import requests

import json

import time

from docx import Document

import os

# Azure AI Language Service configuration

endpoint = "https://<your-azure-ai-resource-name>.cognitiveservices.azure.com/language/analyze-text/jobs?api-version=2023-04-01"

api_key = "<your-api-key>"

headers = {

    "Content-Type": "application/json",

    "Ocp-Apim-Subscription-Key": api_key

}

def summarize_text(text):

    body = {

        "displayName": "Document Summarization",

        "analysisInput": {

            "documents": [

                {

                    "id": "1",

                    "language": "en",

                    "text": text

                }

            ]

        },

        "tasks": [

            {

                "kind": "ExtractiveSummarization",

                "parameters": {

                    "sentenceCount": 5

                }

            }

        ]

    }

    response = requests.post(endpoint, headers=headers, json=body)

    if response.status_code == 202:

        operation_location = response.headers["Operation-Location"]

        return operation_location

    else:

        raise Exception(f"Failed to start summarization job: {response.text}")

def get_summary_result(operation_location):

    while True:

        response = requests.get(operation_location, headers=headers)

        result = json.loads(response.text)

        if result["status"] == "succeeded":

            summary = result["tasks"]["items"][0]["results"]["documents"][0]["sentences"]

            return " ".join([sentence["text"] for sentence in summary])

        elif result["status"] == "failed":

            raise Exception(f"Summarization job failed: {result}")

        time.sleep(5) # Wait for 5 seconds before checking again

def get_text(file_path):

    with open(file_path, 'r') as file:

        file_contents = file.read()

    return file_contents

# Main execution

if __name__ == "__main__":

    docx_file_path = "1.txt"

    # Extract text from Word document

    document_text = get_text(docx_file_path)

    # Start summarization job

    operation_location = summarize_text(document_text)

    print(operation_location)

    # Get summary result

    summary = get_summary_result(operation_location)

    print("Summary:")

    print(summary)

Sample Output:

“””

https://text-ctl-3.cognitiveservices.azure.com/language/analyze-text/jobs/9afb7002-7930-4448-8bd3-e3cb02287708?api-version=2023-04-01

Summary:

The public cloud offers capabilities to the general public in the form of services from the provider̢۪s services portfolio that can be requested as instances called resources. Both for the provider and the general public, IaC is a common paradigm for self-service templates to manage, capture and track changes to a resource during its lifecycle. Public cloud is the epitome of infrastructure both in terms of history and landscape and this book describes principles using references to public cloud. The IaC architecture is almost always dominated by the choice of technology stacks. When the code is delivered, configuration management and infrastructure management provide a live operational environment for testing.

“””

A large document can be split into text as shown:

from docx import Document import os

input_file = 'Document1.docx'

output_file = Text1.txt'

def process_large_file(input_file_path, output_file_path):

try:

doc = Document(input_file_path)

print(f"Number of paragraphs: {len(doc.paragraphs)}")

with open(output_file_path, 'a', encoding='utf-8') as output_file:

for para in doc.paragraphs: chunk = para.text

if chunk:

output_file.write(chunk)

output_file.write("\r\n")

except Exception as e: print(f"An error occurred: {e}")

process_large_file(input_file, output_file)

print(f"Text has been extracted from {input_file} and written to {output_file}")

Instead of “ExtractiveSummarization” value in the request, we can use “AbstractiveSummarization”. The parsing of the operation status will also require to be changed as follows in that case:

def get_summary_result(operation_location):

    while True:

        response = requests.get(operation_location, headers=headers)

        result = json.loads(response.text)

        if result["status"] == "succeeded":

            print(repr(result))

            summary = result["tasks"]["items"][0]["results"]["documents"][0]["summaries"]

            return " ".join([sentence["text"] for sentence in summary])

        elif result["status"] == "failed":

            raise Exception(f"Summarization job failed: {result}")

        time.sleep(5) # Wait for 5 seconds before checking again

and a sample output will result as follows:

https://text-ctl-3.cognitiveservices.azure.com/language/analyze-text/jobs/3f246bed-ebfb-4b2b-bcc3-e40582b800d1?api-version=2023-04-01

Summary:

The document discusses the architecture of Infrastructure-as-Code (IaC) within public clouds, highlighting its tiered implementation that includes IaaS, PaaS, and DevOps tools. It emphasizes the role of IaC in managing resources through code, facilitating quick and consistent provisioning, and addressing changes throughout a resource's lifecycle. The architecture is heavily influenced by the choice of technology stacks, with tools like Ansible, Terraform, and Pulumi being prominent choices. The document notes the benefits of IaC in reducing shadow IT, integrating with CI/CD platforms, and standardizing infrastructure across environments, whether cloud-based or on-premises. It distinguishes between configuration management tools, such as CFEngine, and infrastructure management tools, like Terraform and Pulumi, which can be mixed and matched to meet specific organizational needs. The summary encapsulates the essence of IaC's role in modern cloud environments, its impact on DevOps, and its capacity to manage complex infrastructures effectively.

Sunday, March 2, 2025

 Problem: A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> ... -> sk such that:

• Every adjacent pair of words differs by a single letter.

• Every si for 1 <= i <= k is in wordList. Note that beginWord does not need to be in wordList.

• sk == endWord

Given two words, beginWord and endWord, and a dictionary wordList, return all the shortest transformation sequences from beginWord to endWord, or an empty list if no such sequence exists. Each sequence should be returned as a list of the words [beginWord, s1, s2, ..., sk].

Example 1:

Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]

Output: [["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]

Explanation: There are 2 shortest transformation sequences:

"hit" -> "hot" -> "dot" -> "dog" -> "cog"

"hit" -> "hot" -> "lot" -> "log" -> "cog"

Example 2:

Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]

Output: []

Explanation: The endWord "cog" is not in wordList, therefore there is no valid transformation sequence.

Constraints:

• 1 <= beginWord.length <= 5

• endWord.length == beginWord.length

• 1 <= wordList.length <= 500

• wordList[i].length == beginWord.length

• beginWord, endWord, and wordList[i] consist of lowercase English letters.

• beginWord != endWord

• All the words in wordList are unique.

• The sum of all shortest transformation sequences does not exceed 105.

class Solution {

    public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {

        List<List<String>> results = new ArrayList<List<String>>();

        var q = new LinkedList<String>();

        var s = new HashSet<String>(wordList);

        q.add(beginWord);

        var result = new ArrayList<String>();

        combine(beginWord, endWord, s, results, result);

        var minOpt = results.stream().filter(x -> x.get(0).equals(beginWord)).mapToInt(x -> x.size()).min();

        if (minOpt.isPresent()) {

            var min = minOpt.getAsInt();

            results = results.stream().filter(x -> x.size() == min).collect(Collectors.toList());

        }

        return results;

    }

    private static void combine(String top, String endWord, HashSet<String> s, List<List<String>> results, List<String> result)

    {

            if (top.equals(endWord)) {

                return;

            }

            result.add(top);

            char[] chars = top.toCharArray();

            for (int i = 0; i < chars.length; i++)

            {

                for (char c = 'a'; c <= 'z'; c++)

                {

                    char temp = chars[i];

                    if (temp != c) {

                        chars[i] = c;

                    }

                    String candidate = new String(chars);

                    if (s.contains(candidate) && !result.contains(candidate)) {

                        var clone = new ArrayList<String>(result);

                        if (candidate.equals(endWord)) {

                            clone.add(candidate);

                            results.add(clone);

                        } else {

                            combine(candidate, endWord, s, results, clone);

                        }

                    }

                    chars[i] = temp;

                }

            }

            result.remove(top);

    }

}

Test cases:

1.

Input

beginWord =

"hit"

endWord =

"cog"

wordList =

["hot","dot","dog","lot","log","cog"]

Output

[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]

Expected

[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]

2.

Input

beginWord =

"hit"

endWord =

"cog"

wordList =

["hot","dot","dog","lot","log"]

Output

[]

Expected

[]


Saturday, March 1, 2025

 Sample Code for leveraging Azure AI Language Services to summarize text:

import requests

import json

def summarize_text(document, endpoint, api_key):

    # Define the API endpoint for Text Analytics v3.2-preview.2 (used for text summarization)

    # url = f"{endpoint}/text/analytics/v3.2-preview.2/analyze"

    url = f"{endpoint}/language/analyze-text/jobs?api-version=2023-04-01"

    # Set up headers with your API key

    headers = {

        "Ocp-Apim-Subscription-Key": api_key,

        "Content-Type": "application/json",

        "Content-Length": "0"

    }

    # Define the input document for summarization

    body = {

            "documents": [

                {

                    "id": "1",

                    "language": "en",

                    "text": document

                }

            ],

        "analysisInput": {

            "documents": [

                {

                    "id": "1",

                    "language": "en",

                    "text": document

                }

            ]

        },

        "tasks": [

            {

                "kind": "ExtractiveSummarization",

                "taskName": "extractiveSummarization",

                "parameters": {

                    "modelVersion": "latest",

                    "sentenceCount": 3 # Adjust the number of sentences in the summary

                }

            }

        ]

    }

    # Send the POST request

    response = requests.post(url, headers=headers, json=body)

    # Check for response status

    if response.status_code == 200:

        result = response.json()

        # Extract summarized sentences from the response

        summary = result['tasks']['extractiveSummarizationResults'][0]['results']['documents'][0]['sentences']

        return " ".join([sentence["text"] for sentence in summary])

    elif response.status_code == 202:

        print(f"Headers: {response.headers}")

    else:

        raise Exception(f"Error: {response.status_code}, Message: {response.text}, Headers: {response.headers}")

# Example usage

if __name__ == "__main__":

    # Replace with your Azure Text Analytics endpoint and API key

    AZURE_ENDPOINT = "https://<your-azure-ai-endpoint>.cognitiveservices.azure.com"

    AZURE_API_KEY = "<your-api-key>"

    # Input text document to summarize

    input_document = """

    Artificial intelligence (AI) refers to the simulation of human intelligence in machines

    that are programmed to think like humans and mimic their actions. The term may also

    be applied to any machine that exhibits traits associated with a human mind such as

    learning and problem-solving.

    """

    try:

        summary = summarize_text(input_document, AZURE_ENDPOINT, AZURE_API_KEY)

        print("Summary:")

        print(summary)

    except Exception as e:

        print(e)

Sample trial:

Response Headers:

{'Content-Length': '0', 'operation-location': 'https://<your-azure-ai-endpoint>.cognitiveservices.azure.com/language/analyze-text/jobs/7060ce5a-afb4-4a08-87a1-e456d486510f?api-version=2023-04-01', 'x-envoy-upstream-service-time': '188', 'apim-request-id': 'f44e40fe-e2ef-41f4-b46d-d36896f3f20d', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'x-ms-region': 'Central US', 'Date': 'Sat, 01 Mar 2025 02:59:41 GMT'}

curl -i -H "Ocp-Apim-Subscription-Key: <your-api-key>" "https://<your-azure-ai-endpoint>.cognitiveservices.azure.com/language/analyze-text/jobs/7060ce5a-afb4-4a08-87a1-e456d486510f?api-version=2023-04-01"

HTTP/1.1 200 OK

Content-Length: 933

Content-Type: application/json; charset=utf-8

x-envoy-upstream-service-time: 51

apim-request-id: 30208936-7f0d-49d5-9d36-8fc69ffc976e

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

x-content-type-options: nosniff

x-ms-region: Central US

Date: Sat, 01 Mar 2025 03:01:03 GMT

{"jobId":"7060ce5a-afb4-4a08-87a1-e456d486510f","lastUpdatedDateTime":"2025-03-01T02:59:42Z","createdDateTime":"2025-03-01T02:59:41Z","expirationDateTime":"2025-03-02T02:59:41Z","status":"succeeded","errors":[],"tasks":{"completed":1,"failed":0,"inProgress":0,"total":1,"items":[{"kind":"ExtractiveSummarizationLROResults","taskName":"extractiveSummarization","lastUpdateDateTime":"2025-03-01T02:59:42.8576711Z","status":"succeeded","results":{"documents":[{"id":"1","sentences":[{"text":"Artificial intelligence (AI) refers to the simulation of human intelligence in machines","rankScore":1.0,"offset":5,"length":87},{"text":"that are programmed to think like humans and mimic their actions.","rankScore":0.49,"offset":98,"length":65},{"text":"be applied to any machine that exhibits traits associated with a human mind such as","rankScore":0.3,"offset":187,"length":83}],"warnings":[]}],"errors":[],"modelVersion":"2024-11-04"}}]}}

Reference:

1. previous articles

2. Extractive Summarization:

a. https://learn.microsoft.com/en-us/azure/ai-services/language-service/summarization/overview?tabs=text-summarization

b. https://learn.microsoft.com/en-us/azure/ai-services/language-service/summarization/how-to/document-summarization#try-text-extractive-summarization

3. Abstractive Summarization: https://github.com/microsoft/AzureSearch-MRC/blob/main/README.md


Friday, February 28, 2025

 This is a summary of the book titled “Your Stone Age Brain in the Screen Age: Coping with digital distraction and sensory overload” written by Richard Cytowic and published by MIT Press in 2024. The author is a neurologist who explains how screens are grabbing your attention and how we can regain them. His book talks about the impact of continuous alerts, notifications and stimulations on the human brain and why reclaiming your attention and engaging with real-world is not only pertinent and significant but also a necessity. Excessive screen time is reducing brain development in children, resulting in reduced impulse control even leading to psychological harm. We are hardwired with sensory perceptions which makes it difficult to peel away our eyes from the flickering screen. Cellphone and tablet usage has given rise to increased body dysmorphia and virtual autism. Depriving children of sufficient human contact can inhibit the development of empathy. Screen addictions can put you on a “hedonic treadmill”. Protect your sleep and make space for silence and connection to fight against digital toxicity.

Excessive screen time is causing brain damage in children, resulting in reduced impulse control and reduced attention span. Addiction, originating from the Latin word "addictum," refers to the time spent serving a master. Many people don't see excessive screen time as a problem, but this blindness is due to tech giants exploiting human psychology to keep people glued to their screens. Social media addiction can be fatal and trigger severe psychological harm, with injuries caused by inattentive cellphone usage resulting in 76,000 emergency room visits in the past two decades. The human brain's two hemispheres support different skill sets and distinct conceptualizations of identity, making it difficult to stop giving attention to screens. The internal battle for control between the two hemispheres is a result of the way the brain's two hemispheres interact, making it difficult to stop giving attention to screens.

The brain's sensitivity to change, which helped early humans survive, has led to the rise of digital distractions and increased body dysmorphia. The brain's orienting reflex allows it to misperceive digital sound and visual interruptions as having life-or-death significance. This has led to the development of new mental health conditions, such as Snapchat dysmorphia, a new type of body dysmorphic disorder (BDD), where individuals become distressed when their real-life face doesn't look like their edited digital one. Children with virtual autism show dramatic improvements once digital screens are removed. Heavy screen time can also result in the development of autism-like behaviors in younger children, as they can't learn to make eye contact or display context-appropriate facial expressions. Child psychiatrist Victoria Dunckley identifies digital devices as the primary source of issues in children without autism spectrum disorder (ASD). Parents can limit their child's development of virtual autism by organizing in-person play dates and limiting screen time for children 12 years old and younger.

Attachment theory, based on research by Harry Harlow, suggests that depriving children of human contact can inhibit the development of empathy. Harlow's experiments showed that chimpanzees raised without warmth and comfort were unable to comfort themselves, leading to a "pit of despair" and a lack of relational understanding. The iPhone generation may face similar fate to those raised without warmth, as they may escape into digital worlds at the expense of developing empathy and healthy attention spans. Smartphone addictions can trap individuals on a "hedonic treadmill," chasing fleeting moments of happiness and lacking genuine inner contentment. The perpetual unpredictability of digital rewards makes them never less exciting, leading to a constant state of craving. The brain treats the cues for the addiction as more salient than the reward itself, trapping individuals in a constant state of craving. As children escape into digital worlds, they may do so at the expense of developing empathy and healthy attention spans, as empathy requires the ability to focus on another person long enough to understand a different perspective.

To protect your sleep from blue screen light, follow these self-care and sleep hygiene practices:

1. Establish consistent bedtime and wake-up times, block out light sources, and choose a restorative sleep posture.

2. Keep your bedroom temperature between 65°F and 68°F, using a cooling gel pillow or mattress pad.

3. Keep the bathroom lights low, using low-wattage LED nightlights and candles.

4. Consider taking a walk outdoors before bed, limit digital device use, and get natural light.

5. Rethink digital habits, making room for silence and connection.

6. Engage in niksen, the art of doing nothing and putting life on pause for a few minutes.

7. Switch to paper media, writing by hand, and avoiding streaming while eating.

By following these practices, you can improve your sleep and reduce the risk of health consequences such as rapid cellular aging.


Thursday, February 27, 2025

 Given a wire grid of size N * N with N-1 horizontal edges and N-1 vertical edges along the X and Y axis respectively, and a wire burning out every instant as per the given order using three matrices A, B, C such that the wire that burns is

(A[T], B[T] + 1), if C[T] = 0 or

(A[T] + 1, B[T]), if C[T] = 1

Determine the instant after which the circuit is broken

     public static boolean checkConnections(int[] h, int[] v, int N) {

        boolean[][] visited = new boolean[N][N];

        dfs(h, v, visited,0,0);

        return visited[N-1][N-1];

    }

    public static void dfs(int[]h, int[]v, boolean[][] visited, int i, int j) {

        int N = visited.length;

        if (i < N && j < N && i>= 0 && j >= 0 && !visited[i][j]) {

            visited[i][j] = true;

            if (v[i * (N-1) + j] == 1) {

                dfs(h, v, visited, i, j+1);

            }

            if (h[i * (N-1) + j] == 1) {

                dfs(h, v, visited, i+1, j);

            }

            if (i > 0 && h[(i-1)*(N-1) + j] == 1) {

                dfs(h,v, visited, i-1, j);

            }

            if (j > 0 && h[(i * (N-1) + (j-1))] == 1) {

                dfs(h,v, visited, i, j-1);

            }

        }

    }

    public static int burnout(int N, int[] A, int[] B, int[] C) {

        int[] h = new int[N*N];

        int[] v = new int[N*N];

        for (int i = 0; i < N*N; i++) { h[i] = 1; v[i] = 1; }

        for (int i = 0; i < N; i++) {

            h[(i * (N)) + N - 1] = 0;

            v[(N-1) * (N) + i] = 0;

        }

        System.out.println(printArray(h));

        System.out.println(printArray(v));

        for (int i = 0; i < A.length; i++) {

            if (C[i] == 0) {

                v[A[i] * (N-1) + B[i]] = 0;

            } else {

                h[A[i] * (N-1) + B[i]] = 0;

            }

            if (!checkConnections(h,v, N)) {

                return i+1;

            }

        }

        return -1;

    }

        int[] A = new int[9];

        int[] B = new int[9];

        int[] C = new int[9];

        A[0] = 0; B [0] = 0; C[0] = 0;

        A[1] = 1; B [1] = 1; C[1] = 1;

        A[2] = 1; B [2] = 1; C[2] = 0;

        A[3] = 2; B [3] = 1; C[3] = 0;

        A[4] = 3; B [4] = 2; C[4] = 0;

        A[5] = 2; B [5] = 2; C[5] = 1;

        A[6] = 1; B [6] = 3; C[6] = 1;

        A[7] = 0; B [7] = 1; C[7] = 0;

        A[8] = 0; B [8] = 0; C[8] = 1;

        System.out.println(burnout(9, A, B, C));

1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0

8

Alternatively,

    public static boolean burnWiresAtT(int N, int[] A, int[] B, int[] C, int t) {

        int[] h = new int[N*N];

        int[] v = new int[N*N];

        for (int i = 0; i < N*N; i++) { h[i] = 1; v[i] = 1; }

        for (int i = 0; i < N; i++) {

            h[(i * (N)) + N - 1] = 0;

            v[(N-1) * (N) + i] = 0;

        }

        System.out.println(printArray(h));

        System.out.println(printArray(v));

        for (int i = 0; i < t; i++) {

            if (C[i] == 0) {

                v[A[i] * (N-1) + B[i]] = 0;

            } else {

                h[A[i] * (N-1) + B[i]] = 0;

            }

        }

        return checkConnections(h, v, N);

    }

    public static int binarySearch(int N, int[] A, int[] B, int[] C, int start, int end) {

        if (start == end) {

            if (!burnWiresAtT(N, A, B, C, end)){

                return end;

            }

            return -1;

        } else {

            int mid = (start + end)/2;

            if (burnWiresAtT(N, A, B, C, mid)) {

                return binarySearch(N, A, B, C, mid + 1, end);

            } else {

                return binarySearch(N, A, B, C, start, mid);

            }

        }

    }

1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0

8


Wednesday, February 26, 2025

 #codingexercise

Get the widest difference between two indexes in an array of random integers such that the integer at the second index is greater than that of the first.

import java.util.Arrays;

public class LongestIncreasingSubsequence {

    public static void main(String[] args) {

        int[] arr = {10, 22, 9, 33, 21, 50, 41, 60, 80};

        System.out.println(GetWidestDifferenceBetweenIndicesOfLIS(arr));

    }

    public static int GetWidestDifferenceBetweenIndicesofLIS(int[] arr) {

        int n = arr.length;

        int[] lis = new int[n+1];

        for (int i = 0; i < n+1; i++) {

                lis[i] = 1; // Initialize LIS value for each element

        }

        for (int i = 1; i < n; i++) {

            for (int j = 0; j < i; j++) {

                if (arr[i] > arr[j]) {

                    lis[i] = Math.max(lis[i], lis[j] + 1);

                }

            }

        }

       // lis = 1,2,1,3,2,4,4,5,6

        int max_length = Arrays.stream(lis).max().orElse(0);

        if (max_length == 0) return 0;

        if (max_length == 1) return 1;

        int last = -1;

        for (int i = n-1; i >= 0; i++) {

              if (lis[I] == max_length ) {

                    last = i;

              }

        }

        int first = 0;

        for (int i = 0; i < n; i++) {

             if (lis[i] == 2) {

                 first = i;

                 break;

             }

        }

        for(int I = 0; I < first; i++) {

               if (arr[i] < arr[first]) {

                    first = I;

                    break;

               }

        }

        Return last-first+1;

    }

}

9

#booksummary:  BookSummary233.docx

Tuesday, February 25, 2025

 Problem statement: Given the root of a binary tree, check whether it is a mirror of itself (i.e., symmetric around its center).

Example 1:

                 1

                2 2

             3 4 4 3

Input: root = [1,2,2,3,4,4,3]

Output: true

Example 2:

                 1

                2 2

       null 3 null 3

Input: root = [1,2,2,null,3,null,3]

Output: false

Constraints:

The number of nodes in the tree is in the range [1, 1000].

-100 <= Node.val <= 100

/**

 * Definition for a binary tree node.

 * public class TreeNode {

 * int val;

 * TreeNode left;

 * TreeNode right;

 * TreeNode() {}

 * TreeNode(int val) { this.val = val; }

 * TreeNode(int val, TreeNode left, TreeNode right) {

 * this.val = val;

 * this.left = left;

 * this.right = right;

 * }

 * }

 */

class Solution {

    public boolean isSymmetric(TreeNode root) {

        List<Integer> serialized = new ArrayList<Integer>();

        InorderTraversal(root, serialized);

        return IsPalindrome(serialized);

    }

    public boolean isPalindrome(List<Integer> serialized) {

        int i = 0;

        int j = serialized.count() - 1;

        while (i < j) {

            if (serialized.getAt(i) != serialized.getAt(j)) {

                return false;

            }

            i++;

            j--;

        }

        return true;

    }

    public void InorderTraversal(TreeNode root, List<Imteger> serialized) {

        if (root == null) {

            serialized.Add(Integer.MinValue);

            return;

        }

        InOrderTraversal(root.left);

        serialized.Add(root.val);

        InOrderTraversal(root.right);

    }

}