506. Relative Ranks

本文介绍了一种算法,用于确定N位运动员的相对排名,并为前三名分配金牌、银牌和铜牌。通过使用优先队列或映射的方式,该算法能够高效地处理这一问题。

Given scores of N athletes, find their relative ranks and the people with the top three highest scores, who will be awarded medals: "Gold Medal", "Silver Medal" and "Bronze Medal".

Example 1:

Input: [5, 4, 3, 2, 1]
Output: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"]
Explanation: The first three athletes got the top three highest scores, so they got "Gold Medal", "Silver Medal" and "Bronze Medal". 
For the left two athletes, you just need to output their relative ranks according to their scores.
思路:对于给予的得分情况,找出前三名并给予相应的称号,其余以数字作为其名词,利用优先队列进行记录每个元素的位置和元素值,优先队列的特点是top始终是所有元素中最大的那个。



class Solution {
public:
    vector<string> findRelativeRanks(vector<int>& nums) {
        vector<string> res(nums.size());
        priority_queue<pair<int,int>> temp;
        for(size_t i=0,len=nums.size();i<len;++i)
            temp.push({nums[i],i});
        int count=1;
        while(temp.size())
        {
            auto elem=temp.top();
            temp.pop();
            if(count==1)
                res[elem.second]="Gold Medal";
            else if(count==2)
                res[elem.second]="Silver Medal";
            else if(count==3)
                res[elem.second]="Bronze Medal";
            else
                res[elem.second]=to_string(count);
            ++count;
        }
        return res;
        
    }
};

第二种方法,可以用map来解决,将nums中的元素值作为map的index从而实现将nums排序,同时保存nums的index到map中

class Solution {
public:
    vector<string> findRelativeRanks(vector<int>& nums) {
        vector<string> res(nums.size());
        map<int,int>ma;
        for(int i=0;i!=nums.size();++i)
            ma[nums[i]]=i;
        int count=1;
        for(map<int,int>::reverse_iterator it=ma.rbegin();it!=ma.rend();++it,++count)
        {
            if(count==1)
                res[it->second]="Gold Medal";
            else if(count==2)
                res[it->second]="Silver Medal";
            else if(count==3)
                res[it->second]="Bronze Medal";
            else
                res[it->second]=to_string(count);
        }
        return res;
        
    }
};












