在这个问题中,如果我在第二行count
中创建static
变量,如图所示,kthSmallest()
方法会计算错误的答案。如果变量变为非static
,则计算正确的答案。非静态方法可以使用静态变量,为什么会有差异呢?
class Solution {
public static int count = 0;
public int res = 0;
public int kthSmallest(TreeNode root, int k) {
inorder(root,k);
return res;
}
public void inorder(TreeNode root, int k) {
if (root == null) return;
inorder(root.left,k);
count++;
if (count == k) {
res = root.val;
return;
}
inorder(root.right,k);
}
}
答案 0 :(得分:0)
我认为没有理由为count
方法的单次运行的结果会因static
是count
而受影响,但是如果您执行多个运行,无论是顺序还是并行,您肯定会遇到问题。 static
Solution
表示类Solution
的每个实例都共享该变量,您将其初始化为零,然后仅递增。无论是在count
的相同还是不同的实例上,该方法的第二次运行将继续前一次运行所留下的count
值。
通过确保static
的每个实例都有自己的Solution
变量,使count
非 - kthSmallest()
部分解决了该问题。使用同一实例执行多个kthSmallest()
计算仍然存在问题,但是您可以为每个实例执行一次正确的运行。如果你通过一些自动判断测试这个,那么它确实为每个测试用例创建一个单独的实例是合理的。
但即使这不是完整的解决方案。每个实例最多只能运行一次,如果尝试使用同一个实例执行两次并发运行,您甚至无法确保获得该运行。这里的根本问题是您使用实例(或类)变量来保存特定于class Solution {
// no class or instance variables at all
public int kthSmallest(TreeNode root, int k) {
// int[1] is the simplest mutable container for an int
int[] result = new int[1];
inorder(root, k, result);
return result[0];
}
// does not need to be public:
// returns the number of nodes traversed (not necessarily the whole subtree)
int inorder(TreeNode root, int k, int[] result) {
if (root == null) {
return 0;
} else {
// nodes traversed in the subtree, plus one for the present node
int count = inorder(root.left, k, result) + 1;
if (count == k) {
result[0] = root.val;
} else {
count += inorder(root.right, k, result);
}
return count;
}
}
}
方法的单个运行的状态。
您应该使用该方法的局部变量,如果需要,通过方法参数和/或返回值传递给其他方法。例如:
Public Class Form1
Private clients As DataTable
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Create a new instance of a datatable
clients = New DataTable("Clients")
'Add your columns
clients.Columns.AddRange({
New DataColumn("client_id", GetType(Integer)) With {.AutoIncrement = True},
New DataColumn("forename") With {.MaxLength = 15},
New DataColumn("surname") With {.MaxLength = 15},
New DataColumn("address1") With {.MaxLength = 30},
New DataColumn("postcode") With {.MaxLength = 9},
New DataColumn("rdate", GetType(DateTime)),
New DataColumn("notes") With {.MaxLength = 1000},
New DataColumn("home_insurance", GetType(Boolean)),
New DataColumn("mortgage", GetType(Boolean)),
New DataColumn("home_mover", GetType(Boolean)),
New DataColumn("first_time_buyer", GetType(Boolean)),
New DataColumn("buy_let", GetType(Boolean)),
New DataColumn("life_insurance", GetType(Boolean)),
New DataColumn("critical_illness", GetType(Boolean)),
New DataColumn("income_protection", GetType(Boolean))
})
'Check if the file exists to deserialize the data
If IO.File.Exists("D:\temp\clients.xml") Then
clients.ReadXml("D:\temp\clients.xml")
End If
'Bind the controls
BindingSource1.DataSource = clients
DataGridView1.DataSource = clients
BindingNavigator1.BindingSource = BindingSource1
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
Try
'Create a file if it does not exist
If Not IO.File.Exists("D:\temp\clients.xml") Then
IO.File.Create("D:\temp\clients.xml")
End If
'Serialize the data
clients.WriteXml("D:\temp\clients.xml", XmlWriteMode.WriteSchema)
Catch ex As Exception
'Display any errors
MessageBox.Show("There was an error serializing the data.", "Error", MessageBoxButtons.OK)
Console.WriteLine(ex.Message)
End Try
End Sub
Private Sub ToolStripButtonSearch_Click(sender As Object, e As EventArgs) Handles ToolStripButtonSearch.Click
If String.IsNullOrWhiteSpace(ToolStripTextBoxSearch.Text) Then
'If there is no String, remove the filter
BindingSource1.RemoveFilter()
Else
'If there is
BindingSource1.Filter =
$"forename = '{ToolStripTextBoxSearch.Text}'
OR surname = '{ToolStripTextBoxSearch.Text}'
OR CONVERT(client_id, 'System.String') = '{ToolStripTextBoxSearch.Text}'"
End If
End Sub
End Class