Given a string array names[] containing the names of n students and a 2D integer array marks[][], where marks[i] contains the marks of the i-th student in three subjects, find the student or students having the maximum average score.
The i-th element of names corresponds to the i-th row of marks.
The division is performed using integer division, so the average is rounded down.
If multiple students have the same maximum average, include all their names in the same order as they appear in names.
Return a string containing the names of all students with the maximum average, followed by the maximum average.
Examples:
Input: names[] = ["Shrikanth", "Ram"], marks[][] = [[20, 30, 10], [100, 50, 10]]
Output: Ram 53
Explanation: Shrikanth has an average of (20 + 30 + 10) / 3 = 20, whereas Ram has an average of (100 + 50 + 10) / 3 = 53. Therefore, Ram has the maximum average.Input: names[] = ["Adam", "Rocky", "Suresh"], marks[][] = [[50, 10, 40], [100, 90, 10], [10, 90, 100]]
Output: Rocky Suresh 66
Explanation: Rocky has an average of (100 + 90 + 10) / 3 = 66, and Suresh has an average of (10 + 90 + 100) / 3 = 66. Both have the maximum average, so their names are returned in the same order as they appear in names[].
Table of Content
[Naive Approach] Using Two-Pass Traversal with Extra Array - O(n) Time and O(n) Space
The idea is to first calculate and store the average marks of every student. Then, find the maximum average and collect the names of all students having that average.
Working of Approach:
- Traverse all students and calculate their average marks.
- Store each average in an auxiliary array.
- Find the maximum value from the averages.
- Traverse the array again and collect names having the maximum average.
- Append the maximum average to the final result.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
string studentRecord(vector<string> &names, vector<vector<int>> &marks)
{
int n = names.size();
vector<int> avg(n);
// Calculate and store the average marks of every student.
for (int i = 0; i < n; i++)
{
int sum = marks[i][0] + marks[i][1] + marks[i][2];
avg[i] = sum / 3;
}
// Find the maximum average.
int maxAvg = *max_element(avg.begin(), avg.end());
string res = "";
// Collect all students having the maximum average.
for (int i = 0; i < n; i++)
{
if (avg[i] == maxAvg)
{
if (!res.empty())
{
res += " ";
}
res += names[i];
}
}
// Append the maximum average to the result.
res += " " + to_string(maxAvg);
return res;
}
int main()
{
vector<string> names = {"Adam", "Rocky", "Suresh"};
vector<vector<int>> marks = {{50, 10, 40}, {100, 90, 10}, {10, 90, 100}};
cout << studentRecord(names, marks) << endl;
return 0;
}
import java.util.*;
class GFG {
public String studentRecord(String[] names,
int[][] marks)
{
int n = names.length;
int[] avg = new int[n];
// Calculate and store the average marks of every
// student.
for (int i = 0; i < n; i++) {
int sum
= marks[i][0] + marks[i][1] + marks[i][2];
avg[i] = sum / 3;
}
// Find the maximum average.
int maxAvg = Integer.MIN_VALUE;
for (int i = 0; i < n; i++) {
maxAvg = Math.max(maxAvg, avg[i]);
}
String res = "";
// Collect all students having the maximum average.
for (int i = 0; i < n; i++) {
if (avg[i] == maxAvg) {
if (!res.isEmpty()) {
res += " ";
}
res += names[i];
}
}
// Append the maximum average to the result.
res += " " + maxAvg;
return res;
}
public static void main(String[] args)
{
String[] names = { "Adam", "Rocky", "Suresh" };
int[][] marks = { { 50, 10, 40 },
{ 100, 90, 10 },
{ 10, 90, 100 } };
GFG obj = new GFG();
System.out.println(obj.studentRecord(names, marks));
}
}
def studentRecord(names, marks):
n = len(names)
avg = [0] * n
# Calculate and store the average marks of every student.
for i in range(n):
sum = marks[i][0] + marks[i][1] + marks[i][2]
avg[i] = sum // 3
# Find the maximum average.
maxAvg = max(avg)
res = ""
# Collect all students having the maximum average.
for i in range(n):
if avg[i] == maxAvg:
if res != "":
res += " "
res += names[i]
# Append the maximum average to the result.
res += " " + str(maxAvg)
return res
if __name__ == '__main__':
names = ["Adam", "Rocky", "Suresh"]
marks = [[50, 10, 40], [100, 90, 10], [10, 90, 100]]
print(studentRecord(names, marks))
using System;
class GFG {
public string studentRecord(string[] names,
int[][] marks)
{
int n = names.Length;
int[] avg = new int[n];
// Calculate and store the average marks of every
// student.
for (int i = 0; i < n; i++) {
int sum
= marks[i][0] + marks[i][1] + marks[i][2];
avg[i] = sum / 3;
}
// Find the maximum average.
int maxAvg = int.MinValue;
for (int i = 0; i < n; i++) {
maxAvg = Math.Max(maxAvg, avg[i]);
}
string res = "";
// Collect all students having the maximum average.
for (int i = 0; i < n; i++) {
if (avg[i] == maxAvg) {
if (!string.IsNullOrEmpty(res)) {
res += " ";
}
res += names[i];
}
}
// Append the maximum average to the result.
res += " " + maxAvg;
return res;
}
static void Main(string[] args)
{
string[] names = { "Adam", "Rocky", "Suresh" };
int[][] marks = { new int[] { 50, 10, 40 },
new int[] { 100, 90, 10 },
new int[] { 10, 90, 100 } };
GFG obj = new GFG();
Console.WriteLine(obj.studentRecord(names, marks));
}
}
function studentRecord(names, marks)
{
let n = names.length;
let avg = new Array(n).fill(0);
// Calculate and store the average marks of every
// student.
for (let i = 0; i < n; i++) {
let sum = marks[i][0] + marks[i][1] + marks[i][2];
avg[i] = Math.floor(sum / 3);
}
// Find the maximum average.
let maxAvg = Math.max(...avg);
let res = "";
// Collect all students having the maximum average.
for (let i = 0; i < n; i++) {
if (avg[i] === maxAvg) {
if (res !== "") {
res += " ";
}
res += names[i];
}
}
// Append the maximum average to the result.
res += " " + maxAvg;
return res;
}
// Driver Code
let names = [ "Adam", "Rocky", "Suresh" ];
let marks =
[ [ 50, 10, 40 ], [ 100, 90, 10 ], [ 10, 90, 100 ] ];
console.log(studentRecord(names, marks));
Output
Rocky Suresh 66
[Expected Approach] Using One-Pass Traversal - O(n) Time and O(1) Space
The idea is to calculate each student's average while traversing the array. Update the result whenever a new maximum is found, or add the student when the maximum average is matched.
Working of Approach:
- Initialize maxAvg with a very small value.
- Traverse all students and calculate their average marks.
- If the current average is greater, update maxAvg and reset the result.
- If the current average is equal, append the student's name.
- Finally, append the maximum average to the result.
Let us understand with an example:
Input: names[] = ["Adam", "Rocky", "Suresh"], marks[][] = [[50, 10, 40], [100, 90, 10], [10, 90, 100]]
- Start with maxAvg = INT_MIN and res = "".
- For Adam, average = (50 + 10 + 40) / 3 = 33, so maxAvg = 33 and res = "Adam".
- For Rocky, average = (100 + 90 + 10) / 3 = 66, which is greater than 33, so maxAvg = 66 and res = "Rocky".
- For Suresh, average = (10 + 90 + 100) / 3 = 66, which equals maxAvg, so res = "Rocky Suresh".
- Finally, append maxAvg, giving the result "Rocky Suresh 66".
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
string studentRecord(vector<string> &names, vector<vector<int>> &marks)
{
int maxAvg = INT_MIN;
string res = "";
for (int i = 0; i < names.size(); i++)
{
int sum = marks[i][0] + marks[i][1] + marks[i][2];
int avg = sum / 3;
if (avg > maxAvg)
{
// Found a new maximum
maxAvg = avg;
res = names[i];
}
else if (avg == maxAvg)
{
// Add student with same maximum average
res += " " + names[i];
}
}
return res + " " + to_string(maxAvg);
}
int main()
{
vector<string> names = {"Adam", "Rocky", "Suresh"};
vector<vector<int>> marks = {{50, 10, 40}, {100, 90, 10}, {10, 90, 100}};
cout << studentRecord(names, marks) << endl;
return 0;
}
import java.util.ArrayList;
import java.util.List;
class GFG {
public String studentRecord(String[] names,
int[][] marks)
{
int maxAvg = Integer.MIN_VALUE;
String res = "";
for (int i = 0; i < names.length; i++) {
int sum
= marks[i][0] + marks[i][1] + marks[i][2];
int avg = sum / 3;
if (avg > maxAvg) {
// Found a new maximum
maxAvg = avg;
res = names[i];
}
else if (avg == maxAvg) {
// Add student with same maximum average
res += " " + names[i];
}
}
return res + " " + maxAvg;
}
public static void main(String[] args)
{
String[] names = { "Adam", "Rocky", "Suresh" };
int[][] marks = { { 50, 10, 40 },
{ 100, 90, 10 },
{ 10, 90, 100 } };
GFG obj = new GFG();
System.out.println(obj.studentRecord(names, marks));
}
}
def studentRecord(names, marks):
maxAvg = float('-inf')
res = ""
for i in range(len(names)):
sum = marks[i][0] + marks[i][1] + marks[i][2]
avg = sum // 3
if avg > maxAvg:
# Found a new maximum
maxAvg = avg
res = names[i]
elif avg == maxAvg:
# Add student with same maximum average
res += " " + names[i]
return res + " " + str(maxAvg)
if __name__ == '__main__':
names = ["Adam", "Rocky", "Suresh"]
marks = [[50, 10, 40], [100, 90, 10], [10, 90, 100]]
print(studentRecord(names, marks))
using System;
class GFG {
public string studentRecord(string[] names,
int[][] marks)
{
int maxAvg = int.MinValue;
string res = "";
for (int i = 0; i < names.Length; i++) {
int sum
= marks[i][0] + marks[i][1] + marks[i][2];
int avg = sum / 3;
if (avg > maxAvg) {
// Found a new maximum
maxAvg = avg;
res = names[i];
}
else if (avg == maxAvg) {
// Add student with same maximum average
res += " " + names[i];
}
}
return res + " " + maxAvg;
}
static void Main(string[] args)
{
string[] names = { "Adam", "Rocky", "Suresh" };
int[][] marks = { new int[] { 50, 10, 40 },
new int[] { 100, 90, 10 },
new int[] { 10, 90, 100 } };
GFG obj = new GFG();
Console.WriteLine(obj.studentRecord(names, marks));
}
}
function studentRecord(names, marks)
{
let maxAvg = Number.MIN_VALUE;
let res = "";
for (let i = 0; i < names.length; i++) {
let sum = marks[i][0] + marks[i][1] + marks[i][2];
let avg = Math.floor(sum / 3);
if (avg > maxAvg) {
// Found a new maximum
maxAvg = avg;
res = names[i];
}
else if (avg === maxAvg) {
// Add student with same maximum average
res += " " + names[i];
}
}
return res + " " + maxAvg;
}
// Driver Code
let names = [ "Adam", "Rocky", "Suresh" ];
let marks =
[ [ 50, 10, 40 ], [ 100, 90, 10 ], [ 10, 90, 100 ] ];
console.log(studentRecord(names, marks));
Output
Rocky Suresh 66