Day1

001 ToSum

    //O(n2)
public int[] TwoSum(int[] nums, int target)
{
for (int i = 0; i < nums.Length; i++)
{
for (int j = i + 1; j < nums.Length; j++)
{
if (nums[i] + nums[j] == target)
{
return new int[] { i, j };
}
}
}
return null;
}
    //O(nlogn)
public int[] TwoSum(int[] nums, int target)
{
//原数组复制一个
int[] demmy = new int[nums.Length];
Array.Copy(nums, demmy, nums.Length);
//对原数组排序
Array.Sort(nums);
int n = nums.Length;
int left = 0;
int right = n - 1;
while (nums[left] + nums[right] != target)
{
if (nums[left] + nums[right] > target)
{
right--;
}
else
{
left++;
}
}
int[] result = new int[2];
for (int i = 0; i < nums.Length; i++)
{
if (demmy[i] == nums[left])
{
result[0] = i;
}
}
for (int i = nums.Length - 1; i >= 0; i--)
{
if (demmy[i] == nums[right])
{
result[1] = i;
}
}
return result;
}
    //O(n)
public int[] TwoSum(int[] nums, int target)
{
//构建哈希表<值,索引>
Dictionary<int, int> map = new Dictionary<int, int>();
for(int i = 0; i < nums.Length; i++)
{
int diff = target - nums[i];
//查询过往是否在哈希表有这个值
if (map.ContainsKey(diff))
{
return new int[] { map[diff], i };
}
//如果过往没有,
//并且当前的<值,索引>在哈希表中没被添加过,则加到哈希表中,进行下一次查找
if (!map.ContainsKey(nums[i]))
{
map.Add(nums[i], i);
} }
return null;
}

002 Best Time to Buy and Sell Stock

    //O(n2) TLE
public int MaxProfit(int[] prices)
{
int maxProfit = 0;
for (int i = 0; i < prices.Length; i++)
{
for (int j = i + 1; j < prices.Length; j++)
{
maxProfit = Math.Max(prices[j] - prices[i], maxProfit);
}
}
return maxProfit;
}
    //O(n)
public int MaxProfit(int[] prices)
{
if (prices == null || prices.Length == 0) return 0;
int min = int.MaxValue, maxProfit = 0;
foreach (int price in prices)
{
min = Math.Min(price, min);
if (price > min)
maxProfit = Math.Max(maxProfit, price - min);
}
return maxProfit;
}

通解:状态机

    //O(n)这是解决买卖股票问题的通用解法——状态机
public int MaxProfit(int[] prices)
{
int n = prices.Length;
int[][] dp = new int[n][];
for(int i = 0; i < n; i++)
{
dp[i] = new int[2];
} //初始化
dp[0][0] = 0;
dp[0][1] = -prices[0]; for(int i = 1; i < n; i++)
{
//第i天没股票 = max(前一天没股票,前一天有股票+今天卖掉了)
dp[i][0] = Math.Max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
//第i天有股票 = max(前一天有股票,前一天没股票-今天买了)
dp[i][1] = Math.Max(dp[i - 1][1], 0 - prices[i]);
//因为总的交易次数是1,也就是只能买一次+卖一次,并且必须先买了才能卖,所以前一天没股票就一定是初始状态=0
}
return dp[n - 1][0];
}

003 Insert Intertval

    public int[][] Insert(int[][] intervals, int[] newInterval)
{
List<int[]> result = new List<int[]>();
foreach (int[] current in intervals)
{
//无交集
if(newInterval == null || newInterval[0] > current[1])
{
result.Add(current);
}
else if (newInterval[1] < current[0])
{
result.Add(newInterval);
newInterval = null;
result.Add(current);
}
//有交集
else
{
//上述情况都不满足,那就需要合并
newInterval[0] = Math.Min(newInterval[0], current[0]);
newInterval[1] = Math.Max(newInterval[1], current[1]);
}
}
//手动添加
if(newInterval != null)
{
result.Add(newInterval);
}
return result.ToArray();
}

Day2

004 3Sum

三指针法

