Why the loop runs backward
When you call deleteRow(i), Sheets immediately renumbers every row below it. Row 5 becomes row 4, row 6 becomes row 5, and so on. If your loop is running top-down and you delete row 3, your counter advances to row 4 -- which is now the old row 5. The old row 4 is never checked. The first time I hit this, I ended up with alternating empty rows still in the sheet and spent ten minutes wondering why the script had done anything at all.
Starting at getLastRow() and decrementing avoids this entirely. Deleting a row only renumbers rows below it, and below is where you have already been. Every row gets inspected exactly once.