“给定一个数组 求某一个连续子数组的和 ”从这里开始

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{//数组 求 某一个 连续子数组的和 nums[5] { 5,3,4,6,7} index =
// 需要实际应用情况
//需要思考 :规定 index是下标 () [ ] ( ]的哪一种? 此代码约定 是其中的[]
//以及相等的情况
class Program
{
public int[] nums;
//构造函数中初始化
//类成员变量在构造函数中初始化是一种良好的实践,
//因为它将初始化逻辑封装在类的实例化过程中,使代码更具可维护性和清晰性。
public Program()
{
nums = new int[5] { 5, 3, 4, 6, 7 };
}
int Sum( int index1, int index2)
{
int i;//
//判断index1 index2是否合法
if (index1 < 0 || index1 >= nums.Length || index2 < 0 || index2 >= nums.Length)
{
Console.WriteLine(" 无效的索引");
return 0; //or throw an exception
}
//如果index1 =index2
if (index1 > index2) //如果index1> index2 交换一下
{
int temp = index2;
index2 = index1;
index1 = temp;
}
int sum = nums[index1];
//Console.WriteLine(sum+"我是for循环外的");
for (i = index1; i < index2; i++)
{
//Console.WriteLine(nums[i+1]);
sum += nums[i + 1];
//Console.WriteLine(sum + "我是for循环里的");
}
return sum;
}
static void Main(string[] args)
{
Program p = new Program();
//int nums = new int[5] { 5, 3, 4, 6, 7 };
p.nums = new int[5] { 5, 3, 4, 6, 7 };
int result = p.Sum(2,4);
Console.WriteLine(result);
Console.ReadKey();
}
}
}

 //如果频繁调用同一个数组的,不同的子数组   如何优化??

可以使用字典

使用字典(Dictionary)来缓存已计算的子数组和的结果是一种常见的优化方法,通常被称为"缓存"或"记忆化"。这样可以避免重复计算,提高程序的性能。
下面是一个简单的示例,展示如何使用字典进行优化:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{//数组 求 某一个 连续子数组的和 nums[5] { 5,3,4,6,7} index =
// 实际应用情况
//规定 index是下标 () [ ] ( ] 中的[]
//以及相等的情况
//如果频繁调用同一个数组的,子数组 如何优化
class Program
{
private int[] nums;
private Dictionary<Tuple<int, int>, int> cache;
public Program()
{
nums = new int[5] { 5, 3, 4, 6, 7 };
cache = new Dictionary<Tuple<int, int>, int>();
}
int Sum( int index1, int index2)
{
// Check if the result is already in the cache
Tuple<int, int> key = Tuple.Create(index1, index2);
if(cache.ContainsKey(key))
{
return cache[key];
}
int i,sum;
//判断index1 index2是否合法
if (index1 < 0 || index1 >= nums.Length || index2 < 0 || index2 >= nums.Length)
{
Console.WriteLine(" 无效的索引");
return 0; //or throw an exception
}
if (index1 > index2) //如果index1> index2 交换一下
{
int temp = index2;
index2 = index1;
index1 = temp;
}
sum = nums[index1]; //如果index1 =index2 在for循环里直接跳过
for (i = index1; i < index2; i++)
{
sum += nums[i + 1];
}
cache[key] = sum;
return sum;
}
static void Main(string[] args)
{
Program p = new Program();
int result = p.Sum(2,4);
Console.WriteLine(result);
//对相同范围的后续调用将使用缓存的结果
int cachedResult = p.Sum(2, 4);
Console.WriteLine(cachedResult);
Console.ReadKey();
}
}
}

动态规划,

使用一个数组来存储中间结果,以减少重复计算和内存占用。

设计和思考动态规划问题的关键在于确定状态、状态转移方程以及边界条件。
下面将解释如何设计和思考动态规划问题,以 Sum 问题为例:

确定状态: 首先,考虑问题的状态。在这个问题中,我们可以考虑定义状态 dp[i] 表示数组 nums 中前 i 个元素的和。
这样,问题的最终目标就是求解 dp[index2] 减去 dp[index1 - 1],即子数组和

状态转移方程: 确定状态后,考虑状态之间的关系,即状态转移方程。
在这个问题中,我们可以得到状态转移方程为 dp[i] = dp[i - 1] + nums[i],表示当前状态 dp[i] 可以通过前一个状态 dp[i - 1] 加上当前元素 nums[i] 得到。

**边界条件: **考虑边界条件,即最简单的情况。
在这个问题中,dp[0] 表示数组中的第一个元素,即 dp[0] = nums[0]。

**初始化: **对于某些问题,可能需要在开始时初始化状态。
在这个问题中,我们在构造函数中初始化 dp 数组,保证了 dp[0] 的正确性。

**问题求解: **根据状态、状态转移方程和边界条件,可以编写出动态规划的代码,实现问题求解。
在代码中,通过查询 dp 数组,可以在常数时间内得到子数组和,提高了效率。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{//数组 求 某一个 连续子数组的和 nums[5] { 5,3,4,6,7} index =
// 实际应用情况
//规定 index是下标 () [ ] ( ] 中的[]
//以及相等的情况
//如果频繁调用同一个数组的,子数组 如何优化
//使用字典会占用额外的内存空间,考虑其他的优化方式
class Program
{
private int[] nums;
private int[] dp; //定义状态 dp[i] 表示数组 nums 中前 i 个元素的和。
public Program()
{
nums = new int[5] { 5, 3, 4, 6, 7 };
dp = new int[nums.Length];
InitializeDP();
}
private void InitializeDP() //边界问题
{
dp[0] = nums[0]; //初始化
for (int i = 1; i < nums.Length; i++)
{
dp[i] = dp[i - 1] + nums[i]; //状态转移方程
}
}
int Sum(int index1, int index2)
{
//判断index1 index2是否合法
if (index1 < 0 || index1 >= nums.Length || index2 < 0 || index2 >= nums.Length)
{
Console.WriteLine(" 无效的索引");
return 0; //or throw an exception
}
if (index1 > index2) //如果index1> index2 交换一下
{
int temp = index2;
index2 = index1;
index1 = temp;
}
if (index1 == 0)
{
return dp[index2];
}
else //如果index1 大于等于1 那么 到后面的和 减去到前面的和
{ return dp[index2] - dp[index1 - 1]; }
}
static void Main(string[] args)
{
Program p = new Program();
int result = p.Sum(2,4);
Console.WriteLine(result);
//对相同范围的后续调用将使用缓存的结果
int cachedResult = p.Sum(2, 4);
Console.WriteLine(cachedResult);
Console.ReadKey();
}
}
}
posted @   专心Coding的程侠  阅读(15)  评论(0编辑  收藏  举报
编辑推荐:
· [杂谈]如何选择:Session 还是 JWT?
· 硬盘空间消失之谜:Linux 服务器存储排查与优化全过程
· JavaScript是按顺序执行的吗?聊聊JavaScript中的变量提升
· [杂谈]后台日志该怎么打印
· Pascal 架构 GPU 在 vllm下的模型推理优化
阅读排行:
· WinForm 通用权限框架,简单实用支持二次开发
· 如何为在线客服系统的 Web Api 后台主程序添加 Bootstrap 启动页面
· 硬盘空间消失之谜:Linux 服务器存储排查与优化全过程
· 面试官:DNS解析都整不明白,敢说你懂网络?我:嘤嘤嘤!
· 双语对照的 PDF 翻译工具「GitHub 热点速览」

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示