

想锻炼算法相关内容注意推荐去刷题网站勤加练习,如力扣、牛客网等。
十种常见排序算法可以分为两大类:



常规答案
与2取余,若为0则是偶数,否则为奇数。
public static bool IsEven(int number)
{
return ((number % 2) == 0);
}进阶答案
检测数字的二进制最低位是否为0。将最低位和1相与,如果结果为0,则为偶数,否则为奇数。
如奇数3和1位与,实际上是
00000000 00000000 00000000 00000011
& 00000000 00000000 00000000 00000001
---------------------------------------------
00000000 00000000 00000000 00000001再比如偶数6和1位与,实际上是
00000000 00000000 00000000 00000110
& 00000000 00000000 00000000 00000001
---------------------------------------------
00000000 00000000 00000000 00000000判断一个整数是奇数还是偶数
/** <summary>
/// 判断一个整数是否是偶数
/// </summary>
/// <param name="number">传入的整数</param>
/// <returns>如果是偶数,返回true,否则为false</returns>
public static bool IsEven(int number)
{
return ((number & 1) == 0);
}
/** <summary>
/// 判断一个整数是否是奇数
/// </summary>
/// <param name="number">传入的整数</param>
/// <returns>如果是奇数,返回true,否则为false</returns>
public static bool IsOdd(int number)
{
return !IsEven(number);
}常规答案
利用位运算进行判断,将一个数通过不断位右移,最终结果若为1则为true,否则为false。
判断一个整数是否是2的n次方
public static bool IsPower(int number)
{
if (number <= 0)
{
return false;
}
while (true)
{
if (number == 1)
{
return true;
}
//如果是奇数
if ((number & 1) == 1)
{
return false;
}
//右移一位
number >>= 1;
}
}进阶答案
2的n次方其二进制表示只有1个1,如整数8,其二进制表示形式是00001000,减去1后为00000111,让这两者进行位与的结果刚好是0则为true,否则就是falsez。
判断一个整数是否是2的n次方
public static bool IsPower(int number)
{
if (number <= 0)
{
return false;
}
if ((number & (number - 1)) == 0)
{
return true;
}
return false;
}代码
private static int GetCountGroupByOne(int data)
{
int count = 0;
if (data == 0)
{
}
else if (data > 0)
{
while (data > 0)
{
data &= (data - 1);
count++;
}
}
else
{
int minValue = -0x40000001;
while (data > minValue)
{
data &= (data - 1);
count++;
}
count++;
}
return count;
}利用堆排序、小顶堆实现。
先拿10000个数建堆,然后一次添加剩余元素,如果大于堆顶的数(10000中最小的),将这个数替换堆顶,并调整结构使之仍然是一个最小堆,这样遍历完后,堆中的10000个数就是所需的最大的10000个。建堆时间复杂度是O(mlogm),算法的时间复杂度为O (nmlogm)(n为100,m为10000)。
优化的方法:分治。可以把所有10亿个数据分组存放,比如分别放在1000个文件中。这样处理就可以分别在每个文件的10^6个数据中找出最大的10000个数,合并到一起在再找出1000*10000中的最终的结果。
算法思路:假设目标值在闭区间l, r中,每次将区间长度缩小一半,当l = r时,我们就找到了目标值。
1.当我们将区间l, r划分成l, mid和mid + 1, r时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。(常用)
int bsearch_1(int 1, int r)
{
While (l <r)
{
int mid = l +r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
return l;
}2.当我们将区间l, r划分成l, mid - 1和mid, r时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。
int bsearch_2(int 1, int r)
{
While (l <r)
{
int mid = l + r +1 >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
return l;
}3.代码里的if语句,若变成一个bool函数带入对应的l,r,mid,array等,在函数里面继续二分查找,即可变成“二分答案”。
BFS从根节点开始搜索,并根据树级别模式探索所有邻居根。它使用队列数据结构来记住下一个节点访问。
1.如果不需要确定当前遍历到了哪一层
while queue 不空:
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未访问过:
queue.push(该节点)2.如果要确定当前遍历到了哪一层,BFS 模板如下。 这里增加了 level 表示当前遍历到二叉树中的哪一层了,也可以理解为在一个图中,现在已经走了多少步了。size 表示在当前遍历层有多少个元素,也就是队列中的元素数,我们把这些元素一次性遍历完,即把当前层的所有元素都向外走了一步。
level = 0
while queue 不空:
size = queue.size()
while (size --)
{
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未访问过:
queue.push(该节点)
}
level++;注意搜索的顺序;当搜到叶子节点(递归结束)时就回溯,回退一步看一步。
DFS从根节点开始搜索,并从根节点尽可能远地探索这些节点。使用堆栈数据结构来记住下一个节点访问。
类似于树的 先序遍历

static int Fn(int n) {
if (n <= 0) {
throw new ArgumentOutOfRangeException();
}
if (n == 1||n==2)
{
return 1;
}
return checked(Fn(n - 1) + Fn(n - 2)); // when n>46 memory will overflow
}string a = new string("abc");
a = (a.ToUpper() +"123").Substring(0,2);实在C#中第⼀⾏是会出错的(Java中倒是可⾏)。
应该这样初始化:
string b = new string(new char[] {'a','b','c'});三个临时对象:abc、ABC、AB
已知点P(x,y),以及直线上的两点A(x1,y1)、B(x2,y2),可以通过计算向量AP与向量AB的叉乘是否等于0来计算点P是否在直线AB上。
知识点:叉乘
/// <summary>
/// 2D叉乘
/// </summary>
/// <param name="v1">点1</param>
/// <param name="v2">点2</param>
/// <returns></returns>
public static float CrossProduct2D(Vector2 v1,Vector2 v2)
{
//叉乘运算公式 x1*y2 - x2*y1
return v1.x * v2.y - v2.x * v1.y;
}
/// <summary>
/// 点是否在直线上
/// </summary>
/// <param name="point"></param>
/// <param name="lineStart"></param>
/// <param name="lineEnd"></param>
/// <returns></returns>
public static bool IsPointOnLine(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
{
float value = CrossProduct2D(point - lineStart, lineEnd - lineStart);
return Mathf.Abs(value) <0.0003 /* 使用 Mathf.Approximately(value,0) 方式,在斜线上好像无法趋近为0*/;
}已知点P(x,y),以及线段A(x1,y1),B(x2,y2)。
1)方法一
可以进行下面两部来判断点P是否在线段AB上:
(1)点是否在线段AB所在的直线上(点是否在直线上)
(2)点是否在以线段AB为对角线的矩形上,来忽略点在线段AB延长线上
/// <summary>
/// 2D叉乘
/// </summary>
/// <param name="v1">点1</param>
/// <param name="v2">点2</param>
/// <returns></returns>
public static float CrossProduct2D(Vector2 v1,Vector2 v2)
{
//叉乘运算公式 x1*y2 - x2*y1
return v1.x * v2.y - v2.x * v1.y;
}
/// <summary>
/// 点是否在直线上
/// </summary>
/// <param name="point"></param>
/// <param name="lineStart"></param>
/// <param name="lineEnd"></param>
/// <returns></returns>
public static bool IsPointOnLine(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
{
float value = CrossProduct2D(point - lineStart, lineEnd - lineStart);
return Mathf.Abs(value) <0.0003 /* 使用 Mathf.Approximately(value,0) 方式,在斜线上好像无法趋近为0*/;
}
/// <summary>
/// 点是否在线段上
/// </summary>
/// <param name="point"></param>
/// <param name="lineStart"></param>
/// <param name="lineEnd"></param>
/// <returns></returns>
public static bool IsPointOnSegment(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
{
//1.先通过向量的叉乘确定点是否在直线上
//2.在拍段点是否在指定线段的矩形范围内
if (IsPointOnLine(point,lineStart,lineEnd))
{
//点的x值大于最小,小于最大x值 以及y值大于最小,小于最大
if (point.x >= Mathf.Min(lineStart.x, lineEnd.x) && point.x <= Mathf.Max(lineStart.x, lineEnd.x) &&
point.y >= Mathf.Min(lineStart.y, lineEnd.y) && point.y <= Mathf.Max(lineStart.y, lineEnd.y))
return true;
}
return false;
}Unity性能优化 面试题都在这里了,希望本篇文章能够让你在面试关卡如鱼得水得到自己想要的工作。