# Circular Sentence
**Difficulty:** EASY
[External](https://leetcode.com/problems/circular-sentence)
Canonical: https://scaleengineer.com/dsa/problems/circular-sentence
**Data structures:** String
---
## Problem
A **sentence** is a list of words that are separated by a **single** space with no leading or trailing spaces.

* For example, `"Hello World"`, `"HELLO"`, `"hello world hello world"` are all sentences.

Words consist of **only** uppercase and lowercase English letters. Uppercase and lowercase English letters are considered different.

A sentence is **circular** if:

* The last character of each word in the sentence is equal to the first character of its next word.
* The last character of the last word is equal to the first character of the first word.

For example, `"leetcode exercises sound delightful"`, `"eetcode"`, `"leetcode eats soul" `are all circular sentences. However, `"Leetcode is cool"`, `"happy Leetcode"`, `"Leetcode"` and `"I like Leetcode"` are **not** circular sentences.

Given a string `sentence`, return `true` _if it is circular_. Otherwise, return `false`.

**Example 1:**

**Input:** sentence = "leetcode exercises sound delightful"
**Output:** true
**Explanation:** The words in sentence are ["leetcode", "exercises", "sound", "delightful"].
- leetcode's last character is equal to exercises's first character.
- exercises's last character is equal to sound's first character.
- sound's last character is equal to delightful's first character.
- delightful's last character is equal to leetcode's first character.
The sentence is circular.

**Example 2:**

**Input:** sentence = "eetcode"
**Output:** true
**Explanation:** The words in sentence are ["eetcode"].
- eetcode's last character is equal to eetcode's first character.
The sentence is circular.

**Example 3:**

**Input:** sentence = "Leetcode is cool"
**Output:** false
**Explanation:** The words in sentence are ["Leetcode", "is", "cool"].
- Leetcode's last character is **not** equal to is's first character.
The sentence is **not** circular.

**Constraints:**

* `1 <= sentence.length <= 500`
* `sentence` consist of only lowercase and uppercase English letters and spaces.
* The words in `sentence` are separated by a single space.
* There are no leading or trailing spaces.

# Approaches
## Split into Words and Compare
This approach involves breaking the sentence down into individual words and then checking the circular conditions. We first split the input string by spaces to get an array of words. Then, we iterate through this array to verify two conditions: 1) The last character of each word matches the first character of the next word. 2) The last character of the last word matches the first character of the first word.
**Time:** O(N), where N is the length of the `sentence`. The `split` operation takes O(N) time. The subsequent loop runs `n-1` times (where `n` is the number of words), which is also proportional to N in the worst case. · **Space:** O(N), where N is the length of the `sentence`. The `split` method creates a new array of strings, and the total space required to store these strings is proportional to the length of the original sentence.
**Pros:** The logic is very clear and directly follows the problem definition.; Easy to implement and debug.
**Cons:** Uses extra memory to store the array of words, which can be significant for very long sentences.
### Explanation
The algorithm starts by using the `split(" ")` method to convert the sentence string into an array of strings, where each element is a word.
It then handles the edge case of a sentence with a single word. For a single word, the sentence is circular if its first and last characters are the same.
For sentences with multiple words, it first checks the primary circular condition: if the last character of the last word in the array matches the first character of the first word. If not, it immediately returns `false`.
Next, it iterates through the array of words from the first word up to the second-to-last word. In each iteration, it compares the last character of the current word with the first character of the next word.
If any of these adjacent word checks fail, the function returns `false`.
If all checks pass successfully, the function returns `true`, confirming the sentence is circular.
```java
class Solution {
    public boolean isCircularSentence(String sentence) {
        String[] words = sentence.split(" ");
        int n = words.length;

        // Check if the last character of the last word matches the first character of the first word.
        if (words[0].charAt(0) != words[n - 1].charAt(words[n - 1].length() - 1)) {
            return false;
        }

        // If there's only one word, the above check is sufficient.
        if (n == 1) {
            return true;
        }

        // Check adjacent words.
        for (int i = 0; i < n - 1; i++) {
            String currentWord = words[i];
            String nextWord = words[i + 1];
            if (currentWord.charAt(currentWord.length() - 1) != nextWord.charAt(0)) {
                return false;
            }
        }

        return true;
    }
}
```
### Algorithm
- Split the `sentence` string by the space character to get an array of `words`.
- Let `n` be the number of words.
- Check if the first character of `words[0]` is different from the last character of `words[n-1]`. If so, return `false`.
- If `n` is 1, the previous check is enough, so return `true`.
- Iterate with an index `i` from `0` to `n-2`.
- In each iteration, check if the last character of `words[i]` is different from the first character of `words[i+1]`. If they are different, return `false`.
- If the loop completes without returning, it means all conditions are met. Return `true`.

