I used SQL Server 2008 to these three variations of the aquery.  In my testing I queries the AdventureWorks DB using ProductInventory in the Production schema.  The three queries are:
declare @max int
Select @max =  MAX(Quantity) FROM [AdventureWorks].[Production].[ProductInventory]
SELECT TOP 1000 [ProductID]
      ,[LocationID]
      ,[Shelf]
      ,[Bin]
      ,[Quantity]
      ,[rowguid]
      ,[ModifiedDate]
  FROM [AdventureWorks].[Production].[ProductInventory]
  WHERE Quantity = @max
SELECT TOP 1000 [ProductID]
      ,[LocationID]
      ,[Shelf]
      ,[Bin]
      ,[Quantity]
      ,[rowguid]
      ,[ModifiedDate]
  FROM [AdventureWorks].[Production].[ProductInventory]
  WHERE Quantity = (Select MAX(Quantity) FROM [AdventureWorks].[Production].[ProductInventory])
SELECT TOP 1000 AW1.[ProductID]
      ,AW1.[LocationID]
      ,AW1.[Shelf]
      ,AW1.[Bin]
      ,AW1.[Quantity]
      ,AW1.[rowguid]
      ,AW1.[ModifiedDate]
  FROM [AdventureWorks].[Production].[ProductInventory] AW1
LEFT JOIN [AdventureWorks].[Production].[ProductInventory] AW2 ON AW1.Quantity < AW2.Quantity
WHERE AW2.ProductID IS NULL; 
Using the "Show estimated query plan" icon I can compare the exection events for three cases.  The results are:
- Declaring a variable and filling the variable is 5% faster than a sub-select in the where clause.
- The join is 98% slower than the subselect
- The join is 99% slower than the variable
My suggestion is to declare a variable and fill it.  Use the variable in the WHERE clause