Actual O(n) lol
Intuitionlol at some of solutions here.If for every number up to n you are iterating through its digits (or worse, converting it to a string prior), then you ar
# Intuition
lol at some of solutions here.

If for every number up to $n$ you are iterating through its digits (or worse, converting it to a string prior), then you are making an iteration bound to $log_{10}n$. Divide it by 2 if you want to make it on average. So you have nlogn.

# Actual O(n)

You can make a hash set starting with {1,2,3,...9}. Then until your max element is >= n, Make a new hash set by adding 10^p*(1,2,3,...,9) to every element in the hash set. Do not include the elements of the prior set. Use this new hash set for the base of the next one.

In a second hash set store all the numbers you have generated with this.

Mind you that there are no collisions in forming these numbers so you end up with O(n) to create the set.

Then do the iteration from i=1 to n/2 and check if both i and its complement are in the second set.

Though with this you end up with O(n) memory too and you have no chance of early returning with this.

# Code

I didn't do the o(n) solution above though.

```cpp []
class Solution {
public:
    bool hasZero(int n) {
        if (!n) return true;
        while (n) {
            if (n % 10 == 0) return true;
            n /= 10;
        }
        return false;
    }
    vector<int> getNoZeroIntegers(int n) {
        std::vector<int> answer{2, 0};
        for (int i = 1; i <= n; ++i) {
            if (!hasZero(i) && !hasZero(n-i)) {
                answer[0] = i;
                answer[1] = n-i;
                return answer;
            }
        }
        return answer;
    }
};
```
['C++']