leetcode-AC代码

1.从下往上按层打印二叉树

class Solution {
public:
	vector<vector<int>> levelOrderBottom(TreeNode * root) {
		
		vector<vector<int>> result;
		if (root == NULL)
		{
			return result;
		}
		queue<TreeNode*> q;
		q.push(root);
		while (!q.empty())
		{
			vector<int> v;
			int size = q.size();//精华所在,当前层需要出队列的元素个数直接可得到
			for (int i = 0; i < size; i++)
			{
			    TreeNode* tmp = q.front();
				q.pop();
				v.push_back(tmp->val);
				if (tmp->left != NULL)
					q.push(tmp->left);
				if (tmp->right!=NULL)
					q.push(tmp->right);
			}
			result.push_back(v);
		}
		reverse(result.begin(), result.end());//灵魂操作,使用函数直接翻转
		return result;

	}
};

 

 

70,爬楼梯

第一种方法:动态规划

class Solution {
public:
    int climbStairs(int n) {
        vector<int> dp(n+1,-1);
        dp[0]=1;
        dp[1]=1;
        for(int i=2;i<=n;i++)
            dp[i]=dp[i-1]+dp[i-2];
        return dp[n];
    }
};

343,整数切分

方法一:函数递归+记忆化搜索

函数递归+记忆化搜索
从上到下的思路,将拿到的整数n分成 1-> (n-1),在计算每一种情况的余下的部分拆分后乘积的最大值 
完美的递归思路,

class Solution {
public:
    vector<int> memo;//因为是递归函数,所以在函数外定义
    int max3(int x,int y,int z)
    {
        int tmp=0;
        tmp=x>y?x:y;
        return tmp>z?tmp:z;
    }
        
    int  _integerBreak(int n)
    {
        if(n==1)//划分到 1了,那就不用划分了
            return 1;
        if(memo[n]!=-1)//记忆化搜索,和斐波那契数列一样,存在很多重复计算,如果已经计算过了就直接返回。
            return memo[n];
        
        int res=-1;//这个值用来保存最大的乘积和。
        for(int i=1;i<n;i++)
        {
            res=max3(res,i*(n-i),i*_integerBreak(n-i));
        }
        memo[n]=res;//每次计算完一个数的最大乘积和就保存起来。
        return res;//返回这次递归的计算值
    }
    
    int integerBreak(int n) {
        memo=vector<int>(n+1,-1);//虽然在函数外声明vector,在函数内定义的方式
       return  _integerBreak(n);//
    }
};

方法二:动态规划

//动态规划,自底向上分析法

class Solution {
public:
    int max3(int x,int y,int z)
    {
        return max(x,max(y,z));
    }
       
    int integerBreak(int n) {
        assert(n>=2);
        vector<int> dp(n+1,-1);//个数定为n+1 才有dp[n],方便一一对应,dp[n]表示数字n的最大组合乘积
        dp[1]=1;//1不同切割,直接返回1
        for(int i=2;i<=n;i++)//这层循环用来将2——n中所有的数字遍历,
        {
            for(int j=1;j<=i-1;j++)//拿到2--n中的一个数字i,就划分出1 -- i-1  种情况
            {
                dp[i]=max3(dp[i],j*(i-j),j*dp[i-j]);//每一种情况都可能会改变dp[i],
                                                    //所以将现有的dp[i],当前情况切分一次的乘积
                                                    //,和当前情况切分多次的乘积比较找出最大值
                                                    //把每种情况都遍历完,就能找到最大值。
            }
        }
        return dp[n];
    }
};

198,打家劫舍

方法一:递归+记忆

//函数递归,记忆化搜索法
class Solution {
public:
    vector<int> dp;//下标为i的元素表示[i,n-1]区间内最大价值
    int _rob( vector<int> nums,int index)  //这个函数就是求[index,n-1]的最大价值
    {
        if(index>=nums.size())//没有可以偷盗的房间了,那么可偷盗的价值是0
            return 0;
        if(dp[index]!=-1)//如果[index,n-1]的区间已经计算过了,就不用计算了
            return dp[index];
        
        int res=0;
        for(int i=index;i<nums.size();i++)//[index,n-1]的所有情况
        {
            if(i<=index+1)   //如果是区间[index,n-1],那么必定会从index号房间,或者index+1号房间选择一个
                             //所以只需处理这两种情况,并递归处理两种情况对应的选择
                res=max(res,nums[i]+_rob(nums,i+2) );
        }
        dp[index]=res;
        return res;
    }
    int rob(vector<int>& nums) {
        int n=nums.size();
        dp=vector<int>(n+1,-1);//申请n+1个空间,那么才有dp[n]
        return _rob(nums,0);
    }
};