% 生成 3阶测试张量 clear; start_t = datetime('now'); X = create_symmetric_tensor(5,3); % 设置 TR 秩 (注意首尾秩需相等) ranks = [2,3,3]; % ranks(1) = ranks(end) % 正确参数设置 params = struct(... 'maxiters', 200, ... % 最大迭代次数 'tol', 1e-8, ... % 收敛阈值 'verbose', true, ... % 显示迭代信息 'conv_crit', 'relative error' ... % 收敛准则 ); % 执行分解 [cores, conv_history] = tr_als(X, ranks, params); cores1=cat(3,cores{1,:}); cores2=cat(3,cores{2,:}); cores3=cat(3,cores{3,:}); % 验证结果 reconstructed = cores_2_tensor(cores); error = norm(X(:) - reconstructed(:)) / norm(X(:)); disp(['相对重构误差: ', num2str(error)]); % 绘制图形 duration = milliseconds(datetime('now') - start_t)function [cores, varargout] = tr_als(X, ranks, varargin) %tr_als Compute tensor ring decomposition via alternating least squares % %cores = tr_als(X, ranks) computes a tensor ring (TR) decomposition of the %input N-dimensional array X. ranks is a length-N vector containing the %target ranks. The output cores is a cell containing the N cores tensors, %each represented as a 3-way array. % %cores = tr_als(___, 'tol', tol) is an optional argument that controls the %termination tolerance. If the change in the relative error is less than %tol at the conclusion of a main loop iteration, the algorithm terminates. %Default is 1e-3. % %cores = tr_als(___, 'maxiters', maxiters) is an optional argument that %controls the maximum number of main loop iterations. The default is 50. % %cores = tr_als(___, 'verbose', verbose) is an optional argument that %controls the amount of information printed to the terminal during %execution. Setting verbose to true will result in more print out. Default %is false. % %This algorithm is based on Alg. 2 in paper by %Q. Zhao, G. Zhou, S. Xie, L. Zhang, A. Cichocki. "Tensor ring %decomposition". arXiv:1606.05535, 2016. %% Handle optional inputs params = inputParser; addParameter(params, 'conv_crit', 'none'); addParameter(params, 'tol', 1e-3, @isscalar); addParameter(params, 'maxiters', 50, @(x) isscalar(x) & x > 0); addParameter(params, 'verbose', false, @isscalar); parse(params, varargin{:}); conv_crit = params.Results.conv_crit; tol = params.Results.tol; maxiters = params.Results.maxiters; verbose = params.Results.verbose; %% Initialize cores sz = size(X); cores = initialize_cores(sz, ranks); if nargout > 1 && tol > 0 && (strcmp(conv_crit, 'relative error') || strcmp(conv_crit, 'norm')) conv_vec = zeros(1, maxiters); end %% Main loop % Iterate until convergence, for a maximum of maxiters iterations N = length(sz); er_old = Inf; for it = 1:maxiters for n = 1:N % Compute G_{[2]}^{\neq n} from cores G = subchain_matrix(cores, n); % Compute relevant unfolding of data tensor X XnT = mode_unfolding(X, n).'; % Solve LS problem and update core Z = (G \ XnT).'; cores{n} = classical_mode_folding(Z, 2, size(cores{n})); end % Check convergence: Relative error if tol > 0 && strcmp(conv_crit, 'relative error') % Compute full tensor corresponding to cores Y = cores_2_tensor(cores); % Compute current relative error er = norm(X(:)-Y(:))/norm(X(:)); if verbose fprintf('\tRelative error after iteration %d: %.8f\n', it, er); end % Save current error to conv_vec if required if nargout > 1 conv_vec(it) = er; end % Break if change in relative error below threshold if abs(er - er_old) < tol if verbose fprintf('\tRelative error change below tol; terminating...\n'); end break end % Update old error er_old = er; % Check convergence: Norm change elseif tol > 0 && strcmp(conv_crit, 'norm') % Compute norm of TR tensor and change if it > 1 norm_new = normTR(cores); if it == 1 norm_change = Inf; else norm_change = abs(norm_new - norm_old); if verbose fprintf('\tNorm change after iteration %d: %.8f\n', it, norm_change); end end % Save current norm_change to conv_vec if nargout > 1 conv_vec(it) = norm_change; end % Break if change in relative error below threshold if norm_change < tol if verbose fprintf('\tNorm change below tol; terminating...\n'); end break end % Update old norm norm_old = norm_new; % Just print iteration count else if verbose fprintf('\tIteration %d complete\n', it); end end end if nargout > 1 && exist('conv_vec', 'var') varargout{1} = conv_vec(1:it); else varargout{1} = nan; end end function cores = initialize_cores(sz, ranks, varargin) %initialize_cores Initializes cores using Gaussian distribution % %cores = initialize_cores(sz, ranks) returns a length-N cell with N cores, %each with entires drawn iid from the standard Gaussian distribution. sz is %a length-N vector with the sizes, and ranks is a length-N vector with the %outgoing ranks. % %cores = initialize_cores(___, 'init_zero', init_zero) will just initialize %all cores to zero if init_zero is true. Default is false. % Handle optional inputs params = inputParser; addParameter(params, 'init_zero', false, @isscalar); parse(params, varargin{:}); init_zero = params.Results.init_zero; % Main code N = length(sz); cores = cell(N,1); for n = 1:N R1 = ranks(n); if n == 1 R0 = ranks(end); else R0 = ranks(n-1); end if init_zero cores{n} = zeros(R0, sz(n), R1); else cores{n} = randn(R0, sz(n), R1); end end end,修改代码,使得初始点是固定的一个随机种子生成,而不是高斯分布生成的
最新发布
11-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值