编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
示例 1: 输入: 11 输出: 3 解释: 整数 11 的二进制表示为 00000000000000000000000000001011 示例 2: 输入: 128 输出: 1 解释: 整数 128 的二进制表示为 00000000000000000000000010000000
public int HammingWeight(uint n) {
if(n == 0) return 0;
uint num = 0;
while(n != 1)
{
num += n % 2;
n /= 2;
}
return (int)(num + 1);
}余2表示的是取n最左位的值,而除2是表示n右移一位。最后剩下一位1,所以结果+1。
等同于:
public int HammingWeight(uint n) {
if(n == 0) return 0;
uint num = 0;
while(n != 1)
{
num += (n & 1);
n = (n>>1);
}
return (int)(num + 1);
}
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3 / \ 9 20 / \ 15 7
返回它的最大深度 3 。
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int MaxDepth(TreeNode root) {
if(root == null)
{
return 0;
}
else
{
//递归实现,先进入到最深最深的左节点或右节点,然后慢慢加上来
int left = MaxDepth(root.left);
int right = MaxDepth(root.right);
return left > right ? left + 1 : right + 1;
}
}
}我原本的思路是,用一个List来存储每一层的所有节点,然后取出来遍历(清空list),如果不为空就将他们的子节点添加到list中并将深度加1,直到list中的为空为止。
public class Solution {
public int MaxDepth(TreeNode root) {
List<TreeNode> list = new List<TreeNode>();
list.Add(root);
int height = 0;
while(list.Count > 0)
{
bool isHeight = false;
TreeNode[] all = list.ToArray();
list.Clear();
foreach(TreeNode node in all)
{
if(node != null)
{
isHeight = true;
list.Add(node.left);
list.Add(node.right);
}
}
if(isHeight)
{
height++;
}
}
return height;
}
}
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例: 输入:nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 输出: [1,2,2,3,5,6]
public void Merge(int[] nums1, int m, int[] nums2, int n) {
//合并排序,但是是在合并的数组中存储结果,所以可以先从后面开始,找最大的
int index = m + n - 1;
while(m > 0 && n > 0)
{
if(nums1[m-1] > nums2[n-1])
{
nums1[index] = nums1[m-1];
m--;
}
else
{
nums1[index] = nums2[n-1];
n--;
}
index--;
}
//剩下的m本来就是在nums1中的,所以不需要对剩余m的填充
while(n > 0)
{
nums1[index] = nums2[n-1];
index--;
n--;
}
}
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: 1->1->2->3->3 输出: 1->2->3
public ListNode DeleteDuplicates(ListNode head) {
if(head == null) return null;
ListNode h = head;
while(head.next != null)
{
if(head.next.val != head.val)
{
head = head.next;
}else{
//相同,直接去除掉
head.next = head.next.next;
}
}
return h;
}
假设你正在爬楼梯。需要 n 步你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1: 输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。 1. 1 步 + 1 步 2. 2 步
示例 2: 输入: 3 输出: 3 解释: 有三种方法可以爬到楼顶。 1. 1 步 + 1 步 + 1 步 2. 1 步 + 2 步 3. 2 步 + 1 步
public int ClimbStairs(int n) {
//动态规划
if(n == 0) return 0;
if(n == 1) return 1;//固定两个
if(n == 2) return 2;//后面结果由这两个转移而来
int fi = 1;
int fj = 2;
for(int i = 3;i<=n;i++)
{
fj = fj + fi;//状态转移
fi = fj - fi;
}
return fj;
}
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1: 输入: 4 输出: 2 示例 2: 输入: 8 输出: 2 说明: 8 的平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
public int MySqrt(int x) {
int l = 1;
int r = x;
int mid = 0;
while(l <= r)
{
mid = l + (r - l) / 2;
if(mid == x / mid)
return mid;
else if(mid > x / mid)
r = mid - 1;
else
l = mid + 1;
}
return r;
}public int MySqrt(int x) {
long r = x;
while(r * r > x)
r = (r + x / r) / 2;
return (int)r;
}
给定一个非负整数组成的非空数组,在该数的基础上加一,返回一个新的数组。
最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1: 输入: [1,2,3] 输出: [1,2,4] 解释: 输入数组表示数字 123。 示例 2: 输入: [4,3,2,1] 输出: [4,3,2,2] 解释: 输入数组表示数字 4321。
public int[] PlusOne(int[] digits) {
int[] datas = new int[digits.Length];
int up = 1;
int index = digits.Length - 1;
//第一部分,将+1进行到底,表示为index位+up
while(up == 1 && index >= 0)
{
datas[index] = (digits[index] + up) % 10;
up = (digits[index] + up) / 10;
index--;
}
if(index == -1 && up == 1)
{
//一直有进位到了头部,要加多一位1在头部
int[] temp = datas;
datas = new int[digits.Length + 1];
datas[0] = 1;
for(int i = 1;i<digits.Length + 1;i++)
{
datas[i] = temp[i-1];
}
}else
{
//将剩下的部分复制过来
for(int i = index;i>=0;i--)
{
datas[i] = digits[i];
}
}
return datas;
}
给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。
如果不存在最后一个单词,请返回 0 。
说明:一个单词是指由字母组成,但不包含任何空格的字符串。
示例: 输入: "Hello World" 输出: 5
public int LengthOfLastWord(string s) {
if(s == null || s.Length == 0) return 0;
//去除两边空格
s = s.Trim();
//从后面遍历到空格
int length = 0;
int index = s.Length - 1;
while(index >= 0 && s[index] != ' ')
{
length++;
index--;
}
return length;
}
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
public int MaxSubArray(int[] nums) {
if(nums == null || nums.Length == 0) return 0;
int curValue = nums[0];
int maxValue = nums[0];
for(int i =1;i < nums.Length;i++)
{
//将前面的最大子序列值和自己相加,看看是不是比自己大,找出自身位置的最大子序列值
if(curValue + nums[i] > nums[i])
{
curValue= curValue + nums[i];
}
else
{
curValue = nums[i];
}
//每个位置的最大子序列值和全局最大的对比
if(curValue > maxValue)
{
maxValue = curValue;
}
}
return maxValue;
}curValue表示为当前位置最大的值(相对前面的序列),从一个位置开始不断的推断下去的,动态规划
利用每个位置当前最大的子序列值和全局的最大值对比,更新全局最大值,这样只需要遍历一次数组就可以找出来了。
报数序列是指一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
1. 1 2. 11 3. 21 4. 1211 5. 111221
1 被读作 "one 1" ("一个一") , 即 11。
11 被读作 "two 1s" ("两个一"), 即 21。
21 被读作 "one 2", "one 1" ("一个二" , "一个一") , 即 1211。
给定一个正整数 n ,输出报数序列的第 n 项。
注意:整数顺序将表示为一个字符串
示例 1: 输入: 1 输出: "1" 示例 2: 输入: 4 输出: "1211"
public string CountAndSay(int n) {
if(n == 0) return "";
string res = "1";//初始化第一个报数
StringBuilder tempRes;//临时计算报数的串
for(int i = 2;i <= n;i++)
{
int index = 1;//有几个当前个体
int targetIndex = 0;//当前个体
tempRes = new StringBuilder();
for(int j = 1;j < res.Length; j++)
{
//和前面的比较
if(res[j-1] == res[j])
{
index++;
}
else
{
tempRes.Append( index.ToString() );
tempRes.Append( res[targetIndex] );
targetIndex = j;//更改当前个体为这个不相等的字符
index = 1;//多少个,当然是1个了
}
}
//收尾,最后一次的数数还没有算进来的
tempRes.Append( index.ToString() );
tempRes.Append( res[targetIndex] );
res = tempRes.ToString();
}
return res;
}没有办法的事了,只能不断的利用前一个数去推下一个数,直到推到指定位置的报数了