给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。
示例 1: 输入: [3,0,1] 输出: 2 示例 2: 输入: [9,6,4,2,3,5,7,0,1] 输出: 8
//排序后检查 public int MissingNumber(int[] nums) { Array.Sort(nums); if(nums.Length == 0 || nums[0] == 1) return 0; for(int i = 0;i<nums.Length - 1;i++) { if(nums[i] - nums[i+1] != -1) { return nums[i] + 1; } } return nums[nums.Length-1]+1; }
//高斯求和 public int MissingNumber(int[] nums) { int sum = 0; for(int i = 0;i<nums.Length;i++) { sum += nums[i]; } //因为第一个元素为0,所以... return nums.Length * (nums.Length+1)/2 - sum; }
//异或法 public int MissingNumber(int[] nums) { int xor = 0; int i = 0; for(;i<nums.Length;i++) { //和相同的数异或两次为本身,和0异或为本身 xor = xor ^ i ^ nums[i]; } return xor ^ i; }
编写一个程序判断给定的数是否为丑数。
丑数就是只包含质因数 2, 3, 5 的正整数。
示例 1: 输入: 6 输出: true 解释: 6 = 2 × 3 示例 2: 输入: 8 输出: true 解释: 8 = 2 × 2 × 2 示例 3: 输入: 14 输出: false 解释: 14 不是丑数,因为它包含了另外一个质因数 7。 说明: 1 是丑数。 2 输入不会超过 32 位有符号整数的范围: [−2^31, 2^31 − 1]。
public bool IsUgly(int num) { if(num <= 0) return false; while(num%2 == 0) num /= 2; while(num%3 == 0) num /= 3; while(num%5 == 0) num /= 5; return num == 1; }
给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
示例: 输入: 38 输出: 2 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。 进阶: 你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?
//一次过 public int AddDigits(int num) { while(num/10 != 0) { int temp = num; num = 0; while(temp/10 != 0) { num += temp % 10; temp /= 10; } num += temp; } return num; }
//一脸懵比 public int AddDigits(int num) { return (num-1) % 9 + 1; }
请判断一个链表是否为回文链表。
示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
/** * Definition for singly-linked list. * public class ListNode { * public int val; * public ListNode next; * public ListNode(int x) { val = x; } * } */ public class Solution { public bool IsPalindrome(ListNode head) { //反转前端链表 int num = 0; ListNode temp = head; while(temp != null) { num++; temp = temp.next; } int medioNum = num / 2; ListNode preNode = null; ListNode curNode = head; ListNode startNode = null; while(medioNum != 0)//反转前半段链表 { temp = curNode.next; curNode.next = preNode; preNode = curNode; curNode = temp; medioNum--; } //此时,preNode为前半段的头结点,curNode为后半段的头结点 if(num % 2 == 1) { //链表为奇数的情况下,中间的结点为公有结点不用检查 curNode = curNode.next; } while(curNode != null) { if(curNode.val != preNode.val) return false; curNode = curNode.next; preNode = preNode.next; } return true; } }
一次过,我都惊呆了,虽然不难。先遍历链表计算链表的长度,反转前半段的链表,然后逐个对比就可以了。
给定一个整数,编写一个函数来判断它是否是 2 的幂次方。
示例 1: 输入: 1 输出: true 解释: 2^0 = 1
public bool IsPowerOfTwo(int n) { if(n <= 0) return false; return (n & (n-1)) == 0; }
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。
示例 1: 输入: nums = [1,2,3,1], k = 3 输出: true 示例 2: 输入: nums = [1,0,1,1], k = 1 输出: true 示例 3: 输入: nums = [1,2,3,1,2,3], k = 2 输出: false
public bool ContainsNearbyDuplicate(int[] nums, int k) { Dictionary<int,int> dic = new Dictionary<int,int>(); for(int i = 0;i<nums.Length;i++) { if(dic.ContainsKey(nums[i])) { if(Math.Abs(dic[nums[i]] - i) <= k) { return true; } else { dic[nums[i]] = i;//更新下标位置,前面的的无用啦 } } else { dic.Add(nums[i],i); } } return false; }
给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。
示例 1: 输入: [1,2,3,1] 输出: true 示例 2: 输入: [1,2,3,4] 输出: false 示例 3: 输入: [1,1,1,3,3,4,3,2,4,2] 输出: true
//标志法 public bool ContainsDuplicate(int[] nums) { Dictionary<int,bool> dic = new Dictionary<int,bool>(); for(int i = 0;i<nums.Length;i++) { if(dic.ContainsKey(nums[i])) { return true; } else { dic.Add(nums[i],true); } } return false; }
//排序法 public bool ContainsDuplicate(int[] nums) { if(nums.Length == 0 || nums.Length == 1) return false; Array.Sort(nums); for(int i = 0;i<nums.Length - 1;i++) { if(nums[i] == nums[i+1]) { return true; } } return false; }
反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
/** * Definition for singly-linked list. * public class ListNode { * public int val; * public ListNode next; * public ListNode(int x) { val = x; } * } */ public class Solution { public ListNode ReverseList(ListNode head) { //用三个指标,一个保存上一个,一个保存当前,一个用来临时保存数据 ListNode temp = head; ListNode preNode = null; ListNode curNode = head; while(curNode != null) { temp = curNode.next; curNode.next = preNode; preNode = curNode; curNode = temp; } return preNode; } }
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例 1: 输入: s = "egg", t = "add" 输出: true 示例 2: 输入: s = "foo", t = "bar" 输出: false 示例 3: 输入: s = "paper", t = "title" 输出: true
说明:
你可以假设 s 和 t 具有相同的长度。
public bool IsIsomorphic(string s, string t) { Dictionary<char,int> dic1 = new Dictionary<char,int>(); Dictionary<char,int> dic2 = new Dictionary<char,int>(); int index1 = -1; int index2 = -1; for(int i = 0;i<s.Length;i++) { index1 = -1; index2 = -1; if(dic1.ContainsKey(s[i])) { index1 = dic1[s[i]]; } else { dic1.Add(s[i],i); } if(dic2.ContainsKey(t[i])) { index2 = dic2[t[i]]; } else { dic2.Add(t[i],i); } if(index1 != index2) { return false; } } return true; }
删除链表中等于给定值 val 的所有节点。
示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4->5
/** * Definition for singly-linked list. * public class ListNode { * public int val; * public ListNode next; * public ListNode(int x) { val = x; } * } */ public class Solution { public ListNode RemoveElements(ListNode head, int val) { ListNode MyHead = new ListNode(0);//建一个头结点,应对要删除first结点的情况,达到一致的普遍性 MyHead.next = head; ListNode preNode = MyHead; while(head != null) { if(head.val == val) { //移除结点,上一个结点不变 preNode.next = head.next; } else { preNode = head;//上一个结点推进 } head = head.next;//日常推进 } return MyHead.next; } }