方法二:动态规划

//动态规划方法

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size()==0)//如果数组没有值,那抢劫的价值就是0
            return 0;
        
        int n=nums.size();
        vector<int> dp(nums.size(),-1);//下标为index的元素的值表示在区间[index,n-1]内,抢劫的最大价值
        dp[n-1]=nums[n-1];//定义初始状态
        
        for(int i=n-2;i>=0;i--)//这层循环表示房间数逐渐增加,我们需要从简到繁,所以倒着来
        {
            for(int j=i;j<n;j++)//将[i,n-1]区间内的所有盗窃情况罗列出来
            {
                if(j<=i+1)//实际上只需要罗列盗窃i号房间或者i+1号房间的情况,因为最大值定会出现在这两种情况内
                {
                    dp[i]=max(dp[i],nums[j]+  (j+2<n ? dp[j+2]:0) );//存在j+2越界的情况,所以判断一下
                }
            }
        }
        return dp[0];//最后返回[0,n-1]的盗窃最大值
    }
};

 

 

75.颜色分类

一个数组中只有012,请排序

//中心思想是三路快排法
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n=nums.size();
        int zero=-1;//[0,zero]全部存放0,所以一开始zero等于-1,表示区间内没有0
        int two=n;  //[two,n-1]全部存放2,所以一开始two等于n,表示区间内没有2
        for(int i=0;i<two;)//注意这里不用i++
        {
            if(nums[i]==1)//先不用管往后走,找到0再进行交换就行
                i++;
            else if(nums[i]==0)
            {
                zero++;
                swap(nums[i],nums[zero]);
                i++;//交换后[0,i]都是有序的
            }
            else
            {
                two--;
                swap(nums[i],nums[two]);//将没有处理的数交换过来了,所以不能i++,继续检查i
            }
        }
    }
};

 

167.两数之和 II - 输入有序数组

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。

函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2

说明:

  • 返回的下标值(index1 和 index2)不是从零开始的。
  • 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。

示例:

输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

方法一 


//主要的思想是 首先遍历一遍数组,并且在当前元素的以后的数组中利用二分查找寻找 target-numbers[i]
//在这里肯定会想,我怎么只管后面的,不管前面的数字呢
//事实上,如果前面的数字和当前数字可以满足条件,那么在遍历前面数字的时候就找到了。不会到后面来了
//二分查找的时间复杂度为O(lgn),所以总的时间复杂度为O(nlgn)
//暴力查找的时间复杂度为O(N^2)
class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int n=numbers.size();
        vector<int> result;
       
        for(int i=0;i<n-1;i++)//最后一个数就不用检查了
        {
            int ret=BinarySearch(numbers,i+1,n,target-numbers[i]);//区间[i+1,n)里面找
            if(ret!=-1)
            {
                result.push_back(i+1);
                result.push_back(ret+1);
                return result;
            }   
        }
        return result;
    }
    
    int BinarySearch(vector<int>& numbers,int left,int right,int target)
    {
        while(left<right)
        {
            int mid=left+(right-left)/2;
            if(numbers[mid]==target)
                return mid;
            else if(numbers[mid]>target)
                right=mid;
            else
                left=mid+1;
        }
        return -1;
    }
};

方法二

//中心思想:因为数组是有序的,将左右端点相加,满足就返回,
//         和大于target,那就缩小和,将right--
           和小于target,那就增大和,将left++
class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        vector<int> result;
        int n =numbers.size();
        int left=0;
        int right=n-1;
        while(left<right)//不需要等于号,left和right相等时,表示一个数字,肯定错误
        {
            if(numbers[left]+numbers[right]==target)
            {
                result.push_back(left+1);
                result.push_back(right+1);
                return result;
            }
            else if(numbers[left]+numbers[right]>target)
                right--;
            else
                left++;
        }
        return result;
    }
};

