首页 > 其他分享 >手撕代码之其他类型

手撕代码之其他类型

时间:2023-08-29 11:40:23浏览次数:33  
标签:return psrc int 代码 while 其他 类型 leetcode size



文章目录

  • 一、根据rand7生成rand10(leetcode 470)
  • 二、快速幂(leetcode 50)
  • 三、数字二进制表示后1的个数(leetcode 191)
  • 四、判断点是否在三角形内
  • 五、下一个全排列(leetcode 31)
  • 六、带精度的开根号(leetcode 69)
  • 七、实现strcpy和memcpy
  • 八、路径简化(leetcode 71)
  • 九、字母异位词分组(leetcode 49)
  • 十、lisp语句解析(leetcode 736)


一、根据rand7生成rand10(leetcode 470)

手撕代码之其他类型_字符串


  思路:先根据rand7等概率生成rand49【(rand7() - 1) * 7 + (rand7() - 1)】,再生出rand40,最后生成rand10

class Solution {
public:
    // 先生成rand49
    int rand49() {
        return (rand7() - 1) * 7 + (rand7() - 1);
    }
    // 再生出rand40
    int rand40() {
        int r = rand49();
        while (r >= 40) {
            r = rand49();
        }
        return r;
    }
    // 最后生成rand10
    int rand10() {
        return rand40() % 10 + 1;
    }
};

二、快速幂(leetcode 50)

手撕代码之其他类型_字符串_02


  思路:使用递归分治算法,分为偶数、奇数和负数的情况,每次把n缩小一半,这样n最终会缩小到0,任何数的0次方都为1,这时候我们再往回乘

手撕代码之其他类型_#include_03

class Solution {
public:
    double myPow(double x, int n) {
        if (n == 0)
            return 1;
        double half = myPow(x, n / 2);
        // n为正数或者负数,且为偶数
        if (n % 2 == 0)
            return half * half;
        // n为正数,且为奇数
        if (n > 0)
            return half * half * x;
        // n为负数,且为奇数
        return half * half / x;
    }
};

三、数字二进制表示后1的个数(leetcode 191)

手撕代码之其他类型_ci_04


  思路:除2取余,看余数有多少个1

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int res = 0;
        while (n > 0) {
            // 除2取余,看余数有多少个1
            if (n % 2 == 1)
                res++;
            n /= 2;
        }
        return res;
    }
};

四、判断点是否在三角形内

思路:若点P在三角形ABC内,则三角形ABP+三角形ACP+三角形BCP的面积等于三角形ABC。已知三角形三点坐标ABC,如何求三角形面积呢?根据叉乘公式,向量A=(x1,y1) ,向量B=(x2,y2),A x B = x1y2 - x2y1。此时求得的是向量A和向量B的形成的平行四边形的面积,除以2就是三角形的面积了

#include <iostream>
#include <cmath>
using namespace std;
const double eps = 1e-8;
struct point{
    double x, y;
};
double solve(point a, point b, point c)
{
    point A;
    A.x = b.x-a.x;
    A.y = b.y-a.y;
    B.x = c.x-a.x;
    B.y = c.y-a.y;
    return (A.x*B.y - B.x*A.y) / 2.0;
}

int main()
{
    point A, B, C, P;
    cin >> A.x >> A.y;
    cin >> B.x >> B.y;
    cin >> C.x >> C.y;
    cin >> P.x >> P.y;
    double sum = solve(A,B,C);
    double k = 0;
    k + = solve(A,B,P);
    k + = solve(B,C,P);
    k + = solve(A,C,P);
    if ((k-sum) > eps) 
    	cout<<"在三角形外"<<endl;
    else 
    	cout<<"在三角形内"<<endl;
    return 0;
}

五、下一个全排列(leetcode 31)

手撕代码之其他类型_手撕代码_05


  思路:找到第一个递减的数nums[i],然后找到第一个大于nums[i]的数nums[j],并将两个数交换,最后翻转nums[i]后面的部分

手撕代码之其他类型_ci_06

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int n = nums.size(), i = n - 2, j = n - 1;
        // 找到第一个递减的数nums[i]
        while (i >= 0 && nums[i] >= nums[i+1])
            --i;
        // 然后找到第一个大于nums[i]的数nums[j],并将两个数交换
        if (i >= 0) {
            while (nums[j] <= nums[i])
                --j;
            swap(nums[i], nums[j]);            
        }
        // 最后翻转nums[i]后面的部分
        reverse(nums.begin() + i + 1, nums.end());
    }
};

