I find projects more motivating and satisfying. The feeling you get when you solve your own problem with a code you have written is great. Trying to make your own life better, or just working on something that you find fun, usually helps to keep you interested for longer. Vision of the goal you are trying to achieve helps to push through the difficult moments.
But projects are hard to scope, especially when you are just starting and you don’t have much experience. It’s easy to take a project that is too big or too difficult. And I guess there’s a risk of only reiterating all the things and tools you already know - project might not push you to face completely new things.
I guess one of the main benefits of challenges is that it’s easier to find time to work on them. Many of them are specifically designed to take 15-60 minutes. So sometimes you might feel you don’t really have time to make a visible change in your project, but you do have a time to complete a challenge or two.
Data Structures are overemphasized by CompSci 101 courses. They matter in things like C, where standard library does not even provide things like hash table or doubly linked list. But these are old problems solved decades ago and refined over time. You won’t write better hash table than the one that Java has built in. So just read about various data structures provided by Java and their main properties, so you can reach out for a right tool for the problem you are facing. But that’s literally one evening of reading, and perhaps few more for repetition.
Similar with algorithms. Most algorithms discussed in CompSci are pretty detached from algorithms you are going to need in everyday work. What’s worse, many of these algorithms are optimized over the years, and optimized version is usually much harder to follow than naive version.
What helps is training algorithmic thinking. Thinking about a problem and steps you need to take to solve it, and making these steps explicit. It might be helpful to get some exposure to algorithm optimization - what is the naive version of a solution and how and why it may be optimized further, until you arrive to something closer to optimal version available in libraries. But “premature optimization is the root of all evil”, “measure twice, cut once” etc. In most of everyday work tasks, just not doing careless things will provide acceptable performance.
Of course some companies are committed to testing LeetCode, algorithms and data structures during the hiring process, even if these things have very little to do with actual job. So if your main goal is getting hired, you might want to take that into account.