public class Solution
{
//三指针法
public IList<IList<int>> ThreeSum(int[] nums)
{
IList<IList<int>> result = new List<IList<int>>();
Array.Sort(nums);
//三个指针:i,left,right
for (int i = 0; i < nums.Length - 2; i++)
{
if (i > 0 && nums[i] == nums[i - 1]) continue;
int left = i + 1, right = nums.Length - 1;
while (left < right)
{
if (nums[i] + nums[left] + nums[right] == 0)
{
IList<int> res = new List<int>() { nums[i], nums[left], nums[right] };
result.Add(res);
left++;
right--;
while (left < right && nums[left] == nums[left - 1]) left++;
while (left < right && nums[right] == nums[right + 1]) right--;
}
else if (left < right && nums[i] + nums[left] + nums[right] > 0) right--;
else left++;
}
}
return result;
}
}

005 Product of Array Except Self

前缀和->前缀积、后缀积

思路:左扫一遍右扫一遍

//O(n)
public class Solution {
public int[] ProductExceptSelf(int[] nums) {
int[] left = new int[nums.Length];
int[] right = new int[nums.Length];
//init
left[0] = 1;
right[nums.Length - 1] = 1;
//left
for(int i = 1; i < nums.Length; i++){
left[i] = left[i-1] * nums[i-1];
}
//right
for(int i = nums.Length - 2; i >= 0; i--){
right[i] = right[i+1] * nums[i+1];
}
//left * right
for(int i = 0; i < nums.Length; i++){
left[i] *= right[i];
}
return left;
}
}
//sapce:O(1)
public class Solution {
public int[] ProductExceptSelf(int[] nums) {
int[] result = new int[nums.Length];
for(int i = 0,tmp = 1; i < nums.Length; i++){
//因为是前缀积,所以先赋值
result[i] = tmp;
//下一轮的tmp
tmp *= nums[i];
}
for(int i = nums.Length - 1,tmp = 1; i >= 0; i--){
result[i] *= tmp;
tmp *= nums[i];
}
return result;
}
}

Day3

006Combination Sum

前置知识:DFS

DFS中的回溯模板

public class Solution {
int[] candidates;
int target;
public IList<IList<int>> CombinationSum(int[] candidates, int target) {
this.candidates = candidates;
this.target = target;
List<IList<int>> result = new List<IList<int>>();
DFS(result,new List<int>(),0,0);
return result;
}
public void DFS(List<IList<int>> result,List<int> list,int sum,int start){
if(sum > target)return;
if(sum == target){
result.Add(new List<int>(list));
return;
}
//sum<target
for(int i = start; i < candidates.Length; i++){
list.Add(candidates[i]);
DFS(result,list,sum+candidates[i],i);
list.RemoveAt(list.Count - 1);
}
}
}

为什么需要 list.RemoveAt(list.Count - 1);

因为递归结束返回的时候这条分支的sum>=target,需要删除最后一个结点,然后尝试下一个分支

候选数组是 [2, 3, 6, 7],目标值是 7

递归过程示意:

path = [2]
sum = 2 → 继续递归添加下一个元素 path = [2, 2]
sum = 4 → 继续递归添加下一个元素 path = [2, 2, 2]
sum = 6 → 继续递归添加下一个元素 path = [2, 2, 2, 2]
sum = 8 → 超过 target (7),返回并执行:
list.RemoveAt(list.Count - 1); // 移除最后一个 2,path 变为 [2, 2, 2]

然后继续尝试下一条分支

path = [2, 2, 2, 3]
sum = 9 → 超过 target,再次移除最后一个元素…… 最终找到一条合法路径:
path = [2, 2, 3], sum = 7 → 加入结果集

007 Merge Intervals

public class Solution
{
public int[][] Merge(int[][] intervals)
{
List<int[]> result = new List<int[]>();
Array.Sort(intervals, (a, b) => a[0].CompareTo(b[0]));
int[] current = intervals[0];
foreach (int[] next in intervals)
{
//大于等于都要合并
if (current[1] >= next[0])
{
current[1] = Math.Max(current[1], next[1]);
}
else
{
//没有交集就直接添加进result,并将current更新到下一个interval
result.Add(current);
current = next;
}
}
//最后一个加进来
result.Add(current); return result.ToArray();
}
}

008 Majority Element

多数元素:出现次数超过n/2的元素

