As you said the current solution you use already works fine and you shouldn't worry about all the queries that are executed. You're just seeding the application for testing purposes.
You could also use this approach
return [
"title" => fake()->jobTitle(),
"type" => random_int(0, 1), // 0-> online , 1-> In person
"instructor_id" => Instructor::factory(),
"category_id" => CourseCategory::factory(),
"created_by" => User::factory(),
"description" => fake()->paragraph(1),
];
Alternative Solution
An alternative solution that you could use is that if you know upfront that for example 100 users are created when seeding. You can use a random number from 1 to 100 which will match one of those user id's. This will give you the same result and can also be applied for instructor id and category id.
But if you use this 2nd approach and later decrease the amount of users that are created and forget to change this in this factory it will causes issues. So therefor it might be better to use one of the two other solutions.