199,二叉树的右侧视图

//主要的思想是:利用从上到下按层遍历的思想,但只是将每层的最后一个节点入vector
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        vector<int> result;
        if(root==NULL)return result;
        TreeNode* pCur=NULL;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty())//层序遍历只要一个条件
        {
            int size=q.size();//将本层要遍历的节点数拿到
          
            for(int i=0;i<size;i++)
            {
                pCur=q.front();
                q.pop();
                if(pCur->left!=NULL)
                    q.push(pCur->left);
                if(pCur->right!=NULL)
                    q.push(pCur->right);
            }
            result.push_back(pCur->val);//出了for循环,pCur刚好是最后一节点
        }        
        return result;
    }
};

1.两数之和

 

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> record;
        for(int i=0;i<nums.size();i++)//遍历每个元素,如果直接将每个元素放入map中
                                      //重复的元素会被覆盖,如目标=8,两个元素为4
                                      //所以每次加入一个元素前
                                      //先在map中寻找有没有满足的元素,如果有就返回
                                      //如果没有即便是覆盖了也没事
        {
            int other=target-nums[i];
            if(record.find(other)!=record.end())//find函数遍历map,找不到就到end位置了
            {
                int array[2]={record[other],i};//找到了就把两个索引放入数组中
                vector<int>result(array,array+2);
                return result;
            }
            record[nums[i]]=i;//在map中插入 nums[i]:i这个键值对
        }
    }
};

209.长度最小的子数组

给定一个含有 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组

如果不存在符合条件的连续子数组,返回 0。

示例: 

输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3]
class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int n =nums.size();
        if(n==0)return 0;
        
        int left=0;
        int right=-1;//left和right组成滑动窗口,所以一开始right=-1表示区间为空
        int sum=0;//
        int res=n+1;//用来记录最短子数组
        while(left<n)//当左指针到达最后元素时,才算结束
        {
            if(right+1<n && s>=sum)//条件1 为了防止数组越界
            {
                right++;//注意。先加加
                sum+=nums[right];//使滑动窗口增大
            }
            else
            {
                sum-=nums[left];//注意先减掉左端元素,使滑动窗口缩小
                left++;
            }
            
            if(sum>=s)//每次滑动窗口改变都检查一下是否可以更新最小子数组长度
                res=min(res,right-left+1);//参数2表示当前窗口长度
        }
        if(res==n+1)//要是没有解,就返回0
            return 0;
        return res;
    }
};

 

 3.无重复字符的最长子串

给定一个字符串,找出不含有重复字符的最长子串的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 无重复字符的最长子串是 "abc",其长度为 3。

//利用的是滑动窗口
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n =s.size();
        int left=0;
        int right=-1;
        int res=0;
        int freq[256]={0};//保存所有的字符在滑动窗口中的出现情况
        
        while(left<n)//外层循环的条件还是左端点到达最右边的时候
        {
            if(right+1<n && freq[s[right+1]]==0)//右端点也要防止越界,并且下一个元素不在滑                                                 //动窗口中
            {
                right++;
                freq[s[right]]++;
            }
            else
            {
                freq[s[left]]--;//下一个元素在滑动窗口中,那么就只能左端点向前移动去掉相同的                                 //元素
                left++;
            }
            res=max(res,right-left+1);//更新最大不同子数组长度
        }
        return res;
    }
};

454.四数相加 II

给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0

为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间,最终结果不会超过 231 - 1 。

例如:

输入:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]

输出:
2

解释:
两个元组如下:
1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
//主要的思路:暴力层层遍历的方式时间复杂度为O(n^4)
             //将一个数组放入unodered_map中,层层遍历其他三个数组,时间复杂度为O(N^3)
             //也可以选择将两个数454.
四数相加 II组的所有组合都放入unordered_map中,层层遍历其他两个数组
             //这样的时间复杂度为O(N^2)对于500*500的数量级来说是easy的
             //空间复杂度为O(N^2)