三种方法:

  1. 摩尔投票
  2. 查字典(自己想的)——这其实找的是众数,只是出现次数最多,不是次数 > n/2
  3. 排序——多数元素的出现次数 ≥ n/2 + 1,它至少占据数组中 n/2 + 1 个位置,那么返回中间位置的元素就行
public class Solution {
public int MajorityElement(int[] nums) {
int count = 0;
int candidate = 0;
foreach(int num in nums){
if(count == 0)candidate = num;
count += (num == candidate)? 1 : -1;
}
return candidate;
}
}
public class Solution {
public int MajorityElement(int[] nums) {
Dictionary<int,int> frequencyMap = new Dictionary<int, int>();
int maxFrequency = 0;
int result = nums[0];
foreach(int num in nums){
if(frequencyMap.ContainsKey(num)) frequencyMap[num]++;
else frequencyMap[num] =1;
if(maxFrequency < frequencyMap[num]){
maxFrequency = frequencyMap[num];
result = num;
}
}
return result;
}
}
public class Solution {
public int MajorityElement(int[] nums) {
Array.Sort(nums);
return nums[nums.Length / 2];
}
}

009 Sort Colors

Grind75详解的更多相关文章

  1. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  2. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  3. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

  4. Java 字符串格式化详解

    Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...

  5. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  6. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

  7. Git初探--笔记整理和Git命令详解

    几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...

  8. Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

  9. Node.js npm 详解

    一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...

  10. .NET应用和AEAI CAS集成详解

    1 概述 数通畅联某综合SOA集成项目的统一身份认证工作,需要第三方系统配合进行单点登录的配置改造,在项目中有需要进行单点登录配置的.NET应用系统,本文专门记录.NET应用和AEAI CAS的集成过 ...

随机推荐

  1. 介绍一下opentcs

    OpenTCS是一个开源的自动运载系统(Automated Guided Vehicle,AGV)控制系统.它旨在管理和控制自动化运输车辆,例如AGV或自动搬运车(AMR),在工业和商业环境中执行各种 ...

  2. 如何学好.net core?

    https://www.zhihu.com/question/348740859/answer/842656513

  3. python 函数与方法的区别

    函数与方法的区别 并不是类中的调用都叫方法 1.函数要手动传self,方法不用传self. 2.如果是一个函数,用类名去调用,如果是一个方法,用对象去调用. class Foo(object): de ...

  4. js 时间转时间戳

    前言 有时候我们用时间插件,选择好时间后,需要把日期格式转化为时间戳,再传到后台 时间转时间戳 let time = Math.floor(new Date("2014-04-23 18:5 ...

  5. codelite常用快捷键积累

    博客地址:https://www.cnblogs.com/zylyehuo/ 编译整个工作空间 workplace Ctrl+shift+B 编译当前文件 file Ctrl+F7 编译项目 proj ...

  6. Redis 原理 - Hash

    Hash 数据结构 使用 ziplist 当同时满足下面两个条件时,使用 ziplist 存储数据 元素个数少于512个 (hash-max-ziplist-entries: 512) 每个元素长度小 ...

  7. BUUCTF---古典密码知多少

    题目 知识 一共给出四种古典密码,分别是:猪圈密码.圣堂武士密码.标准银河字母.栅栏密码 猪圈之前有介绍 圣: 标准银河字母 更多加密方式 解题 对照解密 FGCPFLIRTUASYON 再使用栅栏 ...

  8. 面试题-Storm框架

    前言 Storm框架在实际项目中已经平稳运行快一年了,也很好的支撑了海量读写器的数据处理需求,不过和RabbitMQ一样,为了项目进度,实际工作中只能尽快的调研,关注一些关键点,其他的细节就只能放一放 ...

  9. go 语言中的占位符详解

    在 Go 语言的 fmt 包中,占位符用于格式化输出,允许在输出时插入变量的值.以下是一些常用的占位符及其用法: 通用占位符: %v:按照值的默认格式输出. %+v:输出结构体时,会添加字段名. %# ...

  10. FastAPI 核心功能的完整示例代码,涵盖 WebSocket、后台任务、生命周期事件、中间件配置及会话管理

    以下是一个整合 FastAPI 核心功能的完整示例代码,涵盖 WebSocket.后台任务.生命周期事件.中间件配置及会话管理.代码结构参考了多个技术文档的最佳实践: from contextlib ...