记录下leetcode的刷题经历,目前在简单阶段

本博客仅仅是为了记录下我在leetcode里学习算法的经历和学习笔记,方便我每周末复习
记录的第一周

1275、 井字棋的获胜者

A 和 B 在一个 3 x 3 的网格上玩井字棋。

井字棋游戏的规则如下:

玩家轮流将棋子放在空方格 (" ") 上。
第一个玩家 A 总是用 "X" 作为棋子,而第二个玩家 B 总是用 "O" 作为棋子。
"X" 和 "O" 只能放在空方格中,而不能放在已经被占用的方格上。
只要有 3 个相同的(非空)棋子排成一条直线(行、列、对角线)时,游戏结束。
如果所有方块都放满棋子(不为空),游戏也会结束。
游戏结束后,棋子无法再进行任何移动。

给你一个数组 moves,其中每个元素是大小为 2 的另一个数组(元素分别对应网格的行和列),它按照 A 和 B 的行动顺序(先 A 后 B)记录了两人各自的棋子位置。

如果游戏存在获胜者(A 或 B),就返回该游戏的获胜者;如果游戏以平局结束,则返回 “Draw”;如果仍会有行动(游戏未结束),则返回 “Pending”。

你可以假设 moves 都 有效(遵循井字棋规则),网格最初是空的,A 将先行动。

class Solution {
    public String tictactoe(int[][] moves) {
        //构建一个3**3的棋盘
        int[][] ches=new int[3][3];
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                ches[i][j]=0;
            }
        }
        /**遍历move数组,我是这样理解的:先建立个一维数组,然后存储在该数组的0和1的位置上move的行元素和列元素
        *如果ches[][]=1,则是A下的,反之则是B下的;
        */
        int count=0;
        for(int[] move:moves){
            if(count%2==0)
                ches[move[0]][move[1]]=1;//例如第一个moves元素为[0,0],那move[0]=0,move[1]=0;
            else
                ches[move[0]][move[1]]=-1;
            count++;
        }

        //进行判断,每一行和每一列的判断
        for(int i=0;i<3;i++){
           int rowsum=0;
           int colsum=0;
           for(int j=0;j<3;j++){
              rowsum += ches[i][j];
              colsum += ches[j][i];
           }
           if(rowsum==3 || colsum==3)
               return "A";
            if(rowsum==-3||colsum==-3)
              return "B";
        }
        //斜线只有两种情况,直接强行判断
        int biassum1=ches[0][0]+ches[1][1]+ches[2][2];
        int biassum2=ches[0][2]+ches[1][1]+ches[2][0];
        if(biassum1==3||biassum2==3)
           return "A";
        if(biassum1==-3||biassum2==-3)
           return "B";
        //当moves数组长度为9时,则全部都下完了
        if(moves.length==9)
           return  "Draw";
        //所有情况列举完毕,都不符合返回没下完
        return "Pending";

    }
}

思路:采用暴力破解法莱进行解决
1、绘制张3*3的棋盘,A下的地方为1,B下的地方为-1;
2、遍历系统输入的数组
3、计算水平方向、竖直方向、两个对角线之和并判断胜利方
4、若没有胜利这则看系统输入长度是否为9,是则平局,反之就是没下完。

70、爬楼梯【动态规划的典型例题】

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

class Solution {
    public int climbStairs(int n) {
      int[] dp=new int[n+1];
      if(n==1)
        return n;
      dp[1]=1;
      dp[2]=2;
      for(int i=3;i<=n;i++){
          dp[i]=dp[i-1]+dp[i-2];
      }
      return dp[n];


    }
}

思路:本问题其实常规解法可以分成多个子问题,爬第n阶楼梯的方法数量,等于 2 部分之和

爬上 n−1n-1n−1 阶楼梯的方法数量。因为再爬1阶就能到第n阶
爬上 n−2n-2n−2 阶楼梯的方法数量,因为再爬2阶就能到第n阶

所以我们得到公式
dp[n]=dp[n−1]+dp[n−2]dp[n] = dp[n-1] + dp[n-2]dp[n]=dp[n−1]+dp[n−2]
同时需要初始化
dp[0]=1dp[0]=1dp[0]=1 和 dp[1]=1dp[1]=1dp[1]=1

83、删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode p=head;
        while(p != null && p.next != null){
            if(p.next.val == p.val){
                p.next=p.next.next;
            } else{                    
               p=p.next;
            }
        } 
        return head;  
    }
}

思路:直接暴力遍历,因为链表是有序的,所有如果下一个节点的值等于该节点值,那么该节点指向下下个节点,反之节点向后移。(非常简单的一题链表的题目,值得注意,最后返回头结点)

88、合并两个有序数组给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。

说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
这题有两种思路,一种是直接利用Java的函数,先合并在排序。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
       System.arraycopy(nums2, 0, nums1, m, n);
        Arrays.sort(nums1);
    }
}

还有一种思路就是从nums1数组的后面进行插入(所有nums1和nums2都从末尾开始遍历),此时有三种情况:
1、nums1和nums2都没遍历完,当nums1的元素大于nums2时,nums1末尾元素为nums[m-1],且nums末尾指针向前移;反之nums1末尾元素为nums2[n-1],数组末尾指针迁移
2、nums1中m个元素遍历完后,将nums2剩余元素添加到nums1中
3、nums2中n个元素遍历完后,将nums1剩余元素添加到nums1中

class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
        int pos = m + n - 1;
        int s1 = m - 1;
        int s2 = n - 1;
        while (s1 >= 0 && s2 >= 0) {
            if (nums1[s1] >= nums2[s2]) {
                nums1[pos--] = nums1[s1--];
            } else {
                nums1[pos--] = nums2[s2--];
            }
        }
        while (s1 >= 0) {
            nums1[pos--] = nums1[s1--];
        }
        while (s2 >= 0) {
            nums1[pos--] = nums2[s2--];
        }

    }
}

由于要准备蓝桥杯的比赛,目前无法满足每天刷一道leetcode的要求,改成每天刷两道蓝桥杯例题,但仍然会不定时记录我的leetcode刷题之路。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值