## Single Pass Iteration
A more optimized approach is to check the conditions by iterating through the sentence string just once, without splitting it. This avoids the overhead of creating an array of words. The core idea is that the connection between two words always occurs around a space character.
**Time:** O(N), where N is the length of the `sentence`. We perform a single pass over the string. · **Space:** O(1). We only use a few variables to store the length and loop index, requiring constant extra space.
**Pros:** Extremely efficient in terms of memory usage.; Optimal solution with linear time and constant space complexity.
**Cons:** The logic might be slightly less direct than the splitting approach, as it works on character indices rather than abstract "words".
### Explanation
This method performs a single scan of the input string `sentence`.
First, it checks the overall circular condition: the last character of the sentence (`sentence.charAt(n-1)`) must be the same as the first character (`sentence.charAt(0)`). If this fails, the sentence cannot be circular, and the function returns `false`. This single check also correctly handles sentences with just one word.
Next, the algorithm iterates through the string. The loop looks for space characters.
When a space is found at index `i`, it signifies the end of one word and the beginning of the next. The character at `i-1` is the last letter of the preceding word, and the character at `i+1` is the first letter of the succeeding word.
The algorithm checks if `sentence.charAt(i-1)` is equal to `sentence.charAt(i+1)`. If they don't match for any space in the sentence, it returns `false`.
If the loop completes without finding any mismatches, it means all internal word connections are valid. Since the first and last characters of the entire sentence have already been validated, the function returns `true`.
```java
class Solution {
    public boolean isCircularSentence(String sentence) {
        int n = sentence.length();

        // Check if the last character of the sentence matches the first character.
        // This covers the link between the last and first words, and also the case of a single word.
        if (sentence.charAt(n - 1) != sentence.charAt(0)) {
            return false;
        }

        // Iterate through the sentence to check adjacent words.
        for (int i = 0; i < n; i++) {
            if (sentence.charAt(i) == ' ') {
                // If a space is found, the character before it must match the character after it.
                if (sentence.charAt(i - 1) != sentence.charAt(i + 1)) {
                    return false;
                }
            }
        }

        return true;
    }
}
```
### Algorithm
- Get the length of the sentence, `n`.
- Check if the first character (`sentence.charAt(0)`) is different from the last character (`sentence.charAt(n-1)`). If so, return `false`.
- Iterate through the string with an index `i` from `0` to `n-1`.
- If the character at index `i` is a space:
    - Check if the character at `i-1` (last char of the previous word) is different from the character at `i+1` (first char of the next word).
    - If they are different, return `false`.
- If the loop finishes, it means all conditions are satisfied. Return `true`.

# Solutions
### Java

```java
class Solution {
public
  boolean isCircularSentence(String sentence) {
    var ss = sentence.split(" ");
    int n = ss.length;
    for (int i = 0; i < n; ++i) {
      if (ss[i].charAt(ss[i].length() - 1) != ss[(i + 1) % n].charAt(0)) {
        return false;
      }
    }
    return true;
  }
}

```

### JavaScript

```javascript
/** * @param {string} sentence * @return {boolean} */ var isCircularSentence =
  function (sentence) {
    const ss = sentence.split(" ");
    const n = ss.length;
    for (let i = 0; i < n; ++i) {
      if (ss[i][ss[i].length - 1] !== ss[(i + 1) % n][0]) {
        return false;
      }
    }
    return true;
  };

```

### CPP

```cpp
class Solution {
public:
  bool isCircularSentence(string sentence) {
    auto ss = split(sentence, ' ');
    int n = ss.size();
    for (int i = 0; i < n; ++i) {
      if (ss[i].back() != ss[(i + 1) % n][0]) {
        return false;
      }
    }
    return true;
  }
  vector<string> split(string &s, char delim) {
    stringstream ss(s);
    string item;
    vector<string> res;
    while (getline(ss, item, delim)) {
      res.emplace_back(item);
    }
    return res;
  }
};

```

### Python

```python
class Solution:
    def isCircularSentence(self, sentence: str) -> bool: ss = sentence . split() n = len(ss) return all(s[- 1] == ss[(i + 1) % n][0] for i, s in enumerate(ss))

```
