Find the Oxidation States
Ruby, 288 255 bytes

-&gt;m{h={[?O]=&gt;-2,%w[F Cl]=&gt;-1,%w[H Li Na K Rb Cs Fr]=&gt;1,%w[Be Mg Ca Sr Ba Ra]=&gt;2};a=m.scan /([A-Z][a-z]*\d*)/;r=a.flat_map{|(b)|b=~/(\D+)(\d*)/;[a.size==1?0:h[h.keys.find{|v|v.include?$1}]]*($2=='' ? 1:$2.to_i)};r.map{|j|j||-((r-[p]).inject:+)/r.count(p)}}

Try it online!

Saved 1 byte thanks to Jenkar
Saved 32 more bytes by inlining definitions and removing parentheses

Ungolfed
oxidation_state = -&gt; molecule {
    h = {
        %w[H] =&gt; 1,
        %w[O] =&gt; -2,
        %w[F] =&gt; -1,
        %w[Cl] =&gt; -1,
        %w[Li Na K Rb Cs Fr] =&gt; 1,
        %w[Be Mg Ca Sr Ba Ra] =&gt; 2,
    }
    find_oxidation = -&gt; a {
        k = h.keys.find { |as| as.include?(a) }
        h[k]
    }
    atoms = molecule.scan(/([A-Z][a-z]*\d*)/)
    r = atoms.flat_map { |(a)|
        a.match(/([^\d]+)(\d*)/)
        [atoms.length == 1 ? 0 : find_oxidation[$1]] * ($2=='' ? 1 : $2.to_i)
    }
    r.map { |j|
        sum = r.compact.inject(:+)
        !j ? -sum / r.count(nil) : j
    }
}