leetcode刷题-part1


title: leetcode刷题-part1
date: 2018-09-21 17:32:47
updated: 2020-03-11 21:33:18
categories: 算法刷题
tags:
- 算法刷题
- leetcode


此leetcode刷题系列记录单独做的leetcode题目与答案,并非每道题都做,只记录做过的。每篇文档25道题,以官网题目序号为顺序。

一、题目总览

leetcode题目
69x的平方根
104二叉树的最大深度
344反转字符串
349两个数组的交集
637二叉树的层平均值
695岛屿的最大面积
771宝石与石头

二、题目及解答

No.69——x的平方根

题目

Compute and return the square root of x, where x is guaranteed to be a non-negative integer.

Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.

Example 1:

Input: 4
Output: 2

Example 2:

Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since the decimal part is truncated, 2 is returned.

思路

就是开根号,用二分法且用除法避免溢出

代码

class Solution {
public:
    int mySqrt(int x) {
        if(x==0)
            return 0;
        if(x<4){
            return 1;
        }
        int left = 1;
        int right = x/2+1; //这里注意
        int mid;
        while(left <= right){//while中的等号注意
            mid = left + (right-left)/2;
            if(x/mid == mid){
                return mid;
            }
            else if(x/mid > mid){
                left = mid + 1;
            }
            else if(x/mid < mid){
                right = mid - 1;
            }
        }
        return right;
    }
};

No.104——二叉树的最大深度

题目

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

For example:
Given binary tree [3,9,20,null,null,15,7],

	3
   / \
  9  20
    /  \
   15   7
	   

return its depth = 3.

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {//同样用了二叉树左子树右子树的递归思想
        if(!root)
            return 0;
        int ldeep = maxDepth(root->left);
        int rdeep = maxDepth(root->right);
        
        return ldeep>rdeep ? ldeep+1 : rdeep+1;
    }
};

No.344——反转字符串

题目

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

示例 1:

输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例 2:

输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

预备知识

# include <stdio.h>
/*
*	c语言键盘输入字符串char[]:scanf、gets区别
*	不同点:scanf不能接受空格、制表符tab、回车等; gets能接受空格、制表符tab、回车等
*	相同点:字符串接受结束后自动加'\0'
*	2016年6月14日16:51:51
*/
 
int main(void)
{
	char s1[100];		//c语言没有字符串,只有char[]
 
	scanf("%s", s1);
	printf("%s\n", s1);
 
	char s2[100];
	gets(s2);
	printf("%s\n", s2);
 
	return 0;
}

代码

# include <stdio.h>
# include <string.h>	//用于strlen(s)求字符数组长度
/*
*	Write a function that takes a string as input and returns the string reversed.
*	Example:
*	Given s = "hello", return "olleh". 
*	求字符串长度len = strlen(s),需要头文件<string.h>
*	
*	2016年6月14日18:02:25
*/
 
char* reverseString(char*);
 
int main(void)
{
	char s[100];
	gets(s);
 
	reverseString(s);	//!注意传的是s,而不是&s:因为s就是s[100]字符数组s[0]的地址!
	printf("%s\n", s);
 
	return 0;
}
 
 
char* reverseString(char* ps) 
{
    int i = 0;
    int r = strlen(ps) - 1;
	int p;
    while(i < r)
    {
		p = ps[i];		//注意这里s[i]前没有*
        ps[i] = ps[r];
        ps[r] = p;
        i++;
        r--;
    }
    return ps;
}

No.349——两个数组的交集

题目

给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2]

示例 2:

输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [9,4]

说明:

  • 输出结果中的每个元素一定是唯一的。
  • 我们可以不考虑输出结果的顺序。

代码

# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
 
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize);
//以上函数返回的是相同元素的整个数组,而那个returnSize是这个相同数组的大小,并且是个指针变量可以修改!
void show(int* s, int size);
void sort(int* s, int size, int* sizenow);
int main(void)
{
	int s1[7] = {1,2,2,1,11,23,4};
	int s2[6] = {2,2,43,11,3,4};
	show(s1, 7);
	show(s2, 6);
 
 
	int* returnSize = (int *)malloc(sizeof(int));//相同数组的大小,因为是指针变量,所以可以后面被修改
 
	int* count = (int*)malloc(sizeof(int)*100);
	count = intersection(s1, 7, s2, 6, returnSize);
	show(count, *returnSize);
	
	system("pause");
	return 0;
}
 
void show(int* s, int size)
{
	int i;
	for(i=0; i<size; i++)
	{
		printf("%d ", s[i]);
	}
	printf("\n");
}
 
