.subtitle will apply to any element that has a class attribute that contains subtitle, regardless of its type or other entries in the class attribute. For example, .subtitle {} will match all of the following elements:
<h1 class="subtitle">Subtitle</h1>
<h2 class="red-text subtitle">Subtitle</h2>
<p class="subtitle text-center">Centered subtitle</p>
However, h2[class=subtitle] will only ever target <h2> elements that have a class attribute matching subtitle. It won't match if the classname has additional values, or if the element is not an <h2>, i.e.:
<h2 class="subtitle"> <!-- matches -->
<h2 class="subtitle red"> <!-- won't match -->
<h1 class="subtitle"> <!-- won't match -->
It's worth noting about specificity, however. h2[class=subtitle] is more specific than just .subtitle so any styles contained it will override those defined inside of .subtitle.
As a general rule, you should avoid writing [class=] selectors though, since they're very specific and make it difficult to reuse your stylesheet for other elements, and mean a refactor is necessary if your markup changes.
The square bracket notation is actually called the "attribute selector", and can be used for selecting elements based on their attributes and values. You can read more about it here. It's also worth noting that it's possible to use equality checks other than = inside of the attribute selector, as explained in the Syntax section of the MDN link above.