Algorithmic Approaches For Solving Hard Problems: Approximation And Complexity