void sort(int* s, int size, int* sizenow)
{
	int i, j, temp;
	for(i=0; i<size; i++)
	{
		for(j=0; j<size-i-1;j++)
		{
			if(s[j] > s[j+1])
			{
				temp = s[j];
				s[j] = s[j+1];
				s[j+1] = temp;
			}
		}
	}
	int p=1, q=0;
	for(; p<size; p++)
	{
		if(s[p]!=s[q])
		{
			q++;
			s[q] = s[p];
		}
	}
	*sizenow = q+1;
	return;
}
 
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) 
{
	int p = 0, q = 0;
	int c=0;
	int* count = (int*)malloc(sizeof(int)*21);
 
	int* sizenow1 = (int*)malloc(sizeof(int));
	int* sizenow2 = (int*)malloc(sizeof(int));
	sort(nums1, nums1Size, sizenow1);
	sort(nums2, nums2Size, sizenow2);
	nums1Size = *sizenow1;
	nums2Size = *sizenow2;
	
	/*这个算法也可以,差不多的
	while(1)
	{
		if((nums1[p]<nums2[q]) && (p<nums1Size-1))
			p++;
		else if((nums1[p]>nums2[q]) && (q<nums2Size-1))
			q++;
		else if((nums1[p] == nums2[q]))
		{
			count[c] = nums2[q];
			p++;
			q++;
			c++;
		}
		else if((p==nums1Size-1) || (q==nums2Size-1))
			break;
	}
*/
	while((p < nums1Size) || (q > nums2Size) )
	{
		if((nums1[p]<nums2[q]))
			p++;
		else	
		{
			if((nums1[p]>nums2[q]))
				q++;
			else 
			{
				if((nums1[p] == nums2[q]))
				{
					count[c] = nums2[q];
					c++;
					p++;
					q++;	
				}
			}
		}
	}
 
	*returnSize = c;
 
	return count;
}

No.637——二叉树的层平均值

题目

给定一个非空二叉树, 返回一个由每层节点平均值组成的数组.

示例 1:

输入:
    3
   / \
  9  20
    /  \
   15   7
输出:[3, 14.5, 11]
解释:第0层的平均值是 3,  第1层是 14.5, 第2层是 11. 因此返回 [3, 14.5, 11].

注意:节点值的范围在32位有符号整数范围内。

思路

队列实现层次遍历的核心思路:

根节点为空返回NULL,根节点入队,while队列不为空则pop()一个元素,访问该元素后,将其左子树、右子树分别入队

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) { 
        //层次遍历并且要知道每一层的节点都是哪几个;
        //用队列实现层次遍历:根节点为空返回NULL,根节点入队,while队列不为空则pop()一个元素,访问该元素后,将其左子树、右子树分别入队
        vector<double> res;
        if(!root)
            return res;
        
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty())
        {
            int len = que.size();
            int cnt = len;
            double sum = 0;
            while(cnt != 0)
            {
                TreeNode* tmp = que.front();
                sum += tmp->val;
                que.pop();
                if(tmp->left)
                    que.push(tmp->left);
                if(tmp->right)
                    que.push(tmp->right);
                
                cnt--;
            }
            
            
            res.push_back(sum/len);
        }
        
        return res;
    }
};

No.695——岛屿的最大面积

题目

给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。

找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为0。)

示例 1:

[[0,0,1,0,0,0,0,1,0,0,0,0,0],
 [0,0,0,0,0,0,0,1,1,1,0,0,0],
 [0,1,1,0,1,0,0,0,0,0,0,0,0],
 [0,1,0,0,1,1,0,0,1,0,1,0,0],
 [0,1,0,0,1,1,0,0,1,1,1,0,0],
 [0,0,0,0,0,0,0,0,0,0,1,0,0],
 [0,0,0,0,0,0,0,1,1,1,0,0,0],
 [0,0,0,0,0,0,0,1,1,0,0,0,0]]

对于上面这个给定矩阵应返回 6。注意答案不应该是11,因为岛屿只能包含水平或垂直的四个方向的‘1’。

示例 2:

[[0,0,0,0,0,0,0,0]]

对于上面这个给定的矩阵, 返回 0。

注意: 给定的矩阵grid 的长度和宽度都不超过 50。

思路

DFS思想:一直往深处走,直到找到解或者走不下去为止。

实现:采用递归,使用栈保存未被检测的结点,结点按照深度优先的次序被访问并依次被压入栈中,并以相反的次序出栈进行新的检测。

详见 DFS模板

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {//同样用了二叉树左子树右子树的递归思想
        if(!root)
            return 0;
        int ldeep = maxDepth(root->left);
        int rdeep = maxDepth(root->right);
        
        return ldeep>rdeep ? ldeep+1 : rdeep+1;
    }
};
	

No.771——宝石与石头

题目

给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。

J 中的字母不重复,J 和 S中的所有字符都是字母。字母区分大小写,因此"a"和"A"是不同类型的石头。

示例 1:

输入: J = "aA", S = "aAAbbbb"
输出: 3

示例 2:

输入: J = "z", S = "ZZ"
输出: 0

注意:S 和 J 最多含有50个字母。 J 中的字符不重复。

代码

class Solution {
	public:
	    int numJewelsInStones(string J, string S) {
	        //将J存成hash_map,便于S查询计数
	        map<char, int> hash_map;
	        for(int i=0; i<J.length(); i++)
	        {
	            hash_map.insert(pair<char, int>(J[i], 1));
	        }
	        
	        int res = 0;
	        for(char c: S)
	        {
	            if(hash_map.count(c) != 0) //map.count()返回0或1; map.find()返回迭代器
	                res += 1;
	        }
	        return res;
	    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值