六、带精度的开根号(leetcode 69)

// detal表示精度
double my_sq(double num, double detal)
{
	double low = 0, high = num;
	double mid = (low + high) / 2;
	while (abs(mid * mid - num) > detal)
	{
		if (mid * mid > num)
			high = mid;
		else if (mid * mid < num)
			low = mid;
		mid = (low + high) / 2;
	}
	return mid;
}

七、实现strcpy和memcpy

char *MyStrcpy(char *pdes, const char *psrc) {
	if (pdes == NULL || psrc == NULL)
		return NULL;
	char *res = pdes;
	int len = strlen(psrc), i = len;
	if (pdes >= psrc) {
		while (i >= 0) {
			*(pdes + i) = *(psrc + i);
			--i;
		}
	}
	else {
		while (*psrc != '\0') {
			*pdes = *psrc;
			++pdes;
			++psrc;
		}
		*pdes = '\0';
	}
	return res;
}

void *MyMemcpy(void *dst, const void *src, size_t size) {
	char *psrc, *pdst;
	if (NULL == dst || NULL == src) {
		return NULL;
	}
	// 自后向前拷贝
	if ((src < dst) && (char *)src + size > (char *)dst) {
		psrc = (char *)src + size - 1;
		pdst = (char *)dst + size - 1;
		while (size--) {
			*pdst-- = *psrc--;
		}
	}
	else{
		psrc = (char *)src;
		pdst = (char *)dst;
		while (size--) {
			*pdst++ = *psrc++;
		}
	}
	return dst;
}

char buf[100] = "abcdefghijk";
MyMemcpy(buf + 2, buf, 5);
printf("%s\n", buf + 2);

char pdes[5], psrc[5] = "1234";
MyStrcpy(psrc + 1, psrc);
cout << psrc << endl;

八、路径简化(leetcode 71)

手撕代码之其他类型_手撕代码_07


手撕代码之其他类型_字符串_08

class Solution {
public:
    string simplifyPath(string path) {
        vector<string> v;
        int i = 0;
        while (i < path.size()) {
            while (path[i] == '/' && i < path.size()) ++i;
            if (i == path.size()) break;
            int start = i;
            while (path[i] != '/' && i < path.size()) ++i;
            int end = i - 1;
            string s = path.substr(start, end - start + 1);
            if (s == "..") {
                if (!v.empty()) v.pop_back(); 
            } else if (s != ".") {
                v.push_back(s);
            }
        }
        if (v.empty()) return "/";
        string res;
        for (int i = 0; i < v.size(); ++i) {
            res += '/' + v[i];
        }
        return res;
    }
};

九、字母异位词分组(leetcode 49)

手撕代码之其他类型_#include_09


  思路:用临时变量保存每一个字符串,对拷贝的字符串排序(如果字符串互为错位词则排序后都是相同的),最后将其存放到map中。

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> res;
        map<string, vector<string>> mp;
        for (auto str : strs){
            string str_tmp = str;
            sort(str_tmp.begin(), str_tmp.end());
            mp[str_tmp].push_back(str); 
        }
        for (auto m : mp){
            res.push_back(m.second);
        }
        return res;
    }
};

十、lisp语句解析(leetcode 736)

手撕代码之其他类型_ci_10


  对于这种长度不定且每个可能包含子表达式的题,递归是一个很好的选择,由于需要给变量赋值,所以需要建立一个变量和其值之间的映射.

