• 【编程题 】HJ64 MP3光标位置(详细注释 易懂)


    题目描述:

    题目链接:MP3光标位置_牛客题霸_牛客网 (nowcoder.com)

    MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。

    现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:

    1. 歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。

    光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。

     

    2. 歌曲总数大于4的时候(以一共有10首歌为例):

    特殊翻页:屏幕显示的是第一页(即显示第1 – 4首)时,光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。

     其他情况,不用翻页,只是挪动光标就行。

    数据范围:命令长度1\le s\le 100\1≤s≤100 ,歌曲数量1\le n \le 150\1≤n≤150 

    进阶:时间复杂度:O(n)\O(n) ,空间复杂度:O(n)\O(n) 

    输入描述:

    输入说明:
    1 输入歌曲数量
    2 输入命令 U或者D

    输出描述:

    输出说明
    1 输出当前列表
    2 输出当前选中歌曲

    示例

    输入

    10
    UUUU
    

    输出

    7 8 9 10
    7

    题目理解:

        这个题目我只能说,又臭又长,读起来太费劲了。它说的意思,就是给你歌曲的总数 n ,然后它会循环进行  上一首歌,下一首歌的切换,要求你在所有的操作完之后。输出当前所在的歌曲下标(从 1 开始)以及当前页面的歌曲。  那么首先要理解切换歌以及切换页面的含义, 切换歌就是下标 加一 ,或者减一 。

            但切换页面比较特殊,当下标在 1 的时候,切上一首歌,它就换为最后一个页面,页面里的歌就是最后4首歌(这里前提是 歌曲数大于4);当下标在 n 的时候,切下一首歌,页面就换为第一个页面,页面里的歌就是前四首歌。只有这两种情况,是我们正常理解的那种切换页面,就是整个的切换, 而另一种情况的切换页面,就只是把歌曲下标变了一下(第一个下标加 1,最后一个下标加一),其他情况不用页面里的歌不变。 

      思路讲解:

          有了上面的思路理解,这个题就好做些了。首先维护一个数组,它就是歌单,然后维护一个下标,它负责指向当前的歌曲。 当歌曲大于4首的时候,从第一首歌变成最后一首歌,就在数组里放最后四首歌,从最后一首歌变成第一首歌时,就把数组里的歌放前四首。当指向歌曲的下标超过数组里最大的值时,就放当前歌曲以及前面的三首歌曲; 当指向歌曲的下标小于数组里最小的值时,就放当前歌曲以及后面的三首歌曲;最后输出歌单数组,以及指向歌曲的下标就好了。 

       

        其实我这是一种比较常规的方法,还有一种巧方法是,用两个指针,分别指向第一首歌和第4首歌(如果n <4 ,就是指向第n首歌),如果指向歌曲的下标从第一首变为最后一首,就把两个指针修改为最后四首,如果指向歌曲的下标从最后一首变为第一首,就把两个指针修改为前四首,如果指向歌曲的下标超出两个指针,就修改指针就好了,没有超出就不动。 最后输出指针里的歌曲下标就可以了。这个思路比我上面用的思路,代码量少了三分之一。

    代码注释:

       

    1. import java.util.*;
    2. public class Main{
    3. public static void main(String[] args){
    4. Scanner scan = new Scanner(System.in);
    5. int n = scan.nextInt();
    6. String command = scan.next();
    7. int index = 1;
    8. int[] musics = new int[4];
    9. // 小于等于四首歌时,不用切换页面,或者说不用维护歌单数组
    10. if(n<= 4){
    11. for(int i=0;i< command.length();i++){
    12. if(command.charAt(i) == 'U'){
    13. index--;
    14. // 如果index 小于1 ,就跳到最后一首歌
    15. if(index == 0)
    16. index = n;
    17. }else{
    18. index++;
    19. if(index > n)
    20. index = 1;
    21. }
    22. }
    23. int value =1;
    24. for(int j=0;j4) ;j++){
    25. musics[j] = value++;
    26. }
    27. // 最后输出数组里的值就好了
    28. for(int i=0;i< Math.min(n,4)-1;i++){
    29. System.out.print(musics[i]+" ");
    30. }
    31. System.out.println(musics[n-1]);
    32. System.out.println(index);
    33. return;
    34. }else{
    35. // 当歌曲数大于 4首时
    36. for(int i=0;i< command.length();i++){
    37. if(command.charAt(i) == 'U'){
    38. index--;
    39. if(index == 0){
    40. index = n;
    41. int value = index-3;
    42. // 如果从第一首歌跳到最后一首,就把数组更新为最后四首歌
    43. for(int j=0;j< 4 && value <= n;j++){
    44. musics[j] = value++;
    45. }
    46. }
    47. // 如果当前歌的下标,小于数组最小值,就放当前歌和后三首
    48. if(index < musics[0]){
    49. int value = index;
    50. for(int j=0;j< 4 && value <= n;j++){
    51. musics[j] = value++;
    52. }
    53. }
    54. // 切为下一首歌
    55. }else{
    56. index++;
    57. // 如果从最后一首歌切位第一首歌,就把数组里放前四首
    58. if(index > n){
    59. index = 1;
    60. int value = index;
    61. for(int j=0;j<4 && value<=n;j++){
    62. musics[j] = value++;
    63. }
    64. }
    65. //如果当前歌的下标,大于数组最大值,就放当前歌和前三首
    66. if(index > musics[3]){
    67. int value = index-3;
    68. for(int j=0;j<4 && value<=n;j++){
    69. musics[j] = value++;
    70. }
    71. }
    72. }
    73. }
    74. }
    75. for(int i=0;i< musics.length-1;i++){
    76. System.out.print(musics[i]+" ");
    77. }
    78. System.out.println(musics[musics.length-1]);
    79. System.out.println(index);
    80. }
    81. }

  • 相关阅读:
    Rest API --如何设计好一个Delete方法的API
    Spark Core个人总结
    大数据学习(22)-spark
    Linux内核基础 - list_move_tail函数详解
    Hadoop大数据系统架构(深入浅出)
    [附源码]计算机毕业设计右脑开发教育课程管理系统Springboot程序
    贯标还是ISO认证,哪个更重要?
    QT编译环境的搭建
    fdbus之CFdbSession类
    【一文秒懂——Profile配置】
  • 原文地址:https://blog.csdn.net/qq_51901495/article/details/125895435