class Solution {
public:
    int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
        int n=A.size();
        int res=0;
        unordered_map<int,int>mymap;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                mymap[C[i]+D[j]]++;//将两个数组的所有组合加入map中
            }
        }
        
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if( mymap.find(0-A[i]-B[j])!=mymap.end() )
                {
                    res+=mymap[0-A[i]-B[j]];  
                }
            }
        }
        return res;
    }
};

447.回旋镖的数量

给定平面上 n 对不同的点,“回旋镖” 是由点表示的元组 (i, j, k) ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序)。

找到所有回旋镖的数量。你可以假设 n 最大为 500,所有点的坐标在闭区间 [-10000, 10000] 中。

示例:

输入:
[[0,0],[1,0],[2,0]]

输出:
2

解释:
两个回旋镖为 [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]]
//主要的思路是:使用层层遍历的方式,时间复杂度为O(N^4),接受不了
//             每次拿出一个点,再循环拿出其它点,计算其他点与该点的距离
//             并将距离作为键,将该距离出现的次数定为值,作为键值对存入map
//             对于当前点来说,满足条件的三元点个数就是各个距离的长度对应的次数*次数-1的和
//            比如距离为5的点有4个,那么就从这四个中选择两个就行了所以是=4*3,再将所有距离加和

class Solution {
public:
    int numberOfBoomerangs(vector<pair<int, int>>& points) {
        
       
        int res=0;
        //首先遍历整个vector
        for(int i=0;i<points.size();i++)
        {
            //定义一个map,键=当前元素与其他元素的距离,值=同一距离的其他元素的个数
             unordered_map<int,int>record;//每次循环执行到这里就对map重新初始化,相当于清空
            for(int j=0;j<points.size();j++)
            {
                if(i!=j)//不是相同的点的时候
                {
                    record[ dis(points[i],points[j]) ]++;//计算出一个距离,放入map,并++,                                                        // 始值为0
                }
            }
            for(unordered_map<int,int>::iterator iter=record.begin();//遍历map
                                          iter!=record.end();iter++)
                               {
                                    res+=(iter->second)*(iter->second-1);               
                               }
        }
                               return res;
    }
    
        long dis(pair<int,int>& p1,pair<int,int>& p2 )
            //计算两点间的距离((x1-x2)^2)+((y1-y2)^2)开根号
            //因为开根号会导致出现浮点数,但我们只是就算距离是否相等,所以这里不开方,也能比较
        {
            return (p1.first-p2.first)*(p1.first-p2.first)+
                    (p1.second-p2.second)*(p1.second-p2.second);
        }
};

 

104,二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3 。

//要深刻明白二叉树本身就是递归结构
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(root==NULL)
            return 0;
        int left=maxDepth(root->left);
        int right=maxDepth(root->right);
        return max(left,right)+1;//+1是加上当前节点
    }
};

226,翻转二叉树

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root==NULL)
            return NULL;
        invertTree(root->left);
        invertTree(root->right);
        swap(root->left,root->right);
        return root;
    }
};

112,路径总和

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例: 
给定如下二叉树,以及目标和 sum = 22

              5
             / \
            4   8
           /   / \
          11  13  4
         /  \      \
        7    2      1

返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2

//中心的思想:将当前的节点值减掉后交给左右节点去比较
class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if(root==NULL)//要确保第一次不为空
            return false;
        if(root->left==NULL && root->right==NULL)//确保是叶子节点
        {
            return sum==root->val;
        }
        if(hasPathSum(root->left,sum-root->val))
            return true;
        if(hasPathSum(root->right,sum-root->val))
            return true;
        return false;//前面没有返回,那么就是不符合
    }
};

111,二叉树的最小深度

 

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回它的最小深度  2.

//容易出错的点是,遇到一个节点为NULL就返回0,其实应该在叶子节点处才返回0,其他的null节点不用管
class Solution {
public:
    int minDepth(TreeNode* root) {
        if(root==NULL)
            return 0;
        if(root->left==NULL)//若左节点为NULL,那么就只用管右节点了
            return minDepth(root->right)+1;
        if(root->right==NULL)//若右节点为NULL,就只管左节点,记住要+1,表示当前节点
            return minDepth(root->left)+1;
        if(root->left==NULL && root->right==NULL)//左右都是NULL,返回当前节点1就行
            return 1;
                                    //若左右都不为NULL,就将小的返回        
        int left=minDepth(root->left);
        int right=minDepth(root->right);
        return min(left,right)+1;//记住要加1
    }
};