class Solution {
public:
    int evaluate(string expression) {
        unordered_map<string, int> m;
        return helper(expression, m);
    }
    int helper(string str, unordered_map<string, int> m) {
    	// 先处理首尾括号
        if (str[0] == '-' || (str[0] >= '0' && str[0] <= '9')) return stoi(str);
        else if (str[0] != '(') return m[str];
        string s = str.substr(1, str.size() - 2);
        int cur = 0;
        string cmd = parse(s, cur);
        if (cmd == "let") {
            while (true) {
                string var = parse(s, cur);
                if (cur > s.size()) return helper(var, m);
                string t = parse(s, cur);
                m[var] = helper(t, m);
            }
        } else if (cmd == "add") {
            return helper(parse(s, cur), m) + helper(parse(s, cur), m);
        } else if (cmd == "mult") {
            return helper(parse(s, cur), m) * helper(parse(s, cur), m);
        }
    }
    // 解析
    string parse(string& s, int& cur) {
        int end = cur + 1, t = cur, cnt = 1;
        if (s[cur] == '(') {
            while (cnt != 0) {
                if (s[end] == '(') ++cnt;
                else if (s[end] == ')') --cnt;
                ++end;
            }
        } else {
            while (end < s.size() && s[end] != ' ') ++end;
        }
        cur = end + 1;
        return s.substr(t, end - t);
    }
};


标签:return,psrc,int,代码,while,其他,类型,leetcode,size
From: https://blog.51cto.com/u_6526235/7273767

相关文章

  • 手撕代码之字符串
    文章目录一、反转字符串中的每一个单词(leetcode151、557)二、多个字符串的最长公共前缀(leetcode14)三、字符串转整数(leetcode8)四、N位数字串删除K个数字,使剩下的数字串最小(leetcode402)五、回文子串的个数(Leetcode647)六、最长无重复字符的子串(leetcode3)七、最长回文子串(leetcod......
  • 手撕代码之栈和队列
    文章目录一、括号匹配(leetcode20)二、最小栈(leetcode155)三、两个栈实现一个队列(leetcode232)一、括号匹配(leetcode20)classSolution{public:boolisValid(strings){if(s.empty())returntrue;stack<char>stk;stk.push(s[0]......
  • 手撕代码之二叉树
    文章目录一、根据排序数组构造二叉搜索树(leetcode108)二、根据前序遍历和中序遍历构造二叉树(leetcode105)三、二叉树的非递归遍历(leetcode94、144、145)四、二叉树中和为某一值的路径(leetcode112)五、二叉树的最大深度(leetcode104)六、二叉树的层次遍历(leetcode102)七、判断两个二......
  • SQL Server 根据表名查询包含的列名、类型、长度等
      select c.nameas'列名', casewhenc.is_identity=1then'√'else'×'endas'自增', ty.nameas'数据类型', c.max_lengthas'长度', casewhenc.is_nullable=1then'√'else'×&......
  • Java代码审计之目录穿越
    一、目录穿越漏洞1、什么是目录穿越所谓的目录穿越指利用操作系统中的文件系统对目录的表示。在文件系统路径中,".."表示上一级目录,当你使用"../"时,你正在引用当前目录的上一级目录。如果你使用"../../",你实际上在两次".."的基础上,再次引用上一级目录,从而返回到上两级目录。......
  • Vscode如何如何显示vue代码提示
    Vscode使用版本 下载这个插件 ......
  • 5.1.29 远程代码执行漏洞
    ThinkPHP55.0.22/5.1.29远程代码执行漏洞漏洞描述Thinkphp是一个国内轻量级的开发框架。由于没有正确处理控制器名,导致在网站没有开启强制路由的情况下(即默认情况下)可以执行任意方法,从而导致远程命令执行漏洞。验证方式直接访问http://your-ip:8080/index.php?s=/Index/\thi......
  • 类型转换
    byte,short,chart——>int——>long——>float——>double 低————————————————————————>高类型转换分为:强制类型转换(由高-->低时使用),自动类型转换/隐式类型转换(由低-->高时使用),例如:intt=100;doublet1=t;//自动类型转换......
  • python代码画爱心❤(海龟)
    importturtle#设置标题turtle.title("蜜蜂的程序")turtle.st()#显示海龟print(turtle.position())turtle.color("red","pink")turtle.begin_fill()#填充前turtle.left(90)turtle.penup()turtle.pendown()turtle.circle(60,180)turtle.circle(18......
  • 正则表达式判断号码靓号类型
    正则表达式判断号码靓号类型战国墨竹于 2018-04-2010:38:35 发布6962 收藏 14分类专栏: php 正则 php同时被2个专栏收录95篇文章0订阅订阅专栏正则3篇文章0订阅订阅专栏靓号检测:主要可以检测连号(正连12345、倒连65432)、AABB号、手......