275,二叉树的所有路径

给定一个二叉树,返回所有从根节点到叶子节点的路径。

说明: 叶子节点是指没有子节点的节点。

示例:

输入:

   1
 /   \
2     3
 \
  5

输出: ["1->2->5", "1->3"]

解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
//一般的递归方式,难点是返回的是vector
//to_string函数将数字变成字符
class Solution {
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> res;//每次递归函数的res都是新的
        if(root==NULL)
            return res;
        if(root->left==NULL && root->right==NULL)//只有叶子节点才入vector
        {
            res.push_back(to_string(root->val));
            return res;
        }
        vector<string> lefts=binaryTreePaths(root->left);
        for(int i=0;i<lefts.size();i++)//将左子树的所有路径遍历,给前面加上当前节点值
            res.push_back(to_string(root->val)+"->"+lefts[i]);
        
        vector<string> rights=binaryTreePaths(root->right);
        for(int i=0;i<rights.size();i++)//将右子树的所有路径遍历,给前面加上当前节点值
            res.push_back(to_string(root->val)+"->"+rights[i]);
        
        return res;
    }
};

 

110,平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回 true 。

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

       1
      / \
     2   2
    / \
   3   3
  / \
 4   4

返回 false 。

方法一:递归每个节点,并且计算出每个节点的最大深度,进行比较,但是这种方法导致多次重复计算,不可取

public:
    bool isBalanced(TreeNode* root) {
        if(root==NULL)
            return true;
        if(! (isBalanced(root->left) && isBalanced(root->right)) )
            return false;
            
        int left=_isBalanced(root->left);
        int right=_isBalanced(root->right);
        
        return (left-right>=-1 && left-right<=1);
            
    }
    int _isBalanced(TreeNode* root)
    {
        if(root==NULL)
            return 0;
        int left= _isBalanced(root->left);
        int right=_isBalanced(root->right);
        return max(left,right)+1;
    }
        
};

103,锯齿状打印二叉树(之字形)

//中心思想:大体还是层序遍历,但是使用栈存储节点,只能从栈顶出,并且每层入栈的左右顺序不一样
class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> res;//要返回的二维数组
        if(root==NULL)
            return res;
        bool flag=true;//标记位
        stack<TreeNode*> s1;//因为需要一边入栈,一边出栈,所以定义两个栈,一个只入,一个只出
        stack<TreeNode*> s2;
        s1.push(root);//先将根节点入栈,层序遍历的老规矩
        while(!s1.empty())
        {
            s2=s1;//交接班
            int n=s1.size();//这波很关键,因为下面要删栈元素,所以先将栈的元素个数保存
           for(int i=0;i<n;i++)//将只入的栈清空,为了入下层节点准备
           {
               s1.pop();
           }
            vector<int>tmp;//自动刷新
            int size=s2.size();//必须先保存个数
            for(int i=0;i<size;i++)
            {
                TreeNode* pCur=s2.top();
                s2.pop();
                tmp.push_back(pCur->val);//将节点的值加入vector
                if(flag==true)//两种状态,先入左边,将来从右向左打印
                {
                    if(pCur->left!=NULL)
                        s1.push(pCur->left);
                    if(pCur->right!=NULL)
                        s1.push(pCur->right);
                }
                else//先入右边,将来从左向右打印
                {
                     if(pCur->right!=NULL)
                        s1.push(pCur->right);
                     if(pCur->left!=NULL)
                        s1.push(pCur->left);
                }
            }//for
            flag=(!flag);//遍历一层就改变一次状态
            res.push_back(tmp);//加入二维数组
        }//while
        return res;
    }
};

53,最大子虚和

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
         int max=nums[0];//必须要将max置为nums[0],否则当数组只有一个-1时,就会返回0
        int sum=0;
        int n=nums.size();
        for(int i=0;i<n;i++)
        {
            sum+=nums[i];
            if(sum>max)
                max=sum;
            if(sum<0)
                sum=0;
        }
        return max;
    }
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问的解决,有助于将理论知识应用于实践